TomCon.net Infrastructure

tomcon.net is my first ever website. I have never self-hosted a external service like this before. Getting to this point where text is rendering on your screen took a decent amount of learning and trial+error. Before this I was vaugely familiar with some computer networking essentials like internal/external ips and forwarding port numbers. I have been using linux mint as a daily driver for a few years so I know the basics of UNIX file structure and how to work a terminal.

This site is hosted on a thinkpad t440s running linux mint 22.1 cinnamon. The laptop was a spare I had lying around. I finally put it to good use.

General steps to get to this point:

Buy A Domain Name

I think you should start with buying a domain name as your first step. Its useful to know going into this what your domain name is going to be. Theres many providers that are suggested. I choose epik.com as a domain name provider but you can go with cloudflare, namecheap, and many others.

I now pay 15$/yr for the privlege of renting a human readable name certified by a domain authority that gets tie to my networks external IP address. Its unfortunate I cant self-host the domain registry process too. For now im stuck with renting a name from an authority and using their web services to configure things. Its a necessary evil you gotta do to have a website.

Note that other network protocols for sharing information like I2P and TOR do away with the need for a domain name system I believe.

Tie domain name with server external IP through providers web interface

when you find out your external ip with whatsmyip.com, go into your domain name providers web interface and find 'DNS Host Records', Here make sure your domain and subdomains (with the A, AAAA records) point to your servers external IP. Do the same process for all subdomains you want to create, they all take the exact same pointed ip number configuration.

Chapter 0: Foundation - OS install and Web Server Setup

This is the core step of setting up my website. A good operating system like Linux Mint provides an out-of-the-box beginner friendly ecosystem thats easy to install, bulletproof stability, and good community support with over a decade of fourm activity and a very active IRC to fall back on. Note that other operating systems are purpose built as hardened and secured headless server OS. At some point I may feel the need to switch to one.

Setup Linux Mint

install apache2

Apache is a simple web page server. A client request connection to apache, then apache sends html page information to a recieving client on an open port.

	sudo lsof -i :80

Add apache2 to systemctl and enable it

To use a terminal to connect to the webpage and pull the index HTML file:

 curl -I http://localhost

Add your domain name to the hosts file


This is so you can use your name in a local network clients web browser without SSL errors:

 sudo nano /etc/hosts

Troubleshooting local clients connecting to apache

Another potential option especially if troubleshooting and the domain name isn't working for whatever reason is to use direct local ip and port numbers. enter into your browser `http:10.0.0.xx` `http:10.0.0.xx:8080`, or http:localhost:8080 into the address bar. You can try undoing port change from 8080 back to 80 and connecting without defining port after restart (your web browser automatically request http on 80 and https on 443). You can also try allowing 8080 through the firewall if its already set up. The goal is just to see if apache is running/serving the default page and if you can connect locally.

Apache Configuration

Located in '/etc/apache2/ports.conf'

# If you just change the port or add more ports here, you will likely also
# have to change the VirtualHost statement in
# /etc/apache2/sites-enabled/000-default.conf

Listen 8080

<IfModule ssl_module>
#	Listen 443
</IfModule>

<IfModule mod_gnutls.c>
#	Listen 443
</IfModule>

Moving Forward

Make sure apache is running and you can connect locally. If so, its time to move on to exposing the service to external client connections. Its heavily recommended that you follow the next steps for security hardening+reverse proxy with caddy. It is entirely possible for you to just serve regular unencrypted http at this point though. Port forward 80/TCP of your servers local ip in the gateway/router settings and point the domain name at your networks external IP address. Adjust security headers through apache. External clients should be able to recieve html pages using your domain name through http but they'll recieve warnings every time they connect and your SEO will hurt. Its better for everyone involved to set up a way to handle SSL/TLS certificates.

Chapter 2: Security Part 1 - Setup Caddy for HTTPS and Reverse Proxy for local network

caddy serves two important roles along with apache.

A reverse proxy is the solution to two problems at once. It handles pairing a external sub-domain with a specific local ip. And if some of these external services send out web content as http but have no way of issuing ssl certificates, its not a problem. The reverse proxy handles that part of the connection in the local services stead. The reverse proxy part is a little complicated to understand, but it becomes clear what it does the more you think about it (which is true of most things I guess). Its an important part of modern internet infastructure that helps give your network a boost in security and configurability.

