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: July 29 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 daemon's 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 it 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 .Po
89 .Ar localhost
90 by default
91 .Pc .
92 Certificates for the given
93 .Ar hostname
94 are searched inside the
95 .Pa certs-dir
96 directory given with the
97 .Fl d
98 option.
99 They have the form
100 .Pa hostname.cert.pem
101 and
102 .Pa hostname.key.pem .
103 If a certificate or a key doesn't exist for a given hostname, they
104 will be generated automatically.
105 .It Fl h , Fl -help
106 Print the usage and exit.
107 .It Fl p Ar port
108 The port to listen on, by default 1965.
109 .It Fl V , Fl -version
110 Print the version and exit.
111 .It Fl v
112 Verbose mode.
113 Multiple
114 .Fl v
115 options increase the verbosity.
116 .It Fl x Pa path
117 Enable execution of
118 .Sx CGI
119 scripts.
120 See the description of the
121 .Ic cgi
122 option in the
123 .Sq Servers
124 section below to learn how
125 .Pa path
126 is processed.
127 Cannot be provided more than once.
128 .It Pa dir
129 The root directory to serve.
130 By default the current working directory is assumed.
131 .El
132 .Sh CONFIGURATION FILE
133 The configuration file is divided into three sections:
134 .Bl -tag -width xxxx
135 .It Sy Macros
136 User-defined variables may be defined and used later, simplifying the
137 configuration file.
138 .It Sy Global Options
139 Global settings for
140 .Nm .
141 .It Sy Servers
142 Virtual hosts definition.
143 .El
144 .Pp
145 Within the sections, empty lines are ignored and comments can be put
146 anywhere in the file using a hash mark
147 .Pq Sq # ,
148 and extend to the end of the current line.
149 A boolean is either the symbol
150 .Sq on
151 or
152 .Sq off .
153 A string is a sequence of characters wrapped in double quotes,
154 .Dq like this .
155 Multiple strings one next to the other are joined into a single
156 string:
157 .Bd -literal -offset indent
158 # equivalent to "temporary-failure"
159 block return 40 "temporary" "-" "failure"
160 .Ed
161 .Pp
162 Furthermore, quoting is necessary only when a string needs to contain
163 special characters
164 .Pq like spaces or punctuation ,
165 something that looks like a number or a reserved keyword.
166 The last example could have been written also as:
167 .Bd -literal -offset indent
168 block return 40 temporary "-" failure
169 .Ed
170 .Pp
171 Strict ordering of the sections is not enforced, so that is possible
172 to mix macros, options and
173 .Ic server
174 blocks.
175 However, defining all the
176 .Ic server
177 blocks after the macros and the global options is recommended.
178 .Pp
179 Newlines are often optional, except around top-level instructions, and
180 semicolons
181 .Dq \&;
182 can also be optionally used to separate options.
183 .Pp
184 Additional configuration files can be included with the
185 .Ic include
186 keyword, for example:
187 .Bd -literal -offset indent
188 include "/etc/gmid.conf.local"
189 .Ed
190 .Ss Macros
191 Macros can be defined that will later be expanded in context.
192 Macro names must start with a letter, digit or underscore and may
193 contain any of those characters.
194 Macros names may not be reserved words.
195 Macros are not expanded inside quotes.
196 .Pp
197 Two kinds of macros are supported: variable-like and proper macros.
198 When a macro is invoked with a
199 .Dq $
200 before its name its expanded as a string, whereas when it's invoked
201 with a
202 .Dq @
203 its expanded in-place.
204 .Pp
205 For example:
206 .Bd -literal -offset indent
207 dir = "/var/gemini"
208 certdir = "/etc/keys"
209 common = "lang it; auto index on"
211 server "foo" {
212 root $dir "/foo" # -> /var/gemini/foo
213 cert $certdir "/foo.crt" # -> /etc/keys/foo.crt
214 key $certdir "/foo.pem" # -> /etc/keys/foo.pem
215 @common
217 .Ed
218 .Ss Global Options
219 .Bl -tag -width 12m
220 .It Ic chroot Pa path
221 .Xr chroot 2
222 the process to the given
223 .Pa path .
224 The daemon has to be run with root privileges and thus the option
225 .Ic user
226 needs to be provided, so privileges can be dropped.
227 Note that
228 .Nm
229 will enter the chroot after loading the TLS keys, but before opening
230 the virtual host root directories.
231 It's recommended to keep the TLS keys outside the chroot.
232 Future version of
233 .Nm
234 may enforce this.
235 .It Ic ipv6 Ar bool
236 Enable or disable IPv6 support, off by default.
237 .It Ic map Ar mime-type Cm to-ext Ar file-extension
238 Map
239 .Ar mime-type
240 to the given
241 .Ar file-extension .
242 Both argument are strings.
243 .It Ic port Ar portno
244 The port to listen on.
245 1965 by default.
246 .It Ic prefork Ar number
247 Run the specified number of server processes.
248 This increases the performance and prevents delays when connecting to
249 a server.
250 When not in config-less mode,
251 .Nm
252 runs 3 server processes by default.
253 The maximum number allowed is 16.
254 .It Ic protocols Ar string
255 Specify the TLS protocols to enable.
256 Refer to
257 .Xr tls_config_parse_protocols 3
258 for the valid protocol string values.
259 By default, both TLSv1.3 and TLSv1.2 are enabled.
260 Use
261 .Dq tlsv1.3
262 to enable only TLSv1.3.
263 .It Ic user Ar string
264 Run the daemon as the given user.
265 .El
266 .Ss Servers
267 Every virtual host is defined by a
268 .Ic server
269 block:
270 .Bl -tag -width Ds
271 .It Ic server Ar hostname Brq ...
272 Match the server name using shell globbing rules.
273 It can be an explicit name,
274 .Ar www.example.com ,
275 or a name including a wildcards,
276 .Ar *.example.com .
277 .El
278 .Pp
279 Followed by a block of options that is enclosed in curly brackets:
280 .Bl -tag -width Ds
281 .It Ic alias Ar name
282 Specify an additional alias
283 .Ar name
284 for this server.
285 .It Ic auto Ic index Ar bool
286 If no index file is found, automatically generate a directory listing.
287 Disabled by default.
288 .It Ic block Op Ic return Ar code Op Ar meta
289 Send a reply and close the connection;
290 by default
291 .Ar code
292 is 40
293 and
294 .Ar meta
295 is
296 .Dq temporary failure .
297 If
298 .Ar code
299 is in the 3x range, then
300 .Ar meta
301 is mandatory.
302 Inside
303 .Ar meta ,
304 the following special sequences are supported:
305 .Bl -tag -width Ds -compact
306 .It \&%\&%
307 is replaced with a single
308 .Sq \&% .
309 .It \&%p
310 is replaced with the request path.
311 .It \&%q
312 is replaced with the query string of the request.
313 .It \&%P
314 is replaced with the server port.
315 .It \&%N
316 is replaced with the server name.
317 .El
318 .It Ic cert Pa file
319 Path to the certificate to use for this server.
320 The
321 .Pa file
322 should contain a PEM encoded certificate.
323 This option is mandatory.
324 .It Ic cgi Pa path
325 Execute
326 .Sx CGI
327 scripts that matches
328 .Pa path
329 using shell globbing rules.
330 .It Ic default type Ar string
331 Set the default media type that is used if the media type for a
332 specified extension is not found.
333 If not specified, the
334 .Ic default type
335 is set to
336 .Dq application/octet-stream .
337 .It Ic entrypoint Pa path
338 Handle all the requests for the current virtual host using the
339 .Sx CGI
340 script at
341 .Pa path ,
342 relative to the current document root.
343 .It Ic env Ar name Cm = Ar value
344 Set the environment variable
345 .Ar name
346 to
347 .Ar value
348 when executing CGI scripts.
349 Can be provided more than once.
350 .\" don't document the "spawn <prog>" form because it probably won't
351 .\" be kept.
352 .It Ic fastcgi Oo Ic tcp Oc Pa socket Oo Cm port Ar port Oc
353 Enable
354 .Sx FastCGI
355 instead of serving files.
356 The
357 .Pa socket
358 can either be a UNIX-domain socket or a TCP socket.
359 If the FastCGI application is listening on a UNIX domain socket,
360 .Pa socket
361 is a local path name within the
362 .Xr chroot 2
363 root directory of
364 .Nm .
365 Otherwise, the
366 .Ic tcp
367 keyword must be provided and
368 .Pa socket
369 is interpreted as a hostname or an IP address.
370 .Ar port
371 can be either a port number or the name of a service enclosed in
372 double quotes.
373 If not specified defaults to 9000.
374 .It Ic index Ar string
375 Set the directory index file.
376 If not specified, it defaults to
377 .Pa index.gmi .
378 .It Ic key Pa file
379 Specify the private key to use for this server.
380 The
381 .Pa file
382 should contain a PEM encoded private key.
383 This option is mandatory.
384 .It Ic lang Ar string
385 Specify the language tag for the text/gemini content served.
386 If not specified, no
387 .Dq lang
388 parameter will be added in the response.
389 .It Ic location Pa path Brq ...
390 Specify server configuration rules for a specific location.
391 The
392 .Pa path
393 argument will be matched against the request path with shell globbing
394 rules.
395 In case of multiple location statements in the same context, the first
396 matching location will be put into effect and the later ones ignored.
397 Therefore is advisable to match for more specific paths first and for
398 generic ones later on.
400 .Ic location
401 section may include most of the server configuration rules
402 except
403 .Ic alias , Ic cert , Ic cgi , Ic entrypoint , Ic env , Ic key ,
404 .Ic location No and Ic param .
405 .It Ic log Ar bool
406 Enable or disable the logging for the current server or location block.
407 .It Ic param Ar name Cm = Ar value
408 Set the param
409 .Ar name
410 to
411 .Ar value
412 for FastCGI.
413 .It Ic root Pa directory
414 Specify the root directory for this server
415 .Pq alas the current Dq document root .
416 It's relative to the chroot if enabled.
417 .It Ic require Ic client Ic ca Pa path
418 Allow requests only from clients that provide a certificate signed by
419 the CA certificate in
420 .Pa path .
421 It needs to be a PEM-encoded certificate and it's not relative to the
422 chroot.
423 .It Ic strip Ar number
424 Strip
425 .Ar number
426 components from the beginning of the path before doing a lookup in the
427 root directory.
428 It's also considered for the
429 .Ar meta
430 parameter in the scope of a
431 .Ic block return .
432 .El
433 .Sh CGI
434 When a request for an executable file matches the
435 .Ic cgi
436 rule, that file will be executed and its output fed to the client.
437 .Pp
438 The CGI scripts are executed in the directory they reside and inherit
439 the environment from
440 .Nm
441 with these additional variables set:
442 .Bl -tag -width 24m
443 .It Ev GATEWAY_INTERFACE
444 .Dq CGI/1.1
445 .It Ev GEMINI_DOCUMENT_ROOT
446 The root directory of the virtual host.
447 .It Ev GEMINI_SCRIPT_FILENAME
448 Full path to the CGI script being executed.
449 .It Ev GEMINI_URL
450 The full IRI of the request.
451 .It Ev GEMINI_URL_PATH
452 The path of the request.
453 .It Ev PATH_INFO
454 The portion of the requested path that is derived from the the IRI
455 path hierarchy following the part that identifies the script itself.
456 Can be unset.
457 .It Ev PATH_TRANSLATED
458 Present if and only if
459 .Ev PATH_INFO
460 is set.
461 It represent the translation of the
462 .Ev PATH_INFO .
463 .Nm
464 builds this by appending the
465 .Ev PATH_INFO
466 to the virtual host directory root.
467 .It Ev QUERY_STRING
468 The decoded query string.
469 .It Ev REMOTE_ADDR , Ev REMOTE_HOST
470 Textual representation of the client IP.
471 .It Ev REQUEST_METHOD
472 This is present only for RFC3875 (CGI) compliance.
473 It's always set to the empty string.
474 .It Ev SCRIPT_NAME
475 The part of the
476 .Ev GEMINI_URL_PATH
477 that identifies the current CGI script.
478 .It Ev SERVER_NAME
479 The name of the server
480 .It Ev SERVER_PORT
481 The port the server is listening on.
482 .It Ev SERVER_PROTOCOL
483 .Dq GEMINI
484 .It Ev SERVER_SOFTWARE
485 The name and version of the server, i.e.
486 .Dq gmid/1.7.3
487 .It Ev AUTH_TYPE
488 The string "Certificate" if the client used a certificate, otherwise
489 unset.
490 .It Ev REMOTE_USER
491 The subject of the client certificate if provided, otherwise unset.
492 .It Ev TLS_CLIENT_ISSUER
493 The is the issuer of the client certificate if provided, otherwise
494 unset.
495 .It Ev TLS_CLIENT_HASH
496 The hash of the client certificate if provided, otherwise unset.
497 The format is
498 .Dq ALGO:HASH .
499 .It Ev TLS_VERSION
500 The TLS version negotiated with the peer.
501 .It Ev TLS_CIPHER
502 The cipher suite negotiated with the peer.
503 .It Ev TLS_CIPHER_STRENGTH
504 The strength in bits for the symmetric cipher that is being used with
505 the peer.
506 .It Ev TLS_CLIENT_NOT_AFTER
507 The time corresponding to the end of the validity period of the peer
508 certificate in the ISO 8601 format
509 .Pq e.g. Dq 2021-02-07T20:17:41Z .
510 .It Ev TLS_CLIENT_NOT_BEFORE
511 The time corresponding to the start of the validity period of the peer
512 certificate in the ISO 8601 format.
513 .El
514 .Sh FastCGI
515 .Nm
516 optionally supports FastCGI.
518 .Ic fastcgi
519 rule must be present in a server or location block.
520 Then, all requests matching that server or location will be handled
521 via the specified FastCGI backend.
522 .Pp
523 By default the following variables
524 .Pq parameters
525 are sent, and carry the same semantics as with CGI.
526 More parameters can be added with the
527 .Ic param
528 option.
529 .Pp
530 .Bl -bullet -compact
531 .It
532 GATEWAY_INTERFACE
533 .It
534 GEMINI_URL_PATH
535 .It
536 QUERY_STRING
537 .It
538 REMOTE_ADDR
539 .It
540 REMOTE_HOST
541 .It
542 REQUEST_METHOD
543 .It
544 SERVER_NAME
545 .It
546 SERVER_PROTOCOL
547 .It
548 SERVER_SOFTWARE
549 .It
550 AUTH_TYPE
551 .It
552 REMOTE_USER
553 .It
554 TLS_CLIENT_ISSUER
555 .It
556 TLS_CLIENT_HASH
557 .It
558 TLS_VERSION
559 .It
560 TLS_CIPHER
561 .It
562 TLS_CIPHER_STRENGTH
563 .It
564 TLS_CLIENT_NOT_BEFORE
565 .It
566 TLS_CLIENT_NOT_AFTER
567 .El
568 .Sh MIME
569 To auto-detect the MIME type of the response
570 .Nm
571 looks at the file extension and consults its internal table.
572 By default the following mappings are loaded, but they can be
573 overridden or extended using the
574 .Ic map
575 configuration option.
576 If no MIME is found, the value of
577 .Ic default type
578 matching the file
579 .Ic location
580 will be used, which is
581 .Dq application/octet-stream
582 by default.
583 .Pp
584 .Bl -tag -offset indent -width 14m -compact
585 .It diff
586 text/x-patch
587 .It gemini, gmi
588 text/gemini
589 .It gif
590 image/gif
591 .It jpeg
592 image/jpeg
593 .It jpg
594 image/jpeg
595 .It markdown, md
596 text/markdown
597 .It patch
598 text/x-patch
599 .It pdf
600 application/pdf
601 .It png
602 image/png
603 .It svg
604 image/svg+xml
605 .It txt
606 text/plain
607 .It xml
608 text/xml
609 .El
610 .Sh LOGGING
611 Messages and requests are logged by
612 .Xr syslog 3
613 using the
614 .Dv DAEMON
615 facility or printed on
616 .Em stderr .
617 .Pp
618 Requests are logged with the
619 .Dv NOTICE
620 severity.
621 Each request log entry has the following fields, separated by
622 whitespace:
623 .Pp
624 .Bl -bullet -compact
625 .It
626 Client IP address and the source port number, separated by a colon
627 .It
628 .Sy GET
629 keyword
630 .It
631 Request URL
632 .It
633 Response status
634 .It
635 Response meta
636 .El
637 .Sh EXAMPLES
638 Serve the current directory
639 .Bd -literal -offset indent
640 $ gmid .
641 .Ed
642 .Pp
643 To serve the directory
644 .Pa docs
645 and enable CGI scripts inside
646 .Pa docs/cgi
647 .Bd -literal -offset indent
648 $ mkdir docs/cgi
649 $ cat <<EOF > docs/cgi/hello
650 #!/bin/sh
651 printf "20 text/plain\er\en"
652 echo "hello world"
653 EOF
654 $ chmod +x docs/cgi/hello
655 $ gmid -x '/cgi/*' docs
656 .Ed
657 .Pp
658 An X.509 certificate must be provided to run
659 .Nm
660 using a configuration file.
661 First, the RSA certificate is created using a wildcard common name:
662 .Bd -literal -offset indent
663 # openssl genrsa \-out /etc/ssl/private/example.com.key 4096
664 # openssl req \-new \-x509 \-key /etc/ssl/private/example.com.key \e
665 \-out /etc/ssl/example.com.crt \-days 36500 \-nodes \e
666 \-subj "/CN=example.com"
667 # chmod 600 /etc/ssl/example.com.crt
668 # chmod 600 /etc/ssl/private/example.com.key
669 .Ed
670 .Pp
671 In the example above, a certificate is valid for one hundred years from
672 the date it was created, which is normal for TOFU.
673 .Pp
674 The following is an example of a possible configuration for a site
675 that enables only TLSv1.3, adds a mime type for the file extension
676 .Qq rtf
677 and defines two virtual host:
678 .Bd -literal -offset indent
679 ipv6 on # enable ipv6
681 protocols "tlsv1.3"
683 map "application/rtf" to-ext "rtf"
685 server "example.com" {
686 cert "/etc/ssl/example.com.crt"
687 key "/etc/ssl/private/example.com.key"
688 root "/var/gemini/example.com"
691 server "it.example.com" {
692 cert "/etc/ssl/example.com.crt"
693 key "/etc/ssl/private/example.com.key"
694 root "/var/gemini/it.example.com"
696 # enable cgi scripts inside "cgi-bin"
697 cgi "/cgi-bin/*"
699 # set the language for text/gemini files
700 lang "it"
702 .Ed
703 .Pp
704 Yet another example, showing how to enable a
705 .Ic chroot
706 and use
707 .Ic location
708 rule
709 .Bd -literal -offset indent
710 chroot "/var/gemini"
711 user "_gmid"
713 server "example.com" {
714 cert "/path/to/cert.pem" # absolute path
715 key "/path/to/key.pem" # also absolute
716 root "/example.com" # relative to the chroot
718 location "/static/*" {
719 # load the following rules only for
720 # requests that matches "/static/*"
722 auto index on
723 index "index.gemini"
726 .Ed
727 .Sh ACKNOWLEDGEMENTS
728 .Nm
729 uses the
730 .Dq Flexible and Economical
731 UTF-8 decoder written by
732 .An Bjoern Hoehrmann .
733 .Sh AUTHORS
734 .An -nosplit
735 The
736 .Nm
737 program was written by
738 .An Omar Polo Aq Mt op@omarpolo.com .
739 .Sh CAVEATS
740 .Bl -bullet
741 .It
742 All the root directories are opened during the daemon startup; if a
743 root directory is deleted and then re-created,
744 .Nm
745 won't be able to serve files inside that directory until a restart.
746 This restriction only applies to the root directories and not their
747 content.
748 .It
749 a %2F sequence is indistinguishable from a literal slash: this is not
750 RFC3986-compliant.
751 .It
752 a %00 sequence is treated as invalid character and thus rejected.
753 .El