diff options
| author | David T. Sadler <davidtsadler@googlemail.com> | 2021-02-07 23:26:24 +0000 |
|---|---|---|
| committer | David T. Sadler <davidtsadler@googlemail.com> | 2021-02-07 23:26:24 +0000 |
| commit | f2fa60c447aaf0548b1e624eeee7fb1519776ba4 (patch) | |
| tree | f71305b9cb18f061dcfbd9755e134e8b5da98160 /source/_posts | |
| parent | cc7167fb6afbfa1079e5da4d0e559e575e8c3313 (diff) | |
Add How to Host Your Own Gemini Site in the Cloud
Diffstat (limited to 'source/_posts')
| -rw-r--r-- | source/_posts/how_to_host_your_own_gemini_site_in_the_cloud.md | 300 |
1 files changed, 300 insertions, 0 deletions
diff --git a/source/_posts/how_to_host_your_own_gemini_site_in_the_cloud.md b/source/_posts/how_to_host_your_own_gemini_site_in_the_cloud.md new file mode 100644 index 0000000..b53fdc7 --- /dev/null +++ b/source/_posts/how_to_host_your_own_gemini_site_in_the_cloud.md @@ -0,0 +1,300 @@ +--- +extends: _layouts.post +section: content +title: How to Host Your Own Gemini Site in the Cloud +date: 2021-02-15 +description: A guide to setting up a cloud server to host a Gemini site. +tags: [Gemini] +--- + +So I have a Gemini site over at gemini://davidtsadler.co.uk and I thought I'd write up how I achieved this in case anyone was interested in doing the same. + +I would say that from purchasing the domain name to having a complete server hosting the site took about 30 minutes in total. + +## Purchasing a Domain Name + +I decided that for the moment I would keep my traditional "Big Web" content hosted at davidtsadler.com and use a different domain name for my new Gemini site. Since this meant purchasing a new one I popped over to Gandi.net to acquire davidtsadler.co.uk. Side note: I used to own this but decided not to renew it for some crazy reason. + +## Creating a cloud sever + +My cloud provider of choice is Hetzner and creating a new server is done in eight steps. + +### 1. Location + +Hetzner provide a few locations in Europe as to where the server is hosted. For this server I chose Helsinki. + +### 2. Image + +I chose Ubuntu 20.04 as the operating system as this is the one I'm most familiar with. + +### 3. Type + +As this server is only going to a host a Gemini site I don't need a overly powerful system so I chose their most basic CX11 configuration. For €2.99 a month this gives me: + +- 1 virtual CPU. +- 2GB ram. +- 20GB SSD . +- 20 TB of network traffic a month. + +### 4. Volume + +You have the option of attaching additional storage to the server. I skipped this step as for the time been the 20GB SSD that comes with the server should be enough for my needs. + +### 5. Network. + +I skipped this step as its not needed. + +### 6. Additional features + +Again I skipped this step but select any if you believe that you will need them. + +### 7. SSH Key + +When a server is created a root user is added and a password is emailed to you so that you can login. However if you provide a SSH key it will be installed on the server instead of creating a password. + +I like to use separate keys for each server that I manage so I tend store the them in a directory named after the hostname. + +```shell +$ mkdir ~/.ssh/davidtsadler.co.uk + +$ ssh-keygen -t rsa -b 4096 -f ~/.ssh/davidtsadler.co.uk/id_rsa +``` + +The SSH key is added by clicking + ADD SSH KEY and then copying and pasting the contents of the id_rsa.pub file. + +### 8. Name + +I name my servers after the hostname so for this I called it davidtsadler.co.uk. I then created the server by clicking CREATE & BUY NOW. + +## SSH + +Once the server was created I took the allocated IP address and ensured that I could access it via SSH using the key that I had provided. + +```shell +$ ssh root@135.181.201.71 -i ~/.ssh/davidtsadler.co.uk/id_rsa +``` + +## Resolve the Domain Name to the Server + +In my Gandi.net account I went to the DNS Records section for the domain name I had purchased. There I deleted everything except for the @ (A) and www (CNAME) records which was configured as follows: + +- @ (A) 135.181.201.71 +- www (CNAME) davidtsadler.co.uk. + +The A record is configured with the IPv4 address of my new server and the CNAME with the domain name. Note that the CNAME must end with a period! + +After saving the changes it was just a matter of waiting for it to propagate through the DNS system. At which point I could use the domain name when logging in via SSH. + +```shell +$ ssh root@davidtsadler.co.uk -i ~/.ssh/davidtsadler.co.uk/id_rsa +``` + +## Securing the Server + +At a bare minimum I setup a firewall and harden SSH. I may at a later date go further, such as installing fail2ban. + +### Configure a Firewall + +This setup will deny any incoming requests unless they were first initiated by a request from the server. Since I need to be able to access the server I allow SSH. The Gemini protocol uses port 1965 so that is also allowed. + +```shell +$ ufw default allow outgoing +$ ufw default deny incoming +$ ufw allow OpenSSH +$ ufw allow 1965 +$ ufw enable +``` + +### Harden SSH + +I edited the /etc/ssh/sshd_config file. + +```shell +$ vim /etc/ssh/sshd_config +``` + +I added the two below options so that the root user is not allowed to access the sever via SSH and other users may only access using keys. + +``` +PermitRootLogin no +PasswordAuthentication no +``` + +Since I'd made changes to the configuration I needed to restart the SSH service. + +```shell +$ service sshd restart +``` + +### Create non-root User + +Whenever I access a server I like to login as a non-root user that is able to run sudo on the system. + +```shell +$ adduser gemini + +$ usermod -aG sudo gemini +``` + +As the SSH key is already on the server I can copy it to the non-root user account. + +```shell +$ rsync --archive --chown=gemini:gemini ~/.ssh /home/gemini +``` + +On my local system I confirm that I can log in as the new user without a password. + +```shell +$ ssh gemini@davidtsadler.co.uk -i ~/.ssh/davidtsadler.co.uk/id_rsa +``` + +I also confirm that I have sudo access. + +```shell +$ sudo ls +``` + +## Installing a Gemini Site and Server + +### Directory structure + +I decided to go with a very simple directory structure. Each site will be a sub-directory in ~/sites that will be named after the domain name. Then each site will have the following sub-directories. The idea is that I may want to host more than one site in the future. + +- bin This will contain the Gemini server binary. +- certs TLS certificates for the site are kept here. +- public This will contain the .gmi files of the site. +- scripts Contains scripts used to start the Gemini server. + +I created the directory structure with the below command. + +```shell +$ mkdir -p ~/sites/davidtsadler.co.uk/{bin,certs,public,scripts} +``` + +### Install certificates + +Sine the Gemini protocol encourages using a self-signed certificate I installed one with the openssl command. + +```shell +$ openssl req -x509 \ + -newkey rsa:4096 \ + -keyout ~/sites/davidtsadler.co.uk/certs/key.rsa \ + -out ~/sites/davidtsadler.co.uk/certs/cert.pem \ + -days 3650 \ + -nodes \ + -subj "/CN=davidtsadler.co.uk" +``` + +### Create Some Test Content + +I created a very simple index.gmi file purely for testing. + +```shell +$ cat << EOF > ~/sites/davidtsadler.co.uk/public/index.gmi +# Welcome + +Hello world! +EOF +``` + +### Install the Gemini Server Binary + +I decided to go with agate as the Gemini server as its very simple to install and configure. Installing it was a matter of downloading the binary archive into the bin directory and setting the executable permission on it. + + +```shell +$ cd ~/sites/davidtsadler.co.uk/bin + +$ wget https://github.com/mbrubeck/agate/releases/download/v2.3.0/agate.x86_64-unknown-linux-gnu.gz + +$ gunzip agate.x86_64-unknown-linux-gnu.gz + +$ mv agate.x86_64-unknown-linux-gnu agate + +$ chmod u+x agate +``` + +I wrote a very simple bash script to run agate and have it serve the site. + +```shell +$ cat << EOF > ~/sites/davidtsadler.co.uk/scripts/start +#!/bin/bash + +/home/gemini/sites/davidtsadler.co.uk/bin/agate \ + --content /home/gemini/sites/davidtsadler.co.uk/public/ \ + --key /home/gemini/sites/davidtsadler.co.uk/certs/key.rsa \ + --cert /home/gemini/sites/davidtsadler.co.uk/certs/cert.pem \ + --addr [::]:1965 \ + --addr 0.0.0.0:1965 \ + --hostname davidtsadler.co.uk \ + --lang en-GB +EOF + +$ chmod u+x ~/sites/davidtsadler.co.uk/scripts/start +``` + +### Testing the Site + +At this point I have the Gemini server installed and a site available for testing. + +I first started agate with the bash script. + +```shell +$ ~/sites/davidtsadler.co.uk/scripts/start + +[2021-02-05T17:26:56Z INFO agate] Listening on [[::]:1965, 0.0.0.0:1965]... +``` + +With agate up and running I pointed my Gemini client to gemini://davidtsadler.co.uk and confirmed I was able to access the site before entering Ctrl-C to halt agate. + +### Configure Sytemd + +Since I was happy that agate was able to serve my new site I created a systemd unit to ensure that agate was started whenever the system was rebooted. + +```shell +$ sudo vim /etc/systemd/system/agate.service +``` + +The unit is very simple and just runs the bash script to start agate once the network is available. + +``` +[Unit] +Description=Agate Gemini Server +After=network.target + +[Service] +Type=simple +User=gemini +Group=gemini +ExecStart=/home/gemini/sites/davidtsadler.co.uk/scripts/start + +[Install] +WantedBy=default.target +``` + +I then started this service and confirmed it was working. + +``` +$ sudo systemctl start agate.service + +$ sudo systemctl status agate.service + +Active: active (running) +``` + +The final step was to have this service start when the system is rebooted. + +``` +$ sudo systemctl enable agate.service +``` + +## Conclusion + +Setting up a Gemini site was easy to do and I hope this guide shows it. I have several ideas about how I'm going to use this new site and I'm excited to see where this leads to. + +## Links + +- [Gandi.net](https://www.gandi.net) My domain registrar of choice. +- [Hetzner](https://hetzner.cloud/?ref=Gf3UFbRaixBK) My cloud server provider. +- [Agate](https://github.com/mbrubeck/agate) A simple Gemini server. +- [davidtsadler.co.uk](gemini://davidtsadler.co.uk) My Gemini site. |
