💾 Archived View for gemini.susa.net › gemserv_proot.gmi captured on 2023-09-28 at 15:59:26. Gemini links have been rewritten to link to archived content

View Raw

More Information

⬅️ Previous capture (2023-01-29)

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

Running gemserv under proot

I want to run gemserv in a simple container for process isolation from the main filesystem. The simplest container technique is 'chroot', which lets you run a process with a virtual root filesystem, or 'proot', which does similar but doesn't require root any privileges. Since gemserv itself doesn't require root privileges, and 'proot' does everything I need, that's what I'll use in this instance.

The main benefit of all this is security, since it limits what can be seen by at attacker if the server is compromised in some way. It's not particularly strong security, but it's enough to mitigate the reach of many simple attacks, like those we saw in gemserv when dereferencing relative paths.

The script I use now to launch gemserv looks as follows:

#!/bin/bash

# Launch gemserv in a proot container. The content and cgi-assets directories
# are mounted into the continer filesystem.

proot \
    -r /home/kevsan/gemini/rootfs/ \
    -w /home/gemini \
    -b /bin \
    -b /usr \
    -b /lib \
    -b /lib64 \
    -b /home/kevsan/gemini/cgi_assets:/home/gemini/cgi_assets \
    -b /home/kevsan/gemini/content:/home/gemini/content \
    -b /home/kevsan/.znc/users/kevsan/moddata/log/tilde \
    ./gemserv ./config.toml

In the above, the -r specifies the location of my 'virtual' root filesystem, -w defines the working directory the gemserv process should run in (from the containers point of view), and the -b options define the host's filesystem entries that should be visible in the container.

The last line above is simply the command that should be run as the isolated process. In this instance it's just the gemserv binary. Note that it's defined as a path in the container's filesystem view.

So, the files that are needed in order to launch gemserv are: the binary, the config, and the server's certificate. Everything else is just passed through from the host filesystem with the '-b' entries above. Therefore, the simplest root filesystem is as follows:

rootfs
rootfs/home
rootfs/home/gemini
rootfs/home/gemini/gemserv
rootfs/home/gemini/config.toml
rootfs/home/gemini/serv.crt
rootfs/home/gemini/serv.key

This setup maps the existing 'content' and 'cgi_assets' that I had from my non-container setup, in part because I can fall back to running it the old way if needed, but also because it means any existing scripts that run outside of the server don't need to be modified. I also need to map in the ZNC logs that I use for my view of the #gemini IRC channel.

So far, all my cgi-bin scripts seem to run fine with the directories I've included. If anything fails, it should be simple enough for me to figure out what's needed and map that in too.

A few of my CGI scripts contained absolute paths where relative paths should really have been used, so I fixed these up which means they now run regardless of whether or not I run gemserv in a proot container.