Skip to content
Back to Blog
Security10 min read

Server Security Hardening: 10 Configs to Apply Today

Close common attack vectors with ten quick configuration changes—SSH keys, firewall rules, and disabled services that protect your server right now.

Written by Abdul AbrorTechnical Hosting Support Engineer
Server Security Hardening: 10 Configs to Apply Today
On this page

Most breached servers share the same weak spots: password authentication, open ports, outdated software, and services nobody uses running in the background. I've cleaned up after enough incidents to recognize the pattern.

The good news? You can close the biggest holes in under an hour. These ten changes won't make your server invincible, but they stop the automated scans and script-kiddie tools that account for most attacks.

1. Enforce SSH Key Authentication

Password authentication over SSH is asking for trouble. Botnets hammer port 22 with common passwords around the clock.

Generate a key pair on your local machine if you haven't already:

ssh-keygen -t ed25519 -C "[email protected]"

Copy the public key to your server:

ssh-copy-id -i ~/.ssh/id_ed25519.pub user@your-server-ip

Test the key login, then disable password authentication. Edit /etc/ssh/sshd_config:

PasswordAuthentication no
PubkeyAuthentication yes
ChallengeResponseAuthentication no

Restart SSH:

systemctl restart sshd

Don't skip the test login. Locking yourself out means a recovery console session or support ticket.

2. Change the Default SSH Port

Port 22 gets hit constantly. Moving SSH to a high port—something above 1024—drops the noise by ninety percent or more.

Pick a port that's not commonly used. I like numbers in the 50000-60000 range. Edit /etc/ssh/sshd_config:

Port 52847

Update your firewall rules before restarting SSH (more on that in a moment). Then reconnect:

ssh -p 52847 user@your-server-ip

This is security through obscurity, and it's not a replacement for key authentication. But it cuts way down on log spam and CPU cycles wasted on failed login attempts.

3. Configure a Host Firewall

If you're running a Linux server without a firewall, you're trusting every service to be perfectly configured. That's optimistic.

Most distributions ship with firewalld or ufw. Pick one and use it. For ufw on Ubuntu/Debian:

ufw default deny incoming
ufw default allow outgoing
ufw allow 52847/tcp comment 'SSH'
ufw allow 80/tcp comment 'HTTP'
ufw allow 443/tcp comment 'HTTPS'
ufw enable

For firewalld on RHEL/CentOS/AlmaLinux:

firewall-cmd --permanent --remove-service=ssh
firewall-cmd --permanent --add-port=52847/tcp
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --reload

Only open ports you actually need. If you're not running a mail server, don't open ports 25, 587, 465, 993, or 995.

4. Disable Root Login Over SSH

Even with key authentication, allowing direct root login is unnecessary. Create a regular user and give it sudo privileges instead.

Add a user:

adduser deploy
usermod -aG sudo deploy

On RHEL-based systems, replace sudo with wheel.

Copy your SSH key to the new user's home directory, test the login, then edit /etc/ssh/sshd_config:

PermitRootLogin no

Restart SSH. You'll connect as the regular user and escalate to root when needed.

5. Disable Unused Services

Fresh server installs often start services you'll never use. Each one is a potential attack surface.

List running services:

systemctl list-units --type=service --state=running

Common candidates for disabling:

  • cups (printing service—pointless on a headless server)
  • avahi-daemon (network service discovery)
  • bluetooth (why is this even installed?)
  • postfix or sendmail if you route mail through an external SMTP relay

Disable and stop:

systemctl disable --now cups
systemctl disable --now avahi-daemon

Be careful. Don't disable something you rely on. Check first.

6. Keep Software Updated

Outdated packages are low-hanging fruit for attackers. Most exploits target known vulnerabilities with public patches.

Enable automatic security updates on Debian/Ubuntu:

apt install unattended-upgrades
dpkg-reconfigure --priority=low unattended-upgrades

On RHEL/CentOS/AlmaLinux, use dnf-automatic:

dnf install dnf-automatic
systemctl enable --now dnf-automatic.timer

Edit /etc/dnf/automatic.conf and set apply_updates = yes.

For critical servers, you might prefer to test updates in staging first. That's fine. Just don't let systems sit unpatched for months.

7. Configure Fail2Ban