I choose caddy as a reverse proxy and https encryption certificate server instead of nginx+certbot because I was told it was easier to configure. Caddy has automatic https already setup. The caddyfile config promised to not being a nightmare-slog to read through or configure from scratch. Im not used to this kind of thing so I went with the option that promised easiest implementation with the essential features I really needed.

Nginx has some things out of the box caddy doesn't but by the time I get to needing them ill probably be comfortable enough to wrangle with configs without getting stressed out. At the end of the day I wanted to get something working and start making content, not wrangle with grainular infrastructure configs for hours just for something to break.

Installing Caddy

This is the real caddyfile I am using for my site tomcon.net. It took a bit of figuring out on my part how to properly format everything, the caddy docs help but not enough. I hope sharing this serves you well in your own site building journey.

Where Caddy Stores TLS/SSL Certificates

Caddy stores a cert and key pair for each registered domain+subdomain here:

/home/caddy/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory

Chapter 3: Port Forwarding

Once you have caddy and apache2 setup, go into your router and find the port forwarding configuration settings. Make note of your caddy+apache servers local IP address, and forward the ports 80/TCP and 443/TCP. Save. These are the standard ports for http and https which web browsers quietly knock on to connect to. Youve just exposed them for external connection. Instead of directly connecting to apache, caddy claims these ports in apaches stead so all external connections go through caddy first. Apache sends html to caddy on port 8080, caddy adds certificates and passes the data to the external client. Neat!

Chapter 4: Security Part 2 - Hardening Website Headers

Once your site has https and is externally connectable, Go to securityheaders.com and mozilla observatory to get your site tested for header hardening. You want as high a score as you can manage. The headers included in the caddyfile I provided are enough to get tomcon.net at a near-perfect score.

To securityheaders.com

To Mozilla Observatory

Chapter 5 - Security Part 3: Firmware Hardening

Configure firewall

allow ports in UFW

sudo ufw allow http
sudo ufw allow https
sudo ufw allow 80
sudo ufw allow 443
	sudo ufw reload
	sudo ufw enable
	sudo ufw reload
	sudo systemctl enable ufw

Install fail2ban & Enable in systemctl

Fail2ban helps deal with potential issues related to brute force attacks. It monitors connections and if one client tries to connect too many times too quickly it triggers a temp ban or 'jails' the IP for a time.

APPENDIX: Related Bash History of setting up tomcon.net

