A freshly installed Linux server is ready to run services, but it also presents a wide attack surface. Even a small VPS can become a target for credential stuffing, port scans, and automated brute‑force attacks. Hardening the base system does not require complex tools; a handful of well‑known utilities, properly configured, raise the security bar dramatically. This guide walks through the four core pillars: SSH key authentication, a lock‑down firewall, Fail2Ban for intrusion throttling, and reliable update automation. Follow the steps, test each change, and you will have a solid foundation for any production or home‑lab server.
Replace Password Login with SSH Keys
Public‑key authentication eliminates the need for passwords that can be guessed or leaked. Generate a key pair on your workstation, copy the public key to the server, and disable password authentication in sshd_config.
# Generate a 4096‑bit RSA key (adjust algorithm if you prefer Ed25519)
ssh-keygen -t rsa -b 4096 -C "admin@myserver"
# Copy the public key to the remote host (replace user and host as needed)
ssh-copy-id -i ~/.ssh/id_rsa.pub user@your.server.ip
After the key is in place, edit /etc/ssh/sshd_config:
PubkeyAuthentication yes
PasswordAuthentication no
ChallengeResponseAuthentication no
UsePAM no
Restart the daemon and test a new login before closing the old session:
sudo systemctl restart sshd
ssh user@your.server.ip
If the login works, you can safely lock the account password with passwd -l user. For environments with multiple administrators, consider a shared authorized_keys directory or a separate Git‑managed key store.
Lock Down Network Access with a Minimal Firewall
Even with SSH keys, exposing unnecessary ports invites scanning tools and automated exploits. A host‑based firewall such as ufw (Uncomplicated Firewall) provides a readable rule set and integrates with systemd. Install and enable it, then allow only the services you actually need.
# Install ufw (Debian/Ubuntu) or use the built‑in package on most distros
sudo apt-get install ufw -y
# Default deny inbound, allow all outbound
sudo ufw default deny incoming
sudo ufw default allow outgoing
# Allow SSH from a trusted subnet (replace 203.0.113.0/24 with your network)
sudo ufw allow from 203.0.113.0/24 to any port 22 proto tcp
# If the server hosts a web site, open HTTP/HTTPS
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
# Enable the firewall
sudo ufw enable
Check the rule list with sudo ufw status verbose. For more complex routing or VLAN segregation, see our comparison of OPNsense vs pfSense which shows how a dedicated perimeter firewall can complement host‑level rules.
Throttle Brute‑Force Attempts with Fail2Ban
Fail2Ban monitors log files for repeated authentication failures and temporarily bans the offending IP address. Install the package, copy the default jail configuration, and enable the SSH jail.
# Install Fail2Ban (most distributions)
sudo apt-get install fail2ban -y
# Create a local jail file to avoid overwriting defaults on upgrade
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
# Edit /etc/fail2ban/jail.local and enable the sshd section
[sshd]
enabled = true
port = ssh
logpath = %(sshd_log)s
maxretry = 5
bantime = 3600
findtime = 600
After editing, restart the service:
sudo systemctl restart fail2ban
# Verify the jail is active
sudo fail2ban-client status sshd
You can add custom jails for services like nginx, vsftpd, or any daemon that writes to syslog. Adjust bantime and maxretry to match your risk tolerance.
Automate Security Updates
Keeping the OS and installed packages patched is the last line of defense. On Debian‑based systems the unattended-upgrades package can apply security updates automatically. On Red Hat‑based distributions use dnf-automatic. Both tools allow you to schedule nightly runs and receive email reports.
# Debian/Ubuntu: install the package
sudo apt-get install unattended-upgrades apt-listchanges -y
# Enable automatic installation of security updates
sudo dpkg-reconfigure --priority=low unattended-upgrades
# Optional: edit /etc/apt/apt.conf.d/50unattended-upgrades to fine‑tune
# Example snippet – enable only security repos
Unattended-Upgrade::Allowed-Origins {
"${distro_id}:${distro_codename}-security";
};
# Set a daily reboot if a kernel update occurs (optional)
Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time "02:00";
For Fedora, CentOS Stream, or RHEL, enable the timer:
sudo dnf install dnf-automatic -y
sudo systemctl enable --now dnf-automatic.timer
# Review /etc/dnf/automatic.conf to restrict to security updates only
Regularly audit the update logs (/var/log/unattended-upgrades/unattended-upgrades.log or /var/log/dnf.log) and confirm that critical services restart cleanly after a kernel upgrade. Pair automatic updates with a reliable backup strategy such as the 3‑2‑1 backup rule to protect against accidental breakage.
Want to go deeper?
Need to audit your server setup? Our Small Business IT Audit Checklist covers hardware, software, security posture, backups, and network documentation. $9, instant download.
Originally published at lorikeetsmart.com