Even with SSH keys and a non-standard port, you'll still see brute-force attempts. Fail2Ban watches your logs and temporarily blocks IPs after repeated failures.

Install it:

apt install fail2ban   # Debian/Ubuntu
dnf install fail2ban   # RHEL/CentOS/AlmaLinux

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

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

[sshd]
enabled = true
port    = 52847

Restart Fail2Ban:

systemctl restart fail2ban

Check banned IPs:

fail2ban-client status sshd

You can add jails for other services—Apache, Nginx, Postfix—if you run them.

8. Set Up Log Monitoring

You can't respond to attacks if you don't know they're happening. At minimum, keep an eye on authentication logs.

On most distributions:

  • /var/log/auth.log (Debian/Ubuntu)
  • /var/log/secure (RHEL/CentOS/AlmaLinux)

Watch failed SSH attempts:

grep 'Failed password' /var/log/auth.log | tail -n 20

For better visibility, install a log aggregation tool. Options range from simple (logwatch) to comprehensive (ELK stack, Graylog). Pick something you'll actually use.

I've seen plenty of servers with fancy logging tools installed but never configured. A daily cron job that emails you a summary is better than a dashboard you never open.

9. Harden Kernel Parameters with sysctl

The Linux kernel exposes hundreds of tunable parameters. A few quick tweaks improve security with no downside.

Edit /etc/sysctl.conf or create a file in /etc/sysctl.d/:

# 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

# Ignore ICMP pings
net.ipv4.icmp_echo_ignore_all = 1

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

Apply the changes:

sysctl -p

These settings block common network-level attacks and reduce your exposure to routing manipulation. Disabling ICMP echo can break some monitoring tools, so skip that line if you rely on ping checks.

10. Restrict File Permissions

Wrong file permissions let one compromised service escalate into full system access. Tighten them.

World-readable files often contain credentials by accident:

find /etc -type f -perm -o+r -ls

Configuration files should be readable only by their service user:

chmod 600 /etc/some-app/config.yml
chown appuser:appuser /etc/some-app/config.yml

Web directories should never be writable by the web server unless absolutely necessary (uploads, cache). When they must be writable, limit it to specific subdirectories and use the most restrictive permissions that work.

In support tickets I handled, the usual compromise path was: attacker uploads shell through vulnerable form → shell runs as www-data → www-data can write to document root → attacker plants backdoor in every PHP file.

Don't make it easy.

So what's the fastest way to verify your changes?

After applying these configs, test them. SSH into your server from a different IP (a VPS in another region works) and confirm:

  • Password authentication is rejected
  • Only your specified ports respond
  • Fail2Ban blocks repeated failures

Run a basic port scan from outside:

nmap -Pn -p- your-server-ip

You should see only the ports you explicitly opened. Everything else filtered or closed.

Check for listening services:

ss -tunlp

Any service bound to 0.0.0.0 or :: is exposed to the internet. Make sure you meant to do that.

Start with SSH and the firewall

These ten changes take an hour, maybe two if you're unfamiliar with some of the tools. They won't prevent every attack, but they close the doors that automated scans walk through daily.

Prioritize SSH hardening and the firewall first—those two stop the majority of opportunistic attacks. Then work through service cleanup, updates, and monitoring. Circle back every few months to audit what's running and whether it still needs to be.

Security is a process, not a checklist. But starting with these configs puts you ahead of most servers on the internet.

FAQ

Will changing the SSH port break my existing scripts and cron jobs?

Only if they hard-code port 22. Update any automation to use -p with your new port or set it in ~/.ssh/config.

Can I disable IPv6 to reduce attack surface?

You can, but it's better to firewall it properly. More services and networks are IPv6-native now, and disabling it entirely can cause unexpected issues.

How do I know which services are safe to disable?

Google the service name and your distro. If you're unsure, leave it running. Disabling the wrong service can break boot or management access.

Is Fail2Ban enough to stop brute-force attacks?

It's a layer. Combined with key authentication and a non-standard port, brute-force becomes a non-issue. Alone, it helps but won't stop a determined attacker.

Should I install an intrusion detection system?

For most single servers, it's overkill. Focus on the basics first. Once you've locked down SSH, the firewall, and services, then consider tools like AIDE or OSSEC if you need them.