💾 Archived View for altesq.net › ~evenfire › posts › 2022-05-18.gmi captured on 2023-07-10 at 13:36:26. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2023-01-29)
-=-=-=-=-=-=-
Stacksmith recently wanted a simple Gemini self hosting tutorial, so here I go.
The guide contains everything from installing, to hardening with a Systemd service.
There are many choices here, because of the simplicity of the protocol, but personal favorites of mine are Gemserv and Agate, both which are written in Rust. In this tutorial, I'll focus on Agate due to it's simplicity.
Download the latest binary for your corresponding architecture.
You can find your CPU architecture doing `$ uname -r` and looking at the kernel version. For example if you're on RaspberryPi OS 64-bit, you're running arm64/aarch64.
Agate doesn't support CGI, so you cannot run any fancy scripts, but this comes with much improved security. If you wish to run only static pages, choose Agate. Gemserv supports CGI, but it can be easily disabled in the configuration file. The procedure with Gemserv is basically the same, you just use the Gemserv binary and create the Gemserv configuration file and edit a few different settings. You can use the same Systemd service with the respective variables changed.
Once you have your binary downloaded to the server (you can simply use `wget` or `curl`), you have to make it executable. `$ chmod +x <filename>` will add the executable flag to the file. To make it be in your PATH (so you don't need to type the full path, e.g. /some/place/agate you just type `agate`), you have to move it to /usr/local/bin. `# mv agate /usr/local/bin/`. You now have agate installed, ready to be configured. It's configured only through environment variables, no configuration files for the sake of simplicity.
If you have a firewall up and running, (which I hope you do!), you must allow port `1965` on TCP. For example with ufw: `# ufw allow 1965/tcp`.
To make Agate run in a separate non-root user, which is good practice, we have to make one. `# useradd -r agate`
We have to let Systemd manage Agate, so it can harden the process and manage its boot up behavior. I've included a hardened systemd file below, which is tested by me, it also runs on my server. It denies access to most exploitable places in an OS by a process. Place it in `/etc/systemd/system/`.
Make sure to edit the domain name to your corresponding domain name, and the working directory & the command argument to the directory where your index.gmi is. I use /srv/gemini, but you can use whatever directory you please. Also, double check the user you created has access to the mentioned directory. If you want to support TLS 1.2, you can also remove the `--only-tls13` flag.
After you've got the service file configured, execute `# systemctl daemon-reload` in order for Systemd to pick up the new service file.
As mentioned above, the `agate` user must have access to the gemini capsule files. In this example I'll use `/srv/gemini`. First create it, `# mkdir /srv/gemini/` then copy your capsule files over there. Then to change permissions, `# chmod -R agate:agate /srv/gemini/`.
On first run, agate will generate a self-signed certificate with an expiration time of 4096-01-01, so you don't have to worry about that, although they can be changed manually. They reside in your working directory that's specified in the systemd service file, in the `.certificates` directory.
All there is left to do is to enable and start the service at boot up. `# systemctl enable --now agate`, and check if it serves your Gemini capsule!
If something goes wrong, browse the journal log of the agate service: `# journalctl -u agate.service` in order to see what errors it displays.
Double check your firewall configuration and that the user has been created and everything works.