Secure a new Linux server in 10 steps
A new server connected to the internet starts receiving automated login attempts within minutes. Bots constantly scan the whole internet for weak passwords and outdated software. The good news is that a few basic steps stop the vast majority of these attacks. This checklist is what I do on every new Ubuntu or Debian server.
1. Update everything
Many attacks target known vulnerabilities that have already been fixed. Update immediately after creating the server:
sudo apt update && sudo apt upgrade -y
Then enable automatic security updates so you don't fall behind:
sudo apt install unattended-upgrades
sudo dpkg-reconfigure --priority=low unattended-upgrades
2. Create a regular user
Working as root all the time means any mistake or compromised process has full control. Create a normal user with sudo rights:
adduser ali
usermod -aG sudo ali
3. Use SSH keys instead of passwords
Password logins can be guessed; a properly generated SSH key effectively cannot. On your own computer, create a key pair and copy the public key to the server:
ssh-keygen -t ed25519
ssh-copy-id ali@your-server-ip
Log in with the key and make sure it works before the next step.
4. Harden the SSH configuration
Edit /etc/ssh/sshd_config (or add a file in /etc/ssh/sshd_config.d/) and set:
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
Check the configuration and restart SSH:
sudo sshd -t && sudo systemctl restart ssh
Keep your current session open and test logging in from a second terminal before closing it. If something is wrong, you still have a way in to fix it. Most providers also offer a web console as an emergency backup.
5. Turn on a firewall
Only the ports you actually use should be reachable. UFW makes this simple:
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verbose
Always allow SSH before enabling the firewall, or you'll lock yourself out. Add other ports only when a service needs them.
6. Block repeated attackers with Fail2ban
Fail2ban watches log files and temporarily bans IP addresses that fail to log in repeatedly.
sudo apt install fail2ban
sudo systemctl enable --now fail2ban
sudo fail2ban-client status sshd
The default SSH protection is enabled on most distributions. Fail2ban can also protect web logins and other services with additional "jails".
7. Know what's listening
Every listening service is a potential entry point. Check regularly:
sudo ss -tulpn
If you see something you don't recognize or no longer need, stop and disable it. Services that only need to be reached locally — like a database — should listen on 127.0.0.1, not on all interfaces.
8. Protect web applications
- Use HTTPS everywhere (Let's Encrypt certificates are free).
- Keep admin panels off default paths and ports, and protect them with strong unique passwords and two-factor authentication where available.
- Never leave backup files,
.envfiles or.gitfolders inside a public web directory. - Keep web apps, plugins and their dependencies updated.
9. Back up, and test restoring
Security also means being able to recover. Back up configuration files, databases and website files regularly, to a different location than the server itself. A backup you have never restored is only a hope — test a restore at least once.
10. Keep an eye on logs
sudo journalctl -u ssh --since today
sudo tail -f /var/log/auth.log
last -n 20
You don't need to read logs every day, but checking occasionally shows you what's normal, which makes it much easier to spot something that isn't.
Checklist
System updated and auto-updating · non-root sudo user · SSH keys only, root login disabled · firewall allowing only needed ports · Fail2ban running · no unknown listening services · HTTPS and no secrets in web folders · tested backups. Those steps take under an hour and put your server ahead of the easy targets bots are looking for.