From 4bbe114c1a859acd12f1dfdcdb04c53ba2d1dc0b Mon Sep 17 00:00:00 2001 From: "David T. Sadler" Date: Sat, 22 May 2021 12:54:42 +0100 Subject: Ensure html is valid in atom feeds --- www/posts/gemini/atom.xml | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'www/posts/gemini') diff --git a/www/posts/gemini/atom.xml b/www/posts/gemini/atom.xml index 7359329..c0c1da9 100644 --- a/www/posts/gemini/atom.xml +++ b/www/posts/gemini/atom.xml @@ -12,26 +12,26 @@ David T. Sadler. 2021-02-08T12:00:00Z 2021-02-08T12:00:00Z - ![CDATA[

How to Host Your Own Gemini Site in the Cloud

Mon 8th February 2021 By David T. Sadler.

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:

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.

$ mkdir ~/.ssh/davidtsadler.co.uk
+    <h1>How to Host Your Own Gemini Site in the Cloud</h1><blockquote>Mon 8th February 2021 By David T. Sadler.</blockquote><p>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.</p><p>I would say that from purchasing the domain name to having a complete server hosting the site took about 30 minutes in total.</p><h2>Purchasing a Domain Name</h2><p>I decided that for the moment I would keep my traditional &quot;Big Web&quot; 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.</p><h2>Creating a cloud sever</h2><p>My cloud provider of choice is Hetzner and creating a new server is done in eight steps.</p><h3>1. Location</h3><p>Hetzner provide a few locations in Europe as to where the server is hosted. For this server I chose Helsinki.</p><h3>2. Image</h3><p>I chose Ubuntu 20.04 as the operating system as this is the one I'm most familiar with.</p><h3>3. Type</h3><p>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:</p><ul><li>1 virtual CPU.</li><li>2GB ram.</li><li>20GB SSD .</li><li>20 TB of network traffic a month.</li></ul><h3>4. Volume</h3><p>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.</p><h3>5. Network.</h3><p>I skipped this step as its not needed.</p><h3>6. Additional features</h3><p>Again I skipped this step but select any if you believe that you will need them.</p><h3>7. SSH Key</h3><p>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.</p><p>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.</p><pre><code class="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.

$ 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:

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.

$ 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.

$ ufw default allow outgoing
+$ ssh-keygen -t rsa -b 4096 -f ~/.ssh/davidtsadler.co.uk/id_rsa</code></pre><p>The SSH key is added by clicking + ADD SSH KEY and then copying and pasting the contents of the id_rsa.pub file.</p><h3>8. Name</h3><p>I name my servers after the hostname so for this I called it davidtsadler.co.uk. I then created the server by clicking CREATE &amp; BUY NOW.</p><h2>SSH</h2><p>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.</p><pre><code class="shell">$ ssh root@135.181.201.71 -i ~/.ssh/davidtsadler.co.uk/id_rsa</code></pre><h2>Resolve the Domain Name to the Server</h2><p>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:</p><ul><li>@ (A) 135.181.201.71</li><li>www (CNAME) davidtsadler.co.uk.</li></ul><p>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!</p><p>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.</p><pre><code class="shell">$ ssh root@davidtsadler.co.uk -i ~/.ssh/davidtsadler.co.uk/id_rsa</code></pre><h2>Securing the Server</h2><p>At a bare minimum I setup a firewall and harden SSH. I may at a later date go further, such as installing fail2ban.</p><h3>Configure a Firewall</h3><p>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.</p><pre><code class="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.

$ 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.

$ 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.

$ adduser gemini
+$ ufw enable</code></pre><h3>Harden SSH</h3><p>I edited the /etc/ssh/sshd_config file.</p><pre><code class="shell">$ vim /etc/ssh/sshd_config</code></pre><p>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.</p><pre>PermitRootLogin no
+PasswordAuthentication no</pre><p>Since I'd made changes to the configuration I needed to restart the SSH service.</p><pre><code class="shell">$ service sshd restart</code></pre><h3>Create non-root User</h3><p>Whenever I access a server I like to login as a non-root user that is able to run sudo on the system.</p><pre><code class="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.

$ 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.

$ ssh gemini@davidtsadler.co.uk -i ~/.ssh/davidtsadler.co.uk/id_rsa

I also confirm that I have sudo access.

$ 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.

I created the directory structure with the below command.

$ 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.

$ openssl req -x509 \
+$ usermod -aG sudo gemini</code></pre><p>As the SSH key is already on the server I can copy it to the non-root user account.</p><pre><code class="shell">$ rsync --archive --chown=gemini:gemini ~/.ssh /home/gemini</code></pre><p>On my local system I confirm that I can log in as the new user without a password.</p><pre><code class="shell">$ ssh gemini@davidtsadler.co.uk -i ~/.ssh/davidtsadler.co.uk/id_rsa</code></pre><p>I also confirm that I have sudo access.</p><pre><code class="shell">$ sudo ls</code></pre><h2>Installing a Gemini Site and Server</h2><h3>Directory structure</h3><p>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.</p><ul><li>bin This will contain the Gemini server binary.</li><li>certs TLS certificates for the site are kept here.</li><li>public This will contain the .gmi files of the site.</li><li>scripts Contains scripts used to start the Gemini server.</li></ul><p>I created the directory structure with the below command.</p><pre><code class="shell">$ mkdir -p ~/sites/davidtsadler.co.uk/{bin,certs,public,scripts}</code></pre><h3>Install certificates</h3><p>Sine the Gemini protocol encourages using a self-signed certificate I installed one with the openssl command.</p><pre><code class="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.

$ cat << EOF > ~/sites/davidtsadler.co.uk/public/index.gmi
+    -subj &quot;/CN=davidtsadler.co.uk&quot;</code></pre><h3>Create Some Test Content</h3><p>I created a very simple index.gmi file purely for testing.</p><pre><code class="shell">$ cat &lt;&lt; EOF &gt; ~/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.

$ cd ~/sites/davidtsadler.co.uk/bin
+EOF</code></pre><h3>Install the Gemini Server Binary</h3><p>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.</p><pre><code class="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
 
@@ -39,7 +39,7 @@ $ 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.

$ cat << EOF > ~/sites/davidtsadler.co.uk/scripts/start
+$ chmod u+x agate</code></pre><p>I wrote a very simple bash script to run agate and have it serve the site.</p><pre><code class="shell">$ cat &lt;&lt; EOF &gt; ~/sites/davidtsadler.co.uk/scripts/start
 #!/bin/bash
 
 /home/gemini/sites/davidtsadler.co.uk/bin/agate \
@@ -52,9 +52,9 @@ $ chmod u+x agate

I wrote a very simple bash script to run agate --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.

$ ~/sites/davidtsadler.co.uk/scripts/start
+$ chmod u+x ~/sites/davidtsadler.co.uk/scripts/start</code></pre><h3>Testing the Site</h3><p>At this point I have the Gemini server installed and a site available for testing.</p><p>I first started agate with the bash script.</p><pre><code class="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 Systemd

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.

$ 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]
+[2021-02-05T17:26:56Z INFO  agate] Listening on [[::]:1965, 0.0.0.0:1965]...</code></pre><p>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.</p><h3>Configure Systemd</h3><p>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.</p><pre><code class="shell">$ sudo vim /etc/systemd/system/agate.service</code></pre><p>The unit is very simple and just runs the bash script to start agate once the network is available.</p><pre>[Unit]
 Description=Agate Gemini Server
 After=network.target
 
@@ -65,10 +65,10 @@ 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
+WantedBy=default.target</pre><p>I then started this service and confirmed it was working.</p><pre>$ 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 - My domain registrar of choice.Hetzner - My cloud server provider.Agate - A simple Gemini server.davidtsadler.co.uk - My Gemini site.Gemini - Read More Posts.

I don't have comments as I don't want to manage them. You can however contact me at the below address if you want to.

Email david@davidtsadler.com

License

The contents of this site is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.

Copyright © 2021 David T. Sadler.

Return to Homepage.]]
+Active: active (running)</pre><p>The final step was to have this service start when the system is rebooted.</p><pre>$ sudo systemctl enable agate.service</pre><h2>Conclusion</h2><p>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.</p><h3>Links</h3><a href="https://www.gandi.net/">Gandi.net - My domain registrar of choice.</a><a href="https://hetzner.cloud/?ref=Gf3UFbRaixBK">Hetzner - My cloud server provider.</a><a href="https://github.com/mbrubeck/agate/">Agate - A simple Gemini server.</a><a href="gemini://davidtsadler.co.uk/">davidtsadler.co.uk - My Gemini site.</a><a href="/posts/gemini/">Gemini - Read More Posts.</a><p>I don't have comments as I don't want to manage them. You can however contact me at the below address if you want to.</p><a href="mailto:david@davidtsadler.com">Email david@davidtsadler.com</a><h3>License</h3><a href="https://creativecommons.org/licenses/by-sa/4.0/">The contents of this site is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.</a><p>Copyright © 2021 David T. Sadler.</p><a href="/">Return to Homepage.</a> \ No newline at end of file -- cgit v1.2.3-13-gbd6f