💾 Archived View for sanctum.geek.nz › setup.gmi captured on 2020-09-24 at 01:03:36. Gemini links have been rewritten to link to archived content

View Raw

More Information

-=-=-=-=-=-=-

Gemini with shavit, socat, and systemd

This assumes you’ve already got a Let’s Encrypt cert. The server is hardcoded to listen on IPv4-only «localhost» by default, so we add a couple of «socat» tunnels. We also build the server binary statically and run it in a «chroot» environment in such a way that the certificates are legible to it. The whole thing runs comfortably in under 8 MiB of memory—kind of amazing.

Build, install server

~yotam/shavit

$ sudo apt install golang socat  # <tesla_> bro i just apt install $x and it works lol
$ git clone https://git.sr.ht/~yotam/shavit
$ cd shavit
$ CGO_ENABLED=0 GOOS=linux go build -a -ldflags '-extldflags "-static"' .
$ sudo cp shavit /usr/local/bin

Configure server

$ sudo mkdir /etc/shavit
$ sudoedit /etc/shavit/config.toml  # See below
$ sudo adduser --group --home /var/lib/gemini --system gemini  # Debian
$ sudo mkdir -p /var/gemini

Create index

$ sudo chmod g+w /var/gemini
$ sudo chgrp -- "$(id -gn)" /var/gemini
$ vi /var/gemini/index.gmi

Add custom services(5) entry

$ printf 'gemini\t1965/tcp\n' | sudo tee -a /etc/services

Start services

$ sudo systemctl enable shavit.service  # See sample units below
$ sudo systemctl start shavit.service
$ sudo systemctl status shavit.service
â—Ź gemini.slice - Gemini services
   Loaded: loaded (/etc/systemd/system/gemini.slice; static; vendor preset: enabled)
   Active: active since Sun 2020-08-30 01:09:45 NZST; 2min 24s ago
       IP: 10.1K in, 17.2K out
    Tasks: 6
   Memory: 3.1M (high: 8.0M)
      CPU: 356ms
   CGroup: /gemini.slice
           ├─gemini-proxy@TCP4.service
           │ └─27569 /usr/bin/socat -d -d TCP4-LISTEN:gemini,reuseaddr,fork,bind=example.com TCP4:localhost:gemini
           ├─gemini-proxy@TCP6.service
           │ └─27568 /usr/bin/socat -d -d TCP6-LISTEN:gemini,reuseaddr,fork,bind=example.com TCP4:localhost:gemini
           └─shavit.service
             └─27570 /usr/local/bin/shavit
…
$ sudo ss -lrtp '( sport = :1965 )'
State   Recv-Q  Send-Q  Local Address:Port    Peer Address:Port
LISTEN  0       128         localhost:gemini       0.0.0.0:*     users:(("shavit",pid=29963,fd=3))
LISTEN  0       5         example.com:gemini       0.0.0.0:*     users:(("socat",pid=29993,fd=5))
LISTEN  0       5         example.com:gemini          [::]:*     users:(("socat",pid=29992,fd=5))

/etc/shavit/config.toml

source = "/var/gemini"
tls_certificate = "/etc/letsencrypt/live/example.com/fullchain.pem"
tls_key = "/etc/letsencrypt/live/example.com/privkey.pem"

/etc/systemd/system/shavit.service

[Unit]
Description=Gemini server
Wants=gemini-proxy@TCP4.service gemini-proxy@TCP6.service

[Service]
Slice=gemini.slice
RootDirectory=/srv/gemini
BindReadOnlyPaths=/etc/letsencrypt/live/example.com/fullchain.pem
BindReadOnlyPaths=/etc/letsencrypt/live/example.com/privkey.pem
BindReadOnlyPaths=/etc/mime.types
BindReadOnlyPaths=/etc/shavit/config.toml
BindReadOnlyPaths=/usr/local/bin/shavit
BindReadOnlyPaths=/var/gemini
ExecStart=shavit
User=gemini
IPAddressAllow=localhost
IPAddressDeny=any
NoNewPrivileges=yes
PrivateDevices=yes
PrivateTmp=yes
ProtectHome=yes
ProtectSystem=strict
RemoveIPC=yes
RestrictAddressFamilies=AF_INET AF_INET6

[Install]
WantedBy=multi-user.target

/etc/systemd/system/gemini-proxy@.service

[Unit]
Description=Gemini server: %i proxy
Requires=network-online.target
Wants=gemini.service

[Service]
Slice=gemini.slice
ExecStart=socat -d -d %i-LISTEN:gemini,reuseaddr,fork,bind=sanctum.geek.nz TCP4:localhost:gemini
DynamicUser=yes
NoNewPrivileges=yes
PrivateDevices=yes
RestrictAddressFamilies=AF_INET AF_INET6

/etc/systemd/system/gemini.slice

[Unit]
Description=Gemini services

[Slice]
CPUAccounting=true
CPUQuota=10%
IOAccounting=true
IPAccounting=true
MemoryAccounting=true
MemoryHigh=8388608
TasksAccounting=true

Back to tejr's capsule