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