Skip to main content

Linux Security Hardening

Security is not an afterthought — it is the first thing an attacker tests. A fresh server on the public internet will receive SSH brute-force attempts within minutes of coming online. The steps in this chapter are the baseline that every production server should have before running any workloads. Think of it as locking the doors and windows before you move your furniture in.

1. SSH Hardening

SSH is the front door to your server. It is also the most common attack vector. Every step here reduces your attack surface.

Disable Root Login

Never allow direct root login over SSH. If an attacker guesses (or brute-forces) the root password, they have full control immediately. Instead, log in as a regular user and escalate with sudo when needed — this way, the attacker needs both a valid username and either a key or password. Edit /etc/ssh/sshd_config:

Use SSH Keys (Disable Passwords)

Passwords can be brute-forced given enough time. SSH keys are cryptographic — a 256-bit ed25519 key would take longer than the age of the universe to crack. Switching from passwords to keys is the single highest-impact security change you can make.
Critical: Always test SSH key login in a separate terminal before disabling passwords. If your key is not set up correctly and you disable password auth, you will lock yourself out of the server permanently (unless you have console access through your cloud provider).

Change the Default SSH Port (Optional)

Moving SSH off port 22 does not stop determined attackers, but it eliminates 99% of automated bot traffic from your logs and reduces noise dramatically.

2. Firewall (UFW)

Uncomplicated Firewall (UFW) is the friendly interface to Linux’s iptables subsystem. The principle is simple: deny everything by default, then explicitly allow only what you need. Like a building with all doors locked where you hand out keys only for specific rooms.

3. Fail2Ban

Fail2Ban watches log files for signs of malicious behavior (repeated failed logins, probing requests) and automatically bans the offending IP addresses using firewall rules. It is your automated security guard — it spots troublemakers and escorts them out.
Configure /etc/fail2ban/jail.local:

4. System Updates

Unpatched software is one of the most common entry points for attackers. Every security advisory that gets published is also a roadmap for attackers to exploit unpatched systems.

5. File Permissions and Ownership

The principle of least privilege applies to files too — every file should be readable, writable, and executable by only the users and services that need it.

6. Audit and Monitor

Security is not a one-time setup — it requires ongoing monitoring. Think of the hardening steps above as locking your doors. Auditing and monitoring is the security camera system. Locks stop casual intruders; cameras catch the ones who find another way in.

Setting Up Basic Intrusion Detection

For production servers, go beyond manual checks. These lightweight tools run continuously and alert you to changes.
Production gotcha: Most compromises are not detected by the victim — they are reported by a third party (a customer, a monitoring service, law enforcement). The median time to detect a breach is measured in months, not minutes. Automated monitoring with alerts (not just logs you never read) is what shrinks that window.

Quick Hardening Checklist

Use this as a checklist when provisioning any new server. Order matters — do not enable the firewall before allowing SSH, and do not disable password auth before confirming key auth works.
  1. Create a non-root user with sudo access (adduser deploy && usermod -aG sudo deploy)
  2. Set up SSH key authentication (generate locally, copy with ssh-copy-id)
  3. Test key login in a separate terminal before proceeding — if this fails and you disable passwords, you are locked out
  4. Disable SSH password authentication and root login in /etc/ssh/sshd_config
  5. Restart SSH (systemctl restart ssh) and test again in a new terminal
  6. Configure UFW: allow SSH first (ufw allow 22/tcp), then enable (ufw enable)
  7. Install and configure Fail2Ban for SSH brute-force protection
  8. Enable automatic security updates (apt install unattended-upgrades)
  9. Set proper permissions on sensitive files (SSH keys, app secrets, configs)
  10. Remove unnecessary services and packages (apt autoremove, disable unused daemons)
  11. Set up log monitoring and basic intrusion detection (AIDE or similar)
  12. Schedule regular audits: check SUID files, open ports, and sudo users monthly

Key Takeaways

  • Never use passwords for SSH; use key-based authentication exclusively
  • Always run a firewall with a deny-by-default policy
  • Disable direct root login over SSH
  • Use Fail2Ban to automatically block brute-force attempts
  • Keep your system updated — enable unattended upgrades for security patches
  • Apply the principle of least privilege to file permissions and sudo access
  • Monitor authentication logs regularly for suspicious activity

Next: Docker Crash Course →