This is the entire related bash history containing all the terminal commands I put in up to the point the site came online. This doesn't reflect everything done as some actions were through the GUI like editing configs. Nonetheless, it should help give you an idea of the simple workflow and testing it took to set up tomcon.net from a base linux mint cinnamon install.

    1  ifconfig
    2  sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
    3  curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
    4  curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
    5  sudo apt update
    6  sudo apt install caddy
    7  sudo nano /etc/caddy/Caddyfile
    8  sudo systemctl reload caddy
    9  sudo systemctl enable caddy
   10  sudo systemctl status caddy
   11  sudo systemctl reload caddy
   12  sudo systemctl status caddy
   13  sudo ufw allow http
   14  sudo ufw allow https
   15  sudo ufw allow 80
   16  sudo ufw allow 443
   17  sudo ufw reload
   18  sudo ufw enable
   19  sudo ufw reload
   20  sudo caddy validate --config /etc/caddy/Caddyfile
   21  sudo systemctl reload caddy
   22  sudo systemctl status caddy
   23  sudo caddy validate --config /etc/caddy/Caddyfile
   24  caddy fmt --overwrite
   25  caddy fmt --overwrite /etc/caddy/caddyfile
   26  caddy fmt --overwrite etc/caddy/caddyfile
   27  caddy fmt --overwrite etc/caddy/Caddyfile
   28  caddy fmt --overwrite /etc/caddy/Caddyfile
   29  sudo systemctl reload caddy
   30  sudo caddy validate --config /etc/caddy/Caddyfile
   31  curl -I http://localhost
   32  sudo systemctl status caddy
   33  sudo systemctl reload caddy
   34  sudo systemctl status caddy
   35  sudo systemctl reload caddy
   36  sudo systemctl status caddy
   37  sudo systemctl reload caddy
   38  nano /etc/host
   39  sudo nano /etc/host
   40  sudo nano /etc/hosts
   41  sudo systemctl reload caddy
   42  sudo systemctl status caddy
   43  sudo systemctl reload caddy
   44  sudo systemctl status caddy
   45  sudo systemctl reload caddy
   46  sudo systemctl status caddy
   47  sudo apt install apache2
   48  sudo systemctl enable apache2
   49  sudo systemctl status apache2
   50  sudo systemctl enable apache2
   51  sudo systemctl start apache2
   52  sudo systemctl status apache2
   53  systemctl reload caddy
   54  sudosystemctl reload caddy
   55  sudo systemctl reload caddy
   56  sudo systemctl status caddy
   57  sudo lsof -i :80
   58  sudo nano /etc/hosts
   59  sudo systemctl status caddy
   60  ifconfig
   61  sudo systemctl reload caddy
   62  sudo systemctl status caddy
   63  sudo ufw allow 8080
   64  sudo systemctl reload caddy
   65  sudo systemctl status caddy
   66  sudo lsof -i :80
   67  sudo lsof -i :8080
   68  sudo systemctl status caddy
   69  sudo journalctl -u caddy --since 10 minutes ago
   70  sudo journalctl -u caddy --since "10 minutes ago"
   71  sudo journalctl -u caddy
   72  sudo systemctl reload apache2
   73  sudo a2enmod headers
   74  systemctl restart apache2
   75  sudo systemctl  apache2
   76  sudo a2enmod headers
   77  sudo systemctl restart apache2
   78  sudo systemctl reload apache2
   79  sudo systemctl restart apache2
   80  sudo systemctl restart caddy
   81  sudo systemctl reload caddy
   82  sudo systemctl restart caddy
   83  sudo systemctl reload caddy
   84  sudo systemctl restart caddy
   85  sudo systemctl reload caddy
   86  sudo systemctl status caddy
   87  sudo systemctl reload caddy
   88  sudo systemctl status caddy
   89  sudo systemctl restart caddy
   90  sudo systemctl status caddy
   91  sudo systemctl reload caddy
   92  sudo caddy validate --config /etc/caddy/Caddyfile
   93  caddy fmt --overwrite /etc/caddy/caddyfile
   94  caddy fmt --overwrite /etc/caddy/Caddyfile
   95  sudo caddy validate --config /etc/caddy/Caddyfile
   96  sudo systemctl reload caddy
   97  sudo systemctl restart caddy
   98  sudo systemctl reload caddy
   99  sudo systemctl status caddy
  100  sudo systemctl reload caddy
  101  sudo systemctl restart caddy
  102  sudo systemctl status caddy
  103  sudo journalctl -u caddy --since 10 minutes ago
  104  sudo journalctl -u caddy --since "10 minutes ago"
  105  sudo apt install fail2ban
  106  sudo systemctl restart caddy
  107  sudo systemctl reload caddy
  108  sudo journalctl -u caddy --since "5 minutes ago"
  109  sudo systemctl restart caddy
  110  sudo systemctl reload caddy
  111  sudo journalctl -u caddy --since "5 minutes ago"
  112  caddy fmt --overwrite /etc/caddy/Caddyfile
  113  sudo systemctl restart caddy
  114  sudo systemctl reload caddy
  115  sudo caddy validate --config /etc/caddy/Caddyfile
  116  cat ~/.bash_history
  117  sudo nano /etc/hosts
  118  sudo systemctl enable fail2ban
  119  systemctl start fail2ban
  120  sudo systemctl status caddy
  121  sudo journalctl caddy
  122  sudo journalctl -u caddy | grep -i acme
  123  sudo journalctl -u caddy
  124  systemctl status ufe
  125  systemctl status ufw
  126  sudo ufw enable

Gemini Infrastructure

The gemini protocol aspect of this site is powered by a simple Agate server written in Rust. Gemini is a small-net protocol designed for simplicity in implimentation and text formatting. It may be accessed using native browser software or web based proxies.

Agate Install

Visit agates git and download the precompiled binary.
put the program into /bin
open a new bash instance, run the following

sudo agate --hostname your-domainname.com --addr 10.0.0.xx:1965 --content /home/user/gemini/gemtext

If all goes well the agate server should start up fine.