Blob


1 .\" Copyright (c) 2021 Omar Polo <op@omarpolo.com>
2 .\"
3 .\" Permission to use, copy, modify, and distribute this software for any
4 .\" purpose with or without fee is hereby granted, provided that the above
5 .\" copyright notice and this permission notice appear in all copies.
6 .\"
7 .\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 .\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 .\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10 .\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 .\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13 .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14 .Dd $Mdocdate: January 30 2021$
15 .Dt GMID 1
16 .Os
17 .Sh NAME
18 .Nm gmid
19 .Nd simple and secure Gemini server
20 .Sh SYNOPSIS
21 .Nm
22 .Bk -words
23 .Op Fl fnv
24 .Op Fl c Ar config
25 .Op Fl D Ar macro Ns = Ns Ar value
26 .Op Fl P Ar pidfile
27 .Ek
28 .Nm
29 .Bk -words
30 .Op Fl 6hVv
31 .Op Fl d Pa certs-dir
32 .Op Fl H Ar hostname
33 .Op Fl p Ar port
34 .Op Fl x Pa cgi
35 .Op Pa dir
36 .Ek
37 .Sh DESCRIPTION
38 .Nm
39 is a simple and minimal gemini server that can serve static files,
40 execute CGI scripts and talk to FastCGI applications.
41 It can run without a configuration file with a limited set of features
42 available.
43 .Pp
44 .Nm
45 rereads the configuration file when it receives
46 .Dv SIGHUP .
47 .Pp
48 The options are as follows:
49 .Bl -tag -width 14m
50 .It Fl c Pa config
51 Specify the configuration file.
52 .It Fl D Ar macro Ns = Ns Ar value
53 Define
54 .Ar macro
55 to be set to
56 .Ar value
57 on the command line.
58 Overrides the definition of
59 .Ar macro
60 in the config file if present.
61 .It Fl f
62 Stays and logs on the foreground.
63 .It Fl n
64 Check that the configuration is valid, but don't start the server.
65 .It Fl P Pa pidfile
66 Write the daemon pid to the given location.
67 .Ar pidfile
68 will also act as lock: if another process is holding a lock on that
69 file,
70 .Nm
71 will refuse to start.
72 .El
73 .Pp
74 If no configuration file is given,
75 .Nm
76 will look for the following options
77 .Bl -tag -width 14m
78 .It Fl 6
79 Enable IPv6.
80 .It Fl d Pa certs-path
81 Directory where certificates for the config-less mode are stored.
82 By default is
83 .Pa $XDG_DATA_HOME/gmid ,
84 i.e.
85 .Pa ~/.local/share/gmid .
86 .It Fl H Ar hostname
87 The hostname
88 .Ar localhost
89 by default.
90 Certificates for the given
91 .Ar hostname
92 are searched inside the
93 .Pa certs-dir
94 directory given with the
95 .Fl d
96 option.
97 They have the form
98 .Pa hostname.cert.pem
99 and
100 .Pa hostname.key.pem .
101 If a certificate or key don't exists for a given hostname they
102 will be automatically generated.
103 .It Fl h , Fl -help
104 Print the usage and exit.
105 .It Fl p Ar port
106 The port to listen on, by default 1965.
107 .It Fl V , Fl -version
108 Print the version and exit.
109 .It Fl v
110 Verbose mode.
111 Multiple
112 .Fl v
113 options increase the verbosity.
114 .It Fl x Pa path
115 Enable execution of CGI scripts.
116 See the description of the
117 .Ic cgi
118 option in the section
119 .Sq Servers
120 below to learn how
121 .Pa path
122 is processed.
123 Cannot be provided more than once.
124 .It Pa dir
125 The root directory to serve.
126 By default the current working directory is assumed.
127 .El
128 .Sh CONFIGURATION FILE
129 The configuration file is divided into three sections:
130 .Bl -tag -width xxxx
131 .It Sy Macros
132 User-defined variables may be defined and used later, simplifying the
133 configuration file.
134 .It Sy Global Options
135 Global settings for
136 .Nm .
137 .It Sy Servers
138 Virtual hosts definition.
139 .El
140 .Pp
141 Within the sections, empty lines are ignored and comments can be put
142 anywhere in the file using a hash mark
143 .Pq Sq # ,
144 and extend to the end of the current line.
145 A boolean is either the symbol
146 .Sq on
147 or
148 .Sq off .
149 A string is a sequence of characters wrapped in double quotes,
150 .Dq like this .
151 Multiple strings one next to the other are joined into a single
152 string:
153 .Bd -literal -offset indent
154 # equivalent to "temporary-failure"
155 block return 40 "temporary" "-" "failure"
156 .Ed
157 .Pp
158 Furthermore, quoting is necessary only when a string needs to contain
159 spaces, something that looks like a number or a reserved keyword.
160 The last example could have been written also as:
161 .Bd -literal -offset indent
162 block return 40 temporary "-" failure
163 .Ed
164 .Pp
165 Strict ordering of the sections is not enforced, so that is possible
166 to mix macros, options and
167 .Ic server
168 blocks.
169 However, defining all the
170 .Ic server
171 blocks after the macros and the global options is recommended.
172 .Ss Macros
173 Macros can be defined that will later be expanded in context.
174 Macro names must start with a letter, digit or underscore and may
175 contain any of those characters.
176 Macros names may not be reserved words.
177 Macros are not expanded inside quotes.
178 .Pp
179 For example:
180 .Bd -literal -offset indent
181 dir = "/var/gemini"
182 cert = "/etc/keys"
184 server "foo" {
185 root $dir "/foo" # -> /var/gemini/foo
186 cert $cert "/foo.crt" # -> /etc/keys/foo.crt
187 key $cert "/foo.pem" # -> /etc/keys/foo.pem
189 .Ed
190 .Ss Global Options
191 .Bl -tag -width 12m
192 .It Ic chroot Pa path
193 .Xr chroot 2
194 the process to the given
195 .Pa path .
196 The daemon has to be run with root privileges and thus the option
197 .Ic user
198 needs to be provided, so privileges can be dropped.
199 Note that
200 .Nm
201 will enter the chroot after loading the TLS keys, but before opening
202 the virtual host root directories.
203 It's recommended to keep the TLS keys outside the chroot.
204 Future version of
205 .Nm
206 may enforce this.
207 .It Ic ipv6 Ar bool
208 Enable or disable IPv6 support, off by default.
209 .It Ic map Ar mime-type Cm to-ext Ar file-extension
210 Map
211 .Ar mime-type
212 to the given
213 .Ar file-extension .
214 Both argument are strings.
215 .It Ic port Ar portno
216 The port to listen on.
217 1965 by default.
218 .It Ic prefork Ar number
219 Run the specified number of server processes.
220 This increases the performance and prevents delays when connecting to
221 a server.
222 When not in config-less mode,
223 .Nm
224 runs 3 server processes by default.
225 The maximum number allowed is 16.
226 .It Ic protocols Ar string
227 Specify the TLS protocols to enable.
228 Refer to
229 .Xr tls_config_parse_protocols 3
230 for the valid protocol string values.
231 By default, both TLSv1.3 and TLSv1.2 are enabled.
232 Use
233 .Dq tlsv1.3
234 to enable only TLSv1.3.
235 .It Ic user Ar string
236 Run the daemon as the given user.
237 .El
238 .Ss Servers
239 Every virtual host is defined by a
240 .Ic server
241 block:
242 .Bl -tag -width Ds
243 .It Ic server Ar hostname Brq ...
244 Match the server name using shell globbing rules.
245 It can be an explicit name,
246 .Ar www.example.com ,
247 or a name including a wildcards,
248 .Ar *.example.com .
249 .El
250 .Pp
251 Followed by a block of options that is enclosed in curly brackets:
252 .Bl -tag -width Ds
253 .It Ic alias Ar name
254 Specify an additional alias
255 .Ar name
256 for this server.
257 .It Ic auto Ic index Ar bool
258 If no index file is found, automatically generate a directory listing.
259 Disabled by default.
260 .It Ic block Op Ic return Ar code Op Ar meta
261 Send a reply and close the connection;
262 by default
263 .Ar code
264 is 40
265 and
266 .Ar meta
267 is
268 .Dq temporary failure .
269 If
270 .Ar code
271 is in the 3x range, then
272 .Ar meta
273 is mandatory.
274 Inside
275 .Ar meta ,
276 the following special sequences are supported:
277 .Bl -tag -width Ds -compact
278 .It \&%\&%
279 is replaced with a single
280 .Sq \&% .
281 .It \&%p
282 is replaced with the request path.
283 .It \&%q
284 is replaced with the query string of the request.
285 .It \&%P
286 is replaced with the server port.
287 .It \&%N
288 is replaced with the server name.
289 .El
290 .It Ic cert Pa file
291 Path to the certificate to use for this server.
292 The
293 .Pa file
294 should contain a PEM encoded certificate.
295 This option is mandatory.
296 .It Ic cgi Pa path
297 Execute CGI scripts that matches
298 .Pa path
299 using shell globbing rules.
300 .It Ic default type Ar string
301 Set the default media type that is used if the media type for a
302 specified extension is not found.
303 If not specified, the
304 .Ic default type
305 is set to
306 .Dq application/octet-stream .
307 .It Ic entrypoint Pa path
308 Handle all the requests for the current virtual host using the
309 CGI script at
310 .Pa path ,
311 relative to the current document root.
312 .It Ic env Ar name Cm = Ar value
313 Set the environment variable
314 .Ar name
315 to
316 .Ar value
317 when executing CGI scripts.
318 Can be provided more than once.
319 .\" don't document the "spawn <prog>" form because it probably won't
320 .\" be kept.
321 .It Ic fastcgi Oo Ic tcp Oc Pa socket Oo Cm port Ar port Oc
322 Enable FastCGI instead of serving files.
323 The
324 .Pa socket
325 can either be a UNIX-domain socket or a TCP socket.
326 If the FastCGI application is listening on a UNIX domain socket,
327 .Pa socket
328 is a local path name within the
329 .Xr chroot 2
330 root directory of
331 .Nm .
332 Otherwise, the
333 .Ic tcp
334 keyword must be provided and
335 .Pa socket
336 is interpreted as a hostname or an IP address.
337 .Ar port
338 can be either a port number or the name of a service enclosed in
339 double quotes.
340 If not specified defaults to 9000.
341 .It Ic index Ar string
342 Set the directory index file.
343 If not specified, it defaults to
344 .Pa index.gmi .
345 .It Ic key Pa file
346 Specify the private key to use for this server.
347 The
348 .Pa file
349 should contain a PEM encoded private key.
350 This option is mandatory.
351 .It Ic lang Ar string
352 Specify the language tag for the text/gemini content served.
353 If not specified, no
354 .Dq lang
355 parameter will be added in the response.
356 .It Ic location Pa path Brq ...
357 Specify server configuration rules for a specific location.
358 The
359 .Pa path
360 argument will be matched against the request path with shell globbing
361 rules.
362 In case of multiple location statements in the same context, the first
363 matching location will be put into effect and the later ones ignored.
364 Therefore is advisable to match for more specific paths first and for
365 generic ones later on.
367 .Ic location
368 section may include most of the server configuration rules
369 except
370 .Ic alias , Ic cert , Ic cgi , Ic entrypoint , Ic env , Ic key ,
371 .Ic location No and Ic param .
372 .It Ic log Ar bool
373 Enable or disable the logging for the current server or location block.
374 .It Ic param Ar name Cm = Ar value
375 Set the param
376 .Ar name
377 to
378 .Ar value
379 for FastCGI.
380 .It Ic root Pa directory
381 Specify the root directory for this server
382 .Pq alas the current Dq document root .
383 It's relative to the chroot if enabled.
384 .It Ic require Ic client Ic ca Pa path
385 Allow requests only from clients that provide a certificate signed by
386 the CA certificate in
387 .Pa path .
388 It needs to be a PEM-encoded certificate and it's not relative to the
389 chroot.
390 .It Ic strip Ar number
391 Strip
392 .Ar number
393 components from the beginning of the path before doing a lookup in the
394 root directory.
395 It's also considered for the
396 .Ar meta
397 parameter in the scope of a
398 .Ic block return .
399 .El
400 .Sh CGI
401 When a request for an executable file matches the
402 .Ic cgi
403 rule, that file will be execute and its output fed to the client.
404 .Pp
405 The CGI scripts are executed in the directory they reside and inherit
406 the environment from
407 .Nm
408 with these additional variables set:
409 .Bl -tag -width 24m
410 .It Ev GATEWAY_INTERFACE
411 .Dq CGI/1.1
412 .It Ev GEMINI_DOCUMENT_ROOT
413 The root directory of the virtual host.
414 .It Ev GEMINI_SCRIPT_FILENAME
415 Full path to the CGI script being executed.
416 .It Ev GEMINI_URL
417 The full IRI of the request.
418 .It Ev GEMINI_URL_PATH
419 The path of the request.
420 .It Ev PATH_INFO
421 The portion of the requested path that is derived from the the IRI
422 path hierarchy following the part that identifies the script itself.
423 Can be unset.
424 .It Ev PATH_TRANSLATED
425 Present if and only if
426 .Ev PATH_INFO
427 is set.
428 It represent the translation of the
429 .Ev PATH_INFO .
430 .Nm
431 builds this by appending the
432 .Ev PATH_INFO
433 to the virtual host directory root.
434 .It Ev QUERY_STRING
435 The decoded query string.
436 .It Ev REMOTE_ADDR , Ev REMOTE_HOST
437 Textual representation of the client IP.
438 .It Ev REQUEST_METHOD
439 This is present only for RFC3875 (CGI) compliance.
440 It's always set to the empty string.
441 .It Ev SCRIPT_NAME
442 The part of the
443 .Ev GEMINI_URL_PATH
444 that identifies the current CGI script.
445 .It Ev SERVER_NAME
446 The name of the server
447 .It Ev SERVER_PORT
448 The port the server is listening on.
449 .It Ev SERVER_PROTOCOL
450 .Dq GEMINI
451 .It Ev SERVER_SOFTWARE
452 The name and version of the server, i.e.
453 .Dq gmid/1.5
454 .It Ev AUTH_TYPE
455 The string "Certificate" if the client used a certificate, otherwise
456 unset.
457 .It Ev REMOTE_USER
458 The subject of the client certificate if provided, otherwise unset.
459 .It Ev TLS_CLIENT_ISSUER
460 The is the issuer of the client certificate if provided, otherwise
461 unset.
462 .It Ev TLS_CLIENT_HASH
463 The hash of the client certificate if provided, otherwise unset.
464 The format is
465 .Dq ALGO:HASH .
466 .It Ev TLS_VERSION
467 The TLS version negotiated with the peer.
468 .It Ev TLS_CIPHER
469 The cipher suite negotiated with the peer.
470 .It Ev TLS_CIPHER_STRENGTH
471 The strength in bits for the symmetric cipher that is being used with
472 the peer.
473 .It Ev TLS_CLIENT_NOT_AFTER
474 The time corresponding to the end of the validity period of the peer
475 certificate in the ISO 8601 format
476 .Pq e.g. Dq 2021-02-07T20:17:41Z .
477 .It Ev TLS_CLIENT_NOT_BEFORE
478 The time corresponding to the start of the validity period of the peer
479 certificate in the ISO 8601 format.
480 .El
481 .Sh FastCGI
482 .Nm
483 optionally supports FastCGI.
485 .Ic fastcgi
486 rule must be present in a server or location block.
487 Then, all requests matching that server or location will be handled
488 via the specified FastCGI backend.
489 .Pp
490 By default the following variables
491 .Pq parameters
492 are sent, and carry the same semantics as with CGI.
493 More parameters can be added with the
494 .Ic param
495 option.
496 .Pp
497 .Bl -bullet -compact
498 .It
499 GATEWAY_INTERFACE
500 .It
501 GEMINI_URL_PATH
502 .It
503 QUERY_STRING
504 .It
505 REMOTE_ADDR
506 .It
507 REMOTE_HOST
508 .It
509 REQUEST_METHOD
510 .It
511 SERVER_NAME
512 .It
513 SERVER_PROTOCOL
514 .It
515 SERVER_SOFTWARE
516 .It
517 AUTH_TYPE
518 .It
519 REMOTE_USER
520 .It
521 TLS_CLIENT_ISSUER
522 .It
523 TLS_CLIENT_HASH
524 .It
525 TLS_VERSION
526 .It
527 TLS_CIPHER
528 .It
529 TLS_CIPHER_STRENGTH
530 .It
531 TLS_CLIENT_NOT_BEFORE
532 .It
533 TLS_CLIENT_NOT_AFTER
534 .El
535 .Sh MIME
536 To auto-detect the MIME type of the response
537 .Nm
538 looks at the file extension and consults its internal table.
539 By default the following mappings are loaded, but they can be
540 overridden or extended using the
541 .Ic map
542 configuration option.
543 If no MIME is found, the value of
544 .Ic default type
545 matching the file
546 .Ic location
547 will be used, which is
548 .Dq application/octet-stream
549 by default.
550 .Pp
551 .Bl -tag -offset indent -width 14m -compact
552 .It diff
553 text/x-patch
554 .It gemini, gmi
555 text/gemini
556 .It gif
557 image/gif
558 .It jpeg
559 image/jpeg
560 .It jpg
561 image/jpeg
562 .It markdown, md
563 text/markdown
564 .It patch
565 text/x-patch
566 .It pdf
567 application/pdf
568 .It png
569 image/png
570 .It svg
571 image/svg+xml
572 .It txt
573 text/plain
574 .It xml
575 text/xml
576 .El
577 .Sh EXAMPLES
578 Serve the current directory
579 .Bd -literal -offset indent
580 $ gmid .
581 .Ed
582 .Pp
583 To serve the directory
584 .Pa docs
585 and enable CGI scripts inside
586 .Pa docs/cgi
587 .Bd -literal -offset indent
588 $ mkdir docs/cgi
589 $ cat <<EOF > docs/cgi/hello
590 #!/bin/sh
591 printf "20 text/plain\\r\\n"
592 echo "hello world"
593 EOF
594 $ chmod +x docs/cgi/hello
595 $ gmid -x '/cgi/*' docs
596 .Ed
597 .Pp
598 The following is an example of a possible configuration for a site
599 that enables only TLSv1.3, adds a mime type for the file extension
600 "rtf" and defines two virtual host:
601 .Bd -literal -offset indent
602 ipv6 on # enable ipv6
604 protocols "tlsv1.3"
606 map "application/rtf" to-ext "rtf"
608 server "example.com" {
609 cert "/path/to/cert.pem"
610 key "/path/to/key.pem"
611 root "/var/gemini/example.com"
614 server "it.example.com" {
615 cert "/path/to/cert.pem"
616 key "/path/to/key.pem"
617 root "/var/gemini/it.example.com"
619 # enable cgi scripts inside "cgi-bin"
620 cgi "/cgi-bin/*"
622 # set the language for text/gemini files
623 lang "it"
625 .Ed
626 .Pp
627 Yet another example, showing how to enable a
628 .Ic chroot
629 and use
630 .Ic location
631 rule
632 .Bd -literal -offset indent
633 chroot "/var/gemini"
634 user "_gmid"
636 server "example.com" {
637 cert "/path/to/cert.pem" # absolute path
638 key "/path/to/key.pem" # also absolute
639 root "/example.com" # relative to the chroot
641 location "/static/*" {
642 # load the following rules only for
643 # requests that matches "/static/*"
645 auto index on
646 index "index.gemini"
649 .Ed
650 .Sh ACKNOWLEDGEMENTS
651 .Nm
652 uses the
653 .Dq Flexible and Economical
654 UTF-8 decoder written by
655 .An Bjoern Hoehrmann .
656 .Sh AUTHORS
657 .An -nosplit
658 The
659 .Nm
660 program was written by
661 .An Omar Polo Aq Mt op@omarpolo.com .
662 .Sh CAVEATS
663 .Bl -bullet
664 .It
665 All the root directories are opened during the daemon startup; if a
666 root directory is deleted and then re-created,
667 .Nm
668 won't be able to serve files inside that directory until a restart.
669 This restriction only applies to the root directories and not their
670 content.
671 .It
672 a %2F sequence is indistinguishable from a literal slash: this is not
673 RFC3986-compliant.
674 .It
675 a %00 sequence is treated as invalid character and thus rejected.
676 .El