1 .\" Copyright (c) 2021 Omar Polo <op@omarpolo.com>
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.
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$
19 .Nd simple and secure Gemini server
25 .Op Fl D Ar macro Ns = Ns Ar value
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
45 rereads the configuration file when it receives
48 The options are as follows:
51 Specify the configuration file.
52 .It Fl D Ar macro Ns = Ns Ar value
58 Overrides the definition of
60 in the config file if present.
62 Stays and logs on the foreground.
64 Check that the configuration is valid, but don't start the server.
66 Write daemon's pid to the given location.
68 will also act as lock: if another process is holding a lock on that
74 If no configuration file is given,
76 will look for the following options
80 .It Fl d Pa certs-path
81 Directory where certificates for the config-less mode are stored.
83 .Pa $XDG_DATA_HOME/gmid ,
85 .Pa ~/.local/share/gmid .
92 Certificates for the given
94 are searched inside the
96 directory given with the
100 .Pa hostname.cert.pem
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.
106 Print the usage and exit.
108 The port to listen on, by default 1965.
109 .It Fl V , Fl -version
110 Print the version and exit.
115 options increase the verbosity.
120 See the description of the
124 section below to learn how
127 Cannot be provided more than once.
129 The root directory to serve.
130 By default the current working directory is assumed.
132 .Sh CONFIGURATION FILE
133 The configuration file is divided into three sections:
136 User-defined variables may be defined and used later, simplifying the
138 .It Sy Global Options
142 Virtual hosts definition.
145 Within the sections, empty lines are ignored and comments can be put
146 anywhere in the file using a hash mark
148 and extend to the end of the current line.
149 A boolean is either the symbol
153 A string is a sequence of characters wrapped in double quotes,
155 Multiple strings one next to the other are joined into a single
157 .Bd -literal -offset indent
158 # equivalent to "temporary-failure"
159 block return 40 "temporary" "-" "failure"
162 Furthermore, quoting is necessary only when a string needs to contain
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
171 Strict ordering of the sections is not enforced, so that is possible
172 to mix macros, options and
175 However, defining all the
177 blocks after the macros and the global options is recommended.
179 Newlines are often optional, except around top-level instructions, and
182 can also be optionally used to separate options.
184 Additional configuration files can be included with the
186 keyword, for example:
187 .Bd -literal -offset indent
188 include "/etc/gmid.conf.local"
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.
197 Two kinds of macros are supported: variable-like and proper macros.
198 When a macro is invoked with a
200 before its name its expanded as a string, whereas when it's invoked
203 its expanded in-place.
206 .Bd -literal -offset indent
208 certdir = "/etc/keys"
209 common = "lang it; auto index on"
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
220 .It Ic chroot Pa path
222 the process to the given
224 The daemon has to be run with root privileges and thus the option
226 needs to be provided, so privileges can be dropped.
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.
236 Enable or disable IPv6 support, off by default.
237 .It Ic map Ar mime-type Cm to-ext Ar file-extension
242 Both argument are strings.
243 .It Ic port Ar portno
244 The port to listen on.
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
250 When not in config-less mode,
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.
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.
262 to enable only TLSv1.3.
263 .It Ic user Ar string
264 Run the daemon as the given user.
267 Every virtual host is defined by a
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,
279 Followed by a block of options that is enclosed in curly brackets:
282 Specify an additional alias
285 .It Ic auto Ic index Ar bool
286 If no index file is found, automatically generate a directory listing.
288 .It Ic block Op Ic return Ar code Op Ar meta
289 Send a reply and close the connection;
296 .Dq temporary failure .
299 is in the 3x range, then
304 the following special sequences are supported:
305 .Bl -tag -width Ds -compact
307 is replaced with a single
310 is replaced with the request path.
312 is replaced with the query string of the request.
314 is replaced with the server port.
316 is replaced with the server name.
319 Path to the certificate to use for this server.
322 should contain a PEM encoded certificate.
323 This option is mandatory.
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
336 .Dq application/octet-stream .
337 .It Ic entrypoint Pa path
338 Handle all the requests for the current virtual host using the
342 relative to the current document root.
343 .It Ic env Ar name Cm = Ar value
344 Set the environment variable
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
352 .It Ic fastcgi Oo Ic tcp Oc Pa socket Oo Cm port Ar port Oc
355 instead of serving files.
358 can either be a UNIX-domain socket or a TCP socket.
359 If the FastCGI application is listening on a UNIX domain socket,
361 is a local path name within the
367 keyword must be provided and
369 is interpreted as a hostname or an IP address.
371 can be either a port number or the name of a service enclosed in
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
379 Specify the private key to use for this server.
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.
388 parameter will be added in the response.
389 .It Ic location Pa path Brq ...
390 Specify server configuration rules for a specific location.
393 argument will be matched against the request path with shell globbing
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.
401 section may include most of the server configuration rules
403 .Ic alias , Ic cert , Ic cgi , Ic entrypoint , Ic env , Ic key ,
404 .Ic location No and Ic param .
406 Enable or disable the logging for the current server or location block.
407 .It Ic param Ar name Cm = Ar value
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
421 It needs to be a PEM-encoded certificate and it's not relative to the
423 .It Ic strip Ar number
426 components from the beginning of the path before doing a lookup in the
428 It's also considered for the
430 parameter in the scope of a
434 When a request for an executable file matches the
436 rule, that file will be executed and its output fed to the client.
438 The CGI scripts are executed in the directory they reside and inherit
441 with these additional variables set:
443 .It Ev GATEWAY_INTERFACE
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.
450 The full IRI of the request.
451 .It Ev GEMINI_URL_PATH
452 The path of the request.
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.
457 .It Ev PATH_TRANSLATED
458 Present if and only if
461 It represent the translation of the
464 builds this by appending the
466 to the virtual host directory root.
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.
477 that identifies the current CGI script.
479 The name of the server
481 The port the server is listening on.
482 .It Ev SERVER_PROTOCOL
484 .It Ev SERVER_SOFTWARE
485 The name and version of the server, i.e.
488 The string "Certificate" if the client used a certificate, otherwise
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
495 .It Ev TLS_CLIENT_HASH
496 The hash of the client certificate if provided, otherwise unset.
500 The TLS version negotiated with the peer.
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
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.
516 optionally supports 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.
523 By default the following variables
525 are sent, and carry the same semantics as with CGI.
526 More parameters can be added with the
564 TLS_CLIENT_NOT_BEFORE
569 To auto-detect the MIME type of the response
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
575 configuration option.
576 If no MIME is found, the value of
580 will be used, which is
581 .Dq application/octet-stream
584 .Bl -tag -offset indent -width 14m -compact
611 Messages and requests are logged by
615 facility or printed on
618 Requests are logged with the
621 Each request log entry has the following fields, separated by
626 Client IP address and the source port number, separated by a colon
638 Serve the current directory
639 .Bd -literal -offset indent
643 To serve the directory
645 and enable CGI scripts inside
647 .Bd -literal -offset indent
649 $ cat <<EOF > docs/cgi/hello
651 printf "20 text/plain\er\en"
654 $ chmod +x docs/cgi/hello
655 $ gmid -x '/cgi/*' docs
658 An X.509 certificate must be provided to run
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
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.
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
677 and defines two virtual host:
678 .Bd -literal -offset indent
679 ipv6 on # enable ipv6
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"
699 # set the language for text/gemini files
704 Yet another example, showing how to enable a
709 .Bd -literal -offset indent
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/*"
730 .Dq Flexible and Economical
731 UTF-8 decoder written by
732 .An Bjoern Hoehrmann .
737 program was written by
738 .An Omar Polo Aq Mt op@omarpolo.com .
742 All the root directories are opened during the daemon startup; if a
743 root directory is deleted and then re-created,
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
749 a %2F sequence is indistinguishable from a literal slash: this is not
752 a %00 sequence is treated as invalid character and thus rejected.