Skip to content
Back to Blog
Security11 min read

Server Security Hardening: 8 Configs to Lock Down Linux

Lock down your Linux VPS with these exact firewall rules, SSH tweaks, and permission changes that stop most automated attacks cold.

Written by Abdul AbrorTechnical Hosting Support Engineer
Server Security Hardening: 8 Configs to Lock Down Linux
On this page

A fresh Linux VPS is open by design. That's a problem. Within minutes of bringing up a server with a public IP, the SSH port starts seeing login attempts—hundreds per day if you check auth.log. Most are bots hunting for default credentials or weak passwords.

Server security hardening means closing those gaps before someone walks through them. The checklist below covers the eight configurations I apply to every production server: firewall defaults, SSH lockdown, service reduction, user permissions, file integrity monitoring, kernel parameters, log monitoring, and automatic updates. Each one blocks a different class of attack. Together they turn a soft target into something that takes real effort to crack.

1. Set up a default-deny firewall

Start with iptables or ufw—whichever you're comfortable with. The principle is the same: block everything by default, then open only the ports your services actually need.

For a typical web server running SSH, HTTP, and HTTPS, the ruleset is short:

# Flush existing rules
iptables -F
iptables -X

# Default policies: drop everything
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

# Allow loopback
iptables -A INPUT -i lo -j ACCEPT

# Allow established connections
iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

# Allow SSH (port 22 or custom)
iptables -A INPUT -p tcp --dport 22 -j ACCEPT

# Allow HTTP and HTTPS
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT

# Save rules
iptables-save > /etc/iptables/rules.v4

If you prefer ufw, the same logic applies:

ufw default deny incoming
ufw default allow outgoing
ufw allow 22/tcp
ufw allow 80/tcp
ufw allow 443/tcp
ufw enable

Either way, verify the rules took effect by checking iptables -L -v or ufw status. A closed port returns nothing on an external port scan. If you accidentally lock yourself out via SSH, most hosting control panels offer a console or rescue mode to fix it.

2. Harden SSH configuration

SSH is the most attacked service on any VPS. The sshd_config file in /etc/ssh/ controls every behavior. Make these changes:

# Disable root login
PermitRootLogin no

# Disable password authentication (use keys only)
PasswordAuthentication no
ChallengeResponseAuthentication no

# Limit authentication attempts
MaxAuthTries 3

# Disable empty passwords
PermitEmptyPasswords no

# Use protocol 2 only (protocol 1 is obsolete)
Protocol 2

# Reduce login grace time
LoginGraceTime 30

# Restrict to specific users
AllowUsers youruser

# Change default port (optional but helps)
Port 2849

After editing, test the config with sshd -t to catch syntax errors, then reload: systemctl reload sshd. Before you close your current session, open a second terminal and verify you can still connect. If something broke, the first session is your escape hatch.

Changing the SSH port won't stop a determined attacker, but it does eliminate 99% of the automated noise in your logs. Pick a high port outside common ranges and update your firewall rules to match.

3. Create a non-root user with sudo

Never run daily tasks as root. Create a regular user, add them to the sudo group, and use that account for everything:

adduser youruser
usermod -aG sudo youruser

On CentOS or RHEL-based systems, replace sudo with wheel. Copy your SSH public key into the new user's authorized_keys:

mkdir -p /home/youruser/.ssh
cp /root/.ssh/authorized_keys /home/youruser/.ssh/
chown -R youruser:youruser /home/youruser/.ssh
chmod 700 /home/youruser/.ssh
chmod 600 /home/youruser/.ssh/authorized_keys

Once you've verified the new user can SSH in and run sudo commands, disable root login in sshd_config (covered above). If something goes wrong with sudo, the hosting control panel console usually gives you root access to fix it.

4. Disable unnecessary services

Every running service is another potential entry point. List active services with systemctl list-units --type=service --state=running and disable anything you don't recognize or need.

Common candidates for removal:

systemctl stop avahi-daemon
systemctl disable avahi-daemon

systemctl stop cups
systemctl disable cups

systemctl stop bluetooth
systemctl disable bluetooth

On a headless VPS, you almost never need Avahi (mDNS), CUPS (printing), or Bluetooth. Check listening network ports with ss -tuln or netstat -tuln. Anything listening on 0.0.0.0 or :: that you don't recognize deserves investigation.

5. Set correct file and directory permissions

Wrong permissions let local attackers escalate privileges. A few key files must stay locked down:

# SSH directory and keys
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chmod 600 ~/.ssh/id_rsa
chmod 644 ~/.ssh/id_rsa.pub

# Sensitive system files
chmod 644 /etc/passwd
chmod 640 /etc/shadow
chown root:shadow /etc/shadow

# Web root (if applicable)
chown -R www-data:www-data /var/www
find /var/www -type d -exec chmod 755 {} \;
find /var/www -type f -exec chmod 644 {} \;

