Server Hardening
This part is optional, but recommended. Even if we won’t be poking holes through our routers, it’s still a good idea to secure your mini PC or VM. At the end of the day, running a few commands now can save you peace of mind later.
Adding a non-root user (if not already using one)
To add a new non-root user, run the following command as root:
adduser <user>
To give the new user rights to use sudo, run the following command as root:
usermod --append --groups sudo <user> // give that new user rights to use sudo
If you’re using a VM, the platform most likely added the SSH public key to the root user’s .ssh
folder. We also need to add it to the new user’s .ssh
folder or else we can’t log in as that new user. We can simply create the .ssh
folder, copy the authorized_keys
file of root to this new folder, and set the proper permissions and owner.
mkdir -p /home/<user>/.ssh && chmod 700 /home/<user>/.ssh
sudo chmod 600 /home/<user>/.ssh/authorized_keys
sudo chown -R <user>:<user> /home/<user>/.ssh
Firewall
We’ll use Uncomplicated Firewall (UFW) for our firewall. It’s not an advanced, feature-rich solution, but a mere wrapper around iptables that just filter traffic based on some rules we set.
Install the required packages:
sudo apt-get install iptables ipset ufw cron curl wget rsyslog -y
Enable the firewall:
sudo ufw enable
Block known bad IPs using this script from arter97:
sudo wget https://gist.githubusercontent.com/arter97/2b71e193700ab002c75d1e5a0e7da6dc/raw/firewall.sh -O /opt/firewall.sh
sudo chmod 755 /opt/firewall.sh
sudo /opt/firewall.sh
Verify that it’s working by checking the Kernel message buffer:
sudo dmesg
(Optional) Add a cronjob to run the script every day at 5AM. Run sudo crontab -e
and paste the following:
@reboot /opt/firewall.sh
0 5 * * * /opt/firewall.sh
And because port-forwarding in Docker “pokes holes” through UFW, we need to make it so that UFW still has control. To do this, modify the UFW configuration file /etc/ufw/after.rules
and add the following configuration1 at the end of the file:
# BEGIN UFW AND DOCKER
*filter
:ufw-user-forward - [0:0]
:ufw-docker-logging-deny - [0:0]
:DOCKER-USER - [0:0]
-A DOCKER-USER -j ufw-user-forward
-A DOCKER-USER -j RETURN -s 10.0.0.0/8
-A DOCKER-USER -j RETURN -s 172.16.0.0/12
-A DOCKER-USER -j RETURN -s 192.168.0.0/16
-A DOCKER-USER -p udp -m udp --sport 53 --dport 1024:65535 -j RETURN
-A DOCKER-USER -j ufw-docker-logging-deny -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 192.168.0.0/16
-A DOCKER-USER -j ufw-docker-logging-deny -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 10.0.0.0/8
-A DOCKER-USER -j ufw-docker-logging-deny -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 172.16.0.0/12
-A DOCKER-USER -j ufw-docker-logging-deny -p udp -m udp --dport 0:32767 -d 192.168.0.0/16
-A DOCKER-USER -j ufw-docker-logging-deny -p udp -m udp --dport 0:32767 -d 10.0.0.0/8
-A DOCKER-USER -j ufw-docker-logging-deny -p udp -m udp --dport 0:32767 -d 172.16.0.0/12
-A DOCKER-USER -j RETURN
-A ufw-docker-logging-deny -m limit --limit 3/min --limit-burst 10 -j LOG --log-prefix "[UFW DOCKER BLOCK] "
-A ufw-docker-logging-deny -j DROP
COMMIT
# END UFW AND DOCKER
Fail2Ban
Fail2Ban blocks hosts that make too many failed login attempts to your server.
Install the required packages:
sudo apt-get install fail2ban -y
Create a /etc/fail2ban/jail.local
config file and paste the following:
[DEFAULT]
bantime = 1d
findtime = 15m
maxretry = 3
backend = auto
[sshd]
port = 22
Restart the fail2ban daemon:
sudo systemctl restart fail2ban
SSH
Assuming you already have the SSH daemon running on your server, you can paste the following at the end of the /etc/ssh/sshd_config
file:
Protocol 2
MaxAuthTries 3
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
AuthenticationMethods publickey
KbdInteractiveAuthentication no
X11Forwarding no
For additional security measures, you may also refer to Positron Security’s SSH hardening guides2 to further harden your SSH configuration.