Blame


1 3e4749f7 2020-10-02 op .\" Copyright (c) 2020 Omar Polo <op@omarpolo.com>
2 3e4749f7 2020-10-02 op .\"
3 3e4749f7 2020-10-02 op .\" Permission to use, copy, modify, and distribute this software for any
4 3e4749f7 2020-10-02 op .\" purpose with or without fee is hereby granted, provided that the above
5 3e4749f7 2020-10-02 op .\" copyright notice and this permission notice appear in all copies.
6 3e4749f7 2020-10-02 op .\"
7 3e4749f7 2020-10-02 op .\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 3e4749f7 2020-10-02 op .\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 3e4749f7 2020-10-02 op .\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10 3e4749f7 2020-10-02 op .\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 3e4749f7 2020-10-02 op .\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 3e4749f7 2020-10-02 op .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13 3e4749f7 2020-10-02 op .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14 3e4749f7 2020-10-02 op .Dd $Mdocdate: October 2 2020$
15 3e4749f7 2020-10-02 op .Dt GMIND 1
16 3e4749f7 2020-10-02 op .Os
17 3e4749f7 2020-10-02 op .Sh NAME
18 3e4749f7 2020-10-02 op .Nm gmid
19 fab952e1 2020-10-03 op .Nd dead simple zero configuration gemini server
20 3e4749f7 2020-10-02 op .Sh SYNOPSIS
21 3e4749f7 2020-10-02 op .Nm
22 3e4749f7 2020-10-02 op .Bk -words
23 15902770 2021-01-15 op .Op Fl n
24 15902770 2021-01-15 op .Op Fl c Ar config
25 15902770 2021-01-15 op |
26 85dff1f9 2021-01-11 op .Op Fl 6fh
27 15902770 2021-01-15 op .Op Fl C Ar cert
28 15902770 2021-01-15 op .Op Fl d Ar root
29 15902770 2021-01-15 op .Op Fl K Ar key
30 721e2325 2020-11-18 op .Op Fl p Ar port
31 0ed56567 2020-11-06 op .Op Fl x Ar cgi-bin
32 3e4749f7 2020-10-02 op .Ek
33 3e4749f7 2020-10-02 op .Sh DESCRIPTION
34 3e4749f7 2020-10-02 op .Nm
35 b9220ca4 2021-01-11 op is a simple and minimal gemini server that can serve static files and
36 b9220ca4 2021-01-11 op execute CGI scripts.
37 3e4749f7 2020-10-02 op .Pp
38 3e4749f7 2020-10-02 op .Nm
39 df6ca41d 2020-12-25 op won't serve files outside the given directory and won't follow
40 df6ca41d 2020-12-25 op symlinks.
41 6980aad6 2020-10-02 op Furthermore, on
42 6980aad6 2020-10-02 op .Ox ,
43 6980aad6 2020-10-02 op .Xr pledge 2
44 3e4749f7 2020-10-02 op and
45 6980aad6 2020-10-02 op .Xr unveil 2
46 3e4749f7 2020-10-02 op are used to ensure that
47 3e4749f7 2020-10-02 op .Nm
48 0ed56567 2020-11-06 op dosen't do anything else than read files from the given directory,
49 0ed56567 2020-11-06 op accept network connections and, optionally, execute CGI scripts.
50 3e4749f7 2020-10-02 op .Pp
51 df6ca41d 2020-12-25 op .Nm
52 df6ca41d 2020-12-25 op fully supports IRIs (Internationalized Resource Identifiers, see
53 df6ca41d 2020-12-25 op RFC3987).
54 df6ca41d 2020-12-25 op .Pp
55 3e4749f7 2020-10-02 op It should be noted that
56 3e4749f7 2020-10-02 op .Nm
57 3e4749f7 2020-10-02 op is very simple in its implementation, and so it may not be appropriate
58 0ed56567 2020-11-06 op for serving sites with lots of users.
59 0ed56567 2020-11-06 op After all, the code is single threaded and use a single process,
60 83000e2d 2020-12-21 op although it can handle multiple clients at the same time.
61 3e4749f7 2020-10-02 op .Pp
62 fab952e1 2020-10-03 op If a user request path is a directory,
63 fab952e1 2020-10-03 op .Nm
64 fab952e1 2020-10-03 op will try to serve a
65 fab952e1 2020-10-03 op .Pa index.gmi
66 fab952e1 2020-10-03 op file inside that directory.
67 fab952e1 2020-10-03 op .Pp
68 3e4749f7 2020-10-02 op The options are as follows:
69 3e4749f7 2020-10-02 op .Bl -tag -width 12m
70 85dff1f9 2021-01-11 op .It Fl 6
71 85dff1f9 2021-01-11 op Enable IPv6.
72 3e4749f7 2020-10-02 op .It Fl c Ar cert.pem
73 3e4749f7 2020-10-02 op The certificate to use, by default is
74 fab952e1 2020-10-03 op .Pa cert.pem .
75 3e4749f7 2020-10-02 op .It Fl d Ar docs
76 3e4749f7 2020-10-02 op The root directory to serve.
77 3e4749f7 2020-10-02 op .Nm
78 a5d310bc 2020-11-10 op won't serve any file that is outside that directory.
79 a5d310bc 2020-11-10 op By default is
80 0ed56567 2020-11-06 op .Pa docs .
81 d7802bb4 2020-12-02 op .It Fl f
82 d7802bb4 2020-12-02 op stays and log in the foreground, do not daemonize the process.
83 3e4749f7 2020-10-02 op .It Fl h
84 fab952e1 2020-10-03 op Print the usage and exit.
85 3e4749f7 2020-10-02 op .It Fl k Ar key.pem
86 3e4749f7 2020-10-02 op The key for the certificate, by default is
87 fab952e1 2020-10-03 op .Pa key.pem .
88 721e2325 2020-11-18 op .It Fl p Ar port
89 721e2325 2020-11-18 op The port to bind to, by default 1965.
90 0ed56567 2020-11-06 op .It Fl x Ar dir
91 0ed56567 2020-11-06 op Enable execution of CGI scripts inside the given directory (relative
92 0ed56567 2020-11-06 op to the document root.) Cannot be provided more than once.
93 3e4749f7 2020-10-02 op .El
94 72342dc9 2020-11-06 op .Sh CGI
95 0ed56567 2020-11-06 op When CGI scripts are enabled for a directory, a request for an
96 0ed56567 2020-11-06 op executable file will execute it and fed its output to the client.
97 72342dc9 2020-11-06 op .Pp
98 0ed56567 2020-11-06 op The CGI scripts will inherit the environment from
99 0ed56567 2020-11-06 op .Nm
100 0ed56567 2020-11-06 op with these additional variables set:
101 a5d310bc 2020-11-10 op .Bl -tag -width 18m
102 0ed56567 2020-11-06 op .It Ev SERVER_SOFTWARE
103 0ed56567 2020-11-06 op "gmid"
104 0ed56567 2020-11-06 op .It Ev SERVER_PORT
105 0ed56567 2020-11-06 op "1965"
106 a5d310bc 2020-11-10 op .It Ev SCRIPT_NAME
107 a5d310bc 2020-11-10 op The (public) path to the script.
108 a5d310bc 2020-11-10 op .It Ev SCRIPT_EXECUTABLE
109 a5d310bc 2020-11-10 op The full path to the executable.
110 a5d310bc 2020-11-10 op .It Ev REQUEST_URI
111 a5d310bc 2020-11-10 op The user request (without the query parameters.)
112 a5d310bc 2020-11-10 op .It Ev REQUEST_RELATIVE
113 a5d310bc 2020-11-10 op The request relative to the script.
114 0ed56567 2020-11-06 op .It Ev QUERY_STRING
115 a5d310bc 2020-11-10 op The query parameters.
116 a5d310bc 2020-11-10 op .It Ev REMOTE_HOST
117 a5d310bc 2020-11-10 op The remote IP address.
118 677afbd3 2020-12-02 op .It Ev REMOTE_ADDR
119 677afbd3 2020-12-02 op The remote IP address.
120 a5d310bc 2020-11-10 op .It Ev DOCUMENT_ROOT
121 a5d310bc 2020-11-10 op The root directory being served, the one provided with the
122 a5d310bc 2020-11-10 op .Ar d
123 a5d310bc 2020-11-10 op parameter to
124 a5d310bc 2020-11-10 op .Nm
125 677afbd3 2020-12-02 op .It Ev AUTH_TYPE
126 677afbd3 2020-12-02 op The string "Certificate" if the client used a certificate, otherwise unset.
127 677afbd3 2020-12-02 op .It Ev REMOTE_USER
128 677afbd3 2020-12-02 op The subject of the client certificate if provided, otherwise unset.
129 677afbd3 2020-12-02 op .It Ev TLS_CLIENT_ISSUER
130 677afbd3 2020-12-02 op The is the issuer of the client certificate if provided, otherwise unset.
131 677afbd3 2020-12-02 op .It Ev TLS_CLIENT_HASH
132 677afbd3 2020-12-02 op The hash of the client certificate if provided, otherwise unset.
133 677afbd3 2020-12-02 op The format is "ALGO:HASH".
134 0ed56567 2020-11-06 op .El
135 a5d310bc 2020-11-10 op .Pp
136 a5d310bc 2020-11-10 op Let's say you have a script in
137 a5d310bc 2020-11-10 op .Pa /cgi-bin/script
138 a5d310bc 2020-11-10 op and the user request is
139 a5d310bc 2020-11-10 op .Pa /cgi-bin/script/foo/bar?quux .
140 a5d310bc 2020-11-10 op Then
141 a5d310bc 2020-11-10 op .Ev SCRIPT_NAME
142 a5d310bc 2020-11-10 op will be
143 b9220ca4 2021-01-11 op .Pa cgi-bin/script ,
144 a5d310bc 2020-11-10 op .Ev SCRIPT_EXECUTABLE
145 a5d310bc 2020-11-10 op will be
146 a5d310bc 2020-11-10 op .Pa $DOCUMENT_ROOT/cgi-bin/script ,
147 a5d310bc 2020-11-10 op .Ev REQUEST_URI
148 a5d310bc 2020-11-10 op will be
149 b9220ca4 2021-01-11 op .Pa cgi-bin/script/foo/bar ,
150 a5d310bc 2020-11-10 op .Ev REQUEST_RELATIVE
151 a5d310bc 2020-11-10 op will be
152 b9220ca4 2021-01-11 op .Pa foo/bar
153 b9220ca4 2021-01-11 op and
154 a5d310bc 2020-11-10 op .Ev QUERY_STRING
155 a5d310bc 2020-11-10 op will be
156 a5d310bc 2020-11-10 op .Ar quux .
157 3e4749f7 2020-10-02 op .Sh EXAMPLES
158 3e4749f7 2020-10-02 op To quickly getting started
159 6980aad6 2020-10-02 op .Bd -literal -offset indent
160 3e4749f7 2020-10-02 op $ # generate a cert and a key
161 3e4749f7 2020-10-02 op $ openssl req -x509 -newkey rsa:4096 -keyout key.pem \\
162 3e4749f7 2020-10-02 op -out cert.pem -days 365 -nodes
163 3e4749f7 2020-10-02 op $ mkdir docs
164 3e4749f7 2020-10-02 op $ cat <<EOF > docs/index.gmi
165 3e4749f7 2020-10-02 op # Hello world
166 3e4749f7 2020-10-02 op test paragraph...
167 3e4749f7 2020-10-02 op EOF
168 3e4749f7 2020-10-02 op $ gmid -c cert.pem -k key.pem -d docs
169 6980aad6 2020-10-02 op .Ed
170 3e4749f7 2020-10-02 op .Pp
171 0ed56567 2020-11-06 op Now you can visit gemini://localhost/ with your preferred gemini
172 0ed56567 2020-11-06 op client.
173 0ed56567 2020-11-06 op .Pp
174 0ed56567 2020-11-06 op To add some CGI scripts, assuming a setup similar to the previous
175 0ed56567 2020-11-06 op example, you can
176 0ed56567 2020-11-06 op .Bd -literal -offset indent
177 0ed56567 2020-11-06 op $ mkdir docs/cgi-bin
178 0ed56567 2020-11-06 op $ cat <<EOF > docs/cgi-bin/hello-world
179 0ed56567 2020-11-06 op #!/bin/sh
180 0ed56567 2020-11-06 op printf "20 text/plain\\r\\n"
181 0ed56567 2020-11-06 op echo "hello world!"
182 0ed56567 2020-11-06 op EOF
183 0ed56567 2020-11-06 op $ gmid -x cgi-bin
184 0ed56567 2020-11-06 op .Ed
185 0ed56567 2020-11-06 op .Pp
186 0ed56567 2020-11-06 op Note that the argument to the
187 0ed56567 2020-11-06 op .Fl x
188 0ed56567 2020-11-06 op option is
189 0ed56567 2020-11-06 op .Pa cgi-bin
190 0ed56567 2020-11-06 op and not
191 0ed56567 2020-11-06 op .Pa docs/cgi-bin ,
192 a5d310bc 2020-11-10 op since it's relative to the document root.
193 ef04b551 2021-01-09 op .Sh ACKNOWLEDGEMENTS
194 ef04b551 2021-01-09 op .Nm
195 ef04b551 2021-01-09 op uses the "Flexible and Economical" UTF-8 decoder written by
196 ef04b551 2021-01-09 op .An Bjoern Hoehrmann .
197 3e4749f7 2020-10-02 op .Sh CAVEATS
198 3e4749f7 2020-10-02 op .Bl -bullet
199 3e4749f7 2020-10-02 op .It
200 fab952e1 2020-10-03 op it doesn't support virtual hosts: the host part of the request URL is
201 3e4749f7 2020-10-02 op completely ignored.
202 043acc97 2020-12-25 op .It
203 043acc97 2020-12-25 op a %2F sequence in the path part is indistinguishable from a literal
204 043acc97 2020-12-25 op slash: this is not RFC3986-compliant.
205 00781742 2020-12-25 op .It
206 00781742 2020-12-25 op a %00 sequence either in the path or in the query part is treated as
207 00781742 2020-12-25 op invalid character and thus rejected.
208 3e4749f7 2020-10-02 op .El