How to setup vger, a gemini server


Sun, 11 Sep 2022


I recently setup vger, a gemini server to replace agate on ~vern.

The main reason was the great virtual-hosts support (You just put a directory with the domain name in the dir and its rendered on it, no reload or anything!)

Heres some instructions on how I did that, on GNU/Linux.

Firstly, one of the hurdles i came across was that the instructions at the git repo were very BSD-focused.

In our setup, vger runs on the PubNixVM and the TLS Termination Proxy runs on the tilserv.

To install vger, I git clon’d the repo, then ran nix-shell to get a shell with all the deps I need. After that I just ran ./configure and make, like any old unix program.

To start vger though, is a lot more weird. It cannot be started standalone, instead you have to start it through inetd (or an equivalent like xinetd).

I went with Xinetd, and used its nix service to set it up.

services.xinetd.enable = true; = [ vger = [ {
  name = "vger";
  user = "gemini";
  server = "/var/gemini/vger/vger";
  serverArgs = "-v -i -c cgi-bin";
  protocol = "tcp";
  port = 11965;
  unlisted = true;
} ];

This translated to a Xinetd.conf that looks like this :-

  log_type       = SYSLOG daemon info
  log_on_failure = HOST
  log_on_success = PID HOST DURATION EXIT

service vger
  protocol    = tcp
  type        = UNLISTED
  socket_type = stream
  port        = 11965
  wait        = no
  user        = gemini
  server      = /var/gemini/vger/vger
  server_args = -v -i

Additionally, I enabled syslog with services.syslogd.enable = true; and set ForwardToWall=no in journald.conf (services.journald.extraConfig = "ForwardToWall=no";) so that it won’t spam my terminal every time someone visits the capsule.

With a quick nixos-rebuild switch, vger is running on port 11965.

-v flag enabled virtual hosts. This means when you visit, vger will look for the directory /var/gemini/

But if you try to visit localhost:11965 with any gemini client, it will just give you a TLS error.

This is because vger does not handle TLS, instead out-sourcing that to relayd, which hasn’t been ported to GNU/Linux.

So, instead of that, I used this simple (100 LOC) Go project called TLSify

Its really simple, just run tlsify tcp4 :11965 tcp4 :1965 /path/to/cert.pem /path/to/privkey.pem

I also made a systemd service for it :-

Description=TLS Termination Proxy for vger

ExecStart=/usr/local/bin/tlsify tcp4 tcp4 :1965 /etc/letsencrypt/live/ /etc/letsencrypt/live/


Now, just open 1965 through your firewall and you can access your gemini server!

While vger does support CGI, it does not support TLS_CLIENT_HASH since TLS is not handled by it.

Hence some gemini cgi progs will not work (mainly ones that need authentication)

If you have any doubts/questions/recommendations, feel free to ask in #vern-chat