Securing Linux Servers: Essential Hardening Steps for Production
A freshly installed Linux server is open to the internet within minutes, and automated scanners will start probing it almost immediately. Hardening is not a one-time project but a checklist you apply to every server before it handles real traffic. This guide covers the steps that remove the most risk for the least effort on Ubuntu or Debian.
1. Use SSH keys and disable root login
Password logins are the most common way servers get compromised. Create a normal user, add your public key, then edit /etc/ssh/sshd_config:
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
MaxAuthTries 3
Test a second SSH session before closing your current one, then reload with sudo systemctl reload ssh. If you made a mistake, your existing session is your way back in.
2. Turn on a default-deny firewall
Only expose the ports you actually serve. With UFW, deny everything inbound and allow only what you need:
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp
sudo ufw allow 443/tcp
sudo ufw enable
Allow SSH before enabling the firewall, or you will lock yourself out. If your office has a fixed IP, restrict port 22 to that address.
3. Keep the system patched automatically
Most real-world breaches use vulnerabilities that already have a fix. Enable unattended security updates with sudo apt install unattended-upgrades and sudo dpkg-reconfigure unattended-upgrades. Reboot on a schedule for kernel updates.
4. Block brute-force attempts
Fail2ban watches logs and temporarily bans IPs with repeated failed logins. Install it with sudo apt install fail2ban, copy jail.conf to jail.local, and enable the sshd jail. Even with key-only SSH, this cuts log noise and load.
5. Apply least privilege
Run each service under its own unprivileged user. Grant sudo only to people who need it, and remove unused packages and services. Check what is listening with ss -tulpn; anything you do not recognize should be investigated or removed.
6. Log, monitor, and back up
Ship logs to a separate system so an attacker cannot erase them. Enable auditd for sensitive files, and alert on new sudo users or changes to /etc/ssh. Finally, keep encrypted backups off the server and test a restore regularly; a backup you have never restored is only a hope.
Summary
Key-only SSH, a default-deny firewall, automatic patching, brute-force protection, least privilege, and off-box logs and backups together stop the large majority of opportunistic attacks. Run through this list on every new server, and automate it with Ansible or cloud-init so it is applied consistently.