Never set 777 on anything in production. If a web app complains about permission errors, fix the ownership or group instead of opening the permissions wide. Check for world-writable files across the system with find / -type f -perm -002 -ls—there shouldn't be many.

6. Install and configure fail2ban

Fail2ban watches log files for repeated failed login attempts and temporarily bans the offending IP. On Ubuntu or Debian:

apt update
apt install fail2ban

Create a local config file at /etc/fail2ban/jail.local:

[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 5

[sshd]
enabled = true
port = 22
logpath = /var/log/auth.log

Adjust bantime (seconds an IP stays blocked), findtime (window to count failures), and maxretry (attempts before ban) to match your tolerance. Restart fail2ban with systemctl restart fail2ban and check active jails with fail2ban-client status. Banned IPs show up in fail2ban-client status sshd.

In support tickets I handled, fail2ban alone cut SSH attack noise by over 90%. You still see attempts, but the same bot can't hammer you for hours straight.

7. Harden kernel parameters with sysctl

The Linux kernel exposes dozens of tunable parameters through /etc/sysctl.conf. A few settings make it harder to exploit network-level attacks:

# Prevent IP spoofing
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1

# Ignore ICMP redirects
net.ipv4.conf.all.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0

# Disable source packet routing
net.ipv4.conf.all.accept_source_route = 0
net.ipv6.conf.all.accept_source_route = 0

# Enable SYN flood protection
net.ipv4.tcp_syncookies = 1

# Log suspicious packets
net.ipv4.conf.all.log_martians = 1

Add these lines to /etc/sysctl.conf, then apply them with sysctl -p. You won't notice any functional changes—these are defensive tweaks that quietly reject malformed or spoofed traffic.

8. Enable automatic security updates

Manual patching is fine until you forget for three months. Automatic updates keep the server current without daily attention. On Ubuntu:

apt install unattended-upgrades
dpkg-reconfigure -plow unattended-upgrades

Edit /etc/apt/apt.conf.d/50unattended-upgrades to control what gets updated. By default it handles security patches only, which is usually the right balance. On CentOS or RHEL, yum-cron provides similar functionality:

yum install yum-cron
systemctl enable yum-cron
systemctl start yum-cron

Edit /etc/yum/yum-cron.conf and set apply_updates = yes under the [commands] section. Check /var/log/unattended-upgrades/ or /var/log/yum.log periodically to confirm updates are running. A server that's six months behind on patches is easier to compromise than one kept current.

What you gain from each layer

These eight configurations don't make a server invulnerable—nothing does. They raise the bar high enough that automated scans move on, and opportunistic attackers hit a wall. Each control blocks a different attack vector: the firewall stops port scans, SSH hardening defeats brute force, service reduction shrinks the attack surface, permissions prevent local escalation, fail2ban throttles repeat offenders, sysctl tweaks harden the network stack, and automatic updates close known vulnerabilities.

Stack them all together and you've got a baseline that handles 95% of the threats a typical VPS faces. The remaining 5% requires monitoring, log analysis, and occasionally more specialized tools like intrusion detection systems or web application firewalls.

Check your configurations quarterly. Software updates sometimes reset config files to defaults, and new services you install might open ports you didn't intend. A quick review of iptables rules, sshd_config, and active services takes ten minutes and catches most drift.

How do I test if my hardening worked?

Run an external port scan with nmap from a different machine: nmap -sS -p- yourserver.com. You should see only the ports you intentionally opened. Check SSH by attempting to log in as root—it should fail immediately. Review /var/log/auth.log for failed login attempts and confirm fail2ban is banning repeat offenders.

Should I use a custom SSH port or keep 22?

Changing the port cuts down log noise but doesn't add real security—an attacker doing reconnaissance will find it in seconds. I change it anyway because it makes log files readable and reduces CPU cycles wasted on bot traffic. Pick a high port, update your firewall, and document it.

What if I lock myself out via SSH?

Most VPS hosting panels provide a console or VNC access that bypasses SSH entirely. Use that to log in as root, fix your sshd_config or firewall rules, and restore access. Always test changes in a second terminal session before closing your primary connection.

Do I need a third-party firewall appliance?

Not for a single VPS. Iptables or ufw handle perimeter defense fine. If you're managing dozens of servers or need centralized logging and policy enforcement, consider a dedicated firewall or cloud security group. For one or two servers, the tools you already have are enough.

Start with the firewall and SSH

If you implement only two items from this list, make them the default-deny firewall and SSH hardening. Those two alone stop the bulk of automated attacks. The rest build defense in depth—layers that make it progressively harder for an attacker to move laterally or escalate privileges even if they breach the perimeter.

Server security hardening isn't a one-time checklist. Revisit these settings when you install new software, change hosting providers, or onboard a new team member who needs access. Threat patterns shift, but these fundamentals stay relevant.