1# A simplistic and secure Gemini server
2
3**Vger** is a gemini server supporting chroot, virtualhosts, CGI, default language choice, redirections and MIME types detection.
4
5**Vger** design is relying on inetd and a daemon to take care of TLS.  The idea is to delegate TLS and network to daemons which proved doing it correctly, so vger takes its request from stdin and output the result to stdout.
6
7The average setup should look like:
8
9```
10         client
11           ↓           TCP request on port 1965
12       relayd or haproxy
13       or stunnel on inetd
14           ↓           TCP request to a port of choice on localhost
15       vger on inetd
16```
17
18**Vger** is perfectly secure if run on **OpenBSD**, using `unveil()` the filesystem access is restricted to one directory (default to `/var/gemini/`) and with `pledge()` only systems calls related to reading files and reading input/output are allowed. More explanations about Vger security can be found [on this link](https://dataswamp.org/~solene/2021-01-14-vger-security.html).
19
20For all supported OS, it's possible to run **Vger** in a chroot and drop privileges to a dedicated user.
21
22
23# Install
24
25```
26git clone https://tildegit.org/solene/vger.git
27cd vger
28./configure (only really useful for Linux)
29make
30doas make install
31```
32
33On GNU/Linux, make sure you installed `libbsd`, it has been reported that using clang was required too.
34
35# Running tests
36
37**Vger** comes with a test suite you can use with `make test`.
38
39Some files under `/var/gemini/` are required to test the code path without a `-d` parameter.
40
41
42# Command line parameters
43
44**Vger**  has a few parameters you can use in inetd configuration.
45
46- `-d PATH`: use `PATH` as the data directory to serve files from. Default is `/var/gemini`
47- `-l LANG`: change the language in the status return code. Default is no language specified.
48- `-v`: enable virtualhost support, the hostname in the query will be considered as a directory name.
49- `-u username`: enable chroot to the data directory and drop privileges to `username`.
50- `-m MIME` : use MIME as default instead of "application/octet-stream".
51- `-i` : Enable auto index if no "index.gmi" file is found in a directory.
52- `-c CGI_PATH` : files in CGI_PATH are executed and their output is returned to the client.
53
54
55# How to configure Vger using relayd and inetd
56
57Create directory `/var/gemini/` (I'd allow this to be configured later), files will be served from there.
58
59Create an user `gemini_user`.
60
61Add this line to inetd.conf:
62
63```
64127.0.0.1:11965 stream tcp nowait gemini_user /usr/local/bin/vger vger
65```
66
67Add this to relayd.conf
68```
69log connection
70tcp protocol "gemini" {
71    tls keypair hostname.example
72}
73
74relay "gemini" {
75    listen on hostname.example port 1965 tls
76    protocol "gemini"
77    forward to 127.0.0.1 port 11965
78}
79```
80
81Make sure certificates files match hostname:
82`/etc/ssl/private/hostname.example.key` and
83`/etc/ssl/hostname.example.crt`.
84
85On OpenBSD, enable inetd and relayd and start them:
86```
87# rcctl enable relayd inetd
88# rcctl start relayd inetd
89```
90
91Don't forget to open the TCP port 1965 in your firewall.
92
93Vger will serve files named `index.gmi` if no explicit filename is given. If this file doesn't exist and auto index is enabled, an index file with a link to every file in the directory will be served.
94