This was inspired by a Reddit Post, in this post the author asks for advice on self-hosting things. I weighed in with some points on locking down your self-hosted services.
It's fun, it helps give you real world experience. On top of this, if you care for privacy and security, it helps you lock the environment down so you feel more comfortable. Remember, nothing is bulletproof. If a determined threat actor wants in, it only takes one tiny mistake to open the flood gates.
Welcome to the exciting world of self-hosting! It's a great hobby. System administration rocks.
Let's assume you'll be using a flavour of linux, such as Debian or Ubuntu. First, I always pick the most recent LTS, in the case of Ubuntu, I'll prefer 18.04 LTS. I use DigitalOcean (ref link) for hosting most personal things, including this very own blog along with my wife's. They've done a great job at making both developers and new-comers life super simple.
Go ahead and make an account at DigitalOcean, get some free credit, spin up a droplet for yourself with Ubuntu 18.04. You'll need an SSH key, you can generate one on linux or mac by doing the following:
ssh-keygen -b 4096
To retrieve the public key, just run this command and then paste it into the ssh key slot on DigitalOcean (like shown below):
Then, finalize and create your droplet! Within about 1 minute your droplet is online and ready to use.
You'll need to use ssh, just type in your terminal (linux/mac) or Putty/other-ssh client on Windows:
Replace $IP_ADDRESS with your droplets IP address. You're in!
Immediately, the first things you'll want to do is start locking down your droplet. Start by running a simple apt update and installing fail2ban:
apt-get update && apt-get install fail2ban -y
This will update your packet repository, install and enable fail2ban. Fail2ban works wonders for SSH and helps ban brute-force attackers. But, we really shouldn't keep our ssh port 22 as the default.
It is always advisable to either (a) change the SSH port, (b) limit access to SSH via firewall, or, (c) do both. I always pick option C.
Let's change the ssh port! I use vim for this (yes, I know) - but nano is a good alternative. If you don't have nano, run apt-get install nano and you'll have it.
In the first few lines you should see "Port 22" - go ahead and change this to any memorable port you know, pick something that isn't simple to guess (eg. 2222). I'll use in this example port 9132.
Go ahead and save this file, then restart ssh - you may have to reconnect once this is done.
service ssh restart
To reconnect with the new port, run:
ssh root@$IP_ADDRESS -p $PORT
Now this is getting more locked down, but let's imagine we have an apache2 server running, and we use Cloudflare. We want to make sure that only Cloudflare and our IP can access the web server directly, let's introduce a Cloud Firewall from DigitalOcean. Go ahead and create one, tag it appropriately.
Here is what your basic configuration should look like (IP list for cloudflare is available here: https://www.cloudflare.com/ips/
As you can see, HTTP is open to Cloudflare only. Perfect. Now if you try to access it you should get rejected by the firewall (unless you whitelisted yourself). I opened 10/8 for this demonstration so if you have multiple droplets they can communicate properly with each-other (I'd suggest just whitelisting IPs manually, not entire subnets, however). YMMV.
DigitalOcean charges peanuts to do them automatically, this blog costs me $1/mo to backup. I'd recommend you always keep a personal backup as well, just in case.
If you have any questions, feel free to give me a shout!