Published on
Why this is really necessary
If you look at the log file /var/log/auth.log after a new server has been provisioned, you will usually see hundreds of failed login attempts after just a few hours. These are not targeted attacks on you, but bots that continuously sweep the entire IPv4 address space and try default credentials: root with 123456, admin with admin and so on.
As long as your root password is long and random, this leads nowhere. Still, a password can be guessed, typed off, visible in a screenshot or leaked from another service. An SSH key cannot. The following four steps build on each other.
Step 1: Generate an SSH key pair
An SSH key pair consists of a private key that never leaves your computer and a public key that you store on the server. You generate it on your local computer, not on the server:
ssh-keygen -t ed25519 -C "my-laptop"
You can confirm the suggested storage path with Enter. When asked for a passphrase, you should set one - it protects the private key in case your computer ever falls into the wrong hands. So that you do not have to type it on every connection, your operating system's SSH agent caches it.
Why ed25519 and not RSA? Ed25519 keys are shorter, faster and, as things stand today, at least as secure as RSA with 4096 bits. Only on very old systems that do not support Ed25519 yet is ssh-keygen -t rsa -b 4096 the fallback.
Then transfer the public key to the server:
ssh-copy-id yourname@YOUR-SERVER-IP
The command asks for the password once and then stores the key in ~/.ssh/authorized_keys. If ssh-copy-id is not available - on Windows, for example - you can do it by hand:
type $env:USERPROFILE\.ssh\id_ed25519.pub | ssh yourname@YOUR-SERVER-IP "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
Test now before you continue. Open a new terminal and connect. If you get in without a password prompt, the key works.
Step 2: Disable password login and root login
Only once the key demonstrably works do you switch off password login. Make sure to keep your existing SSH session open - if something goes wrong, you can use it to repair things.
Open the configuration file:
sudo nano /etc/ssh/sshd_config
Find and set the following values. If they are preceded by a hash sign, remove it:
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
KbdInteractiveAuthentication no
Save with Ctrl+O, close with Ctrl+X. Then check the configuration for syntax errors and restart the service:
sudo sshd -t
sudo systemctl restart ssh
The command sshd -t is the most important line in this whole guide: it reports errors before the restart locks you out. If it prints nothing, everything is fine.
Now open a second terminal and connect again. If that works, the change was successful. If it does not, undo the change in the first session that is still open.
Should both fail after all: via the VNC console in the web interface, you can reach the system independently of SSH and correct /etc/ssh/sshd_config there.
Step 3: Fail2ban against constant attacks
With password login disabled, brute-force attempts are hopeless, but they still clutter log files and use CPU. Fail2ban reads the logs and automatically bans IP addresses that fail too often.
sudo apt install fail2ban -y
The supplied configuration is overwritten on updates, so create your own file:
sudo nano /etc/fail2ban/jail.local
Content:
[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5
[sshd]
enabled = true
This means: anyone who fails five times within ten minutes is banned for one hour. Enable and check:
sudo systemctl enable --now fail2ban
sudo fail2ban-client status sshd
The last line shows you how many addresses are currently banned. After a few days of uptime, that is often a surprisingly long list.
Step 4: Restrict the firewall to what is needed
The firewall is the second line of defence: even if a service accidentally listens on all interfaces, nobody from outside can reach it. On Debian and Ubuntu, ufw is the simplest tool.
sudo apt install ufw -y
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH
sudo ufw enable
The SSH rule must be set before enabling the firewall, otherwise it cuts your own connection the moment it starts. You then open further services as needed:
sudo ufw allow 80/tcp # HTTP
sudo ufw allow 443/tcp # HTTPS
sudo ufw allow 9987/udp # TeamSpeak 3
sudo ufw status numbered
With sudo ufw delete NUMBER, you remove a rule again that you found in the numbered overview.
Optional: move the SSH port
A frequent recommendation is to move SSH from port 22 to a different port. To be honest, this is not a real security measure - a targeted attacker finds the port with a scan in seconds. What it reliably does achieve: the mass of automated scans that bluntly sweep port 22 passes you by completely. Your log files become much easier to read.
If you want to do this, change the line Port 22 in /etc/ssh/sshd_config to a value above 1024 and open it in the firewall beforehand:
sudo ufw allow 2222/tcp
sudo sshd -t && sudo systemctl restart ssh
From then on, you connect with ssh -p 2222 yourname@YOUR-SERVER-IP. Do not forget to remove the old rule for port 22 afterwards.
Quick checklist
- Key pair generated, public key installed and login tested
PasswordAuthentication noandPermitRootLogin nosetsshd -trun before every restart- Fail2ban active, status checked
- Firewall active, only required ports open
- Private key backed up - if it is lost, the only way into the system is the VNC console
Not set up yet? The first steps on your VPS cover updates, your own user and the basic firewall. Once SSH is secured, it is time for backups and, depending on your plans, a web server or Docker.
Frequently asked questions
VPS with full root access
Root access means you decide on the security configuration yourself - from SSH hardening to the firewall. All plans with NVMe SSD, unmetered traffic and DDoS protection up to 250 Gbit/s, prepaid without a contract.
View VPS plans & pricesRent a VPS
from €2.95 / month
Prepaid without a contract, full root access, DDoS protection up to 250 Gbit/s.
View plans & pricesRead more
- VPS - plans & prices
- First steps on your VPS
- Set up a web server
- Set up backups
- Install Docker
- LXC or KVM?
Discover more