cd /blog
LinuxHardeningSSHUFWSecurity

#Linux Server Hardening: A Practical Checklist

A step-by-step guide to hardening a fresh Ubuntu/Debian server — from SSH lockdown and firewall rules to kernel parameter tuning and audit logging.

3 min read 478 words

Why Hardening Matters

A default Linux installation is designed for broad compatibility, not maximum security. Default settings leave unnecessary services running, weak password policies in place, and valuable logging disabled. Hardening is the systematic process of reducing the attack surface.

Scope: This guide targets Ubuntu 22.04 LTS / Debian 12 on a VPS or bare-metal server.


1. Initial System Updates

Always start with a fully patched system.

apt update && apt full-upgrade -y
apt autoremove -y && apt autoclean

Enable unattended security upgrades:

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

2. SSH Hardening

SSH is the most common attack vector on internet-exposed servers. Lock it down hard.

# Edit /etc/ssh/sshd_config
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
X11Forwarding no
AllowTcpForwarding no
MaxAuthTries 3
LoginGraceTime 30
ClientAliveInterval 300
ClientAliveCountMax 2
# Change the default port (optional, reduces noise in logs)
Port 2222

Reload SSH after editing:

systemctl reload sshd

3. Firewall with UFW

apt install ufw -y

# Default deny-all policy
ufw default deny incoming
ufw default allow outgoing

# Allow only what you need
ufw allow 2222/tcp   # SSH (your custom port)
ufw allow 80/tcp     # HTTP
ufw allow 443/tcp    # HTTPS

ufw enable
ufw status verbose

4. Fail2Ban: Auto-Block Brute Force

apt install fail2ban -y

# Create local override (never edit jail.conf directly)
cat > /etc/fail2ban/jail.local << 'EOF'
[DEFAULT]
bantime  = 1h
findtime = 10m
maxretry = 5

[sshd]
enabled = true
port    = 2222
EOF

systemctl enable --now fail2ban
fail2ban-client status sshd

5. Kernel Parameter Hardening (sysctl)

cat >> /etc/sysctl.d/99-hardening.conf << 'EOF'
# Prevent IP spoofing
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1

# Ignore ICMP broadcast requests
net.ipv4.icmp_echo_ignore_broadcasts = 1

# Disable IPv6 if unused
net.ipv6.conf.all.disable_ipv6 = 1

# Protect against SYN flood
net.ipv4.tcp_syncookies = 1

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

# Randomise kernel address space
kernel.randomize_va_space = 2
EOF

sysctl --system

6. Audit Logging with auditd

apt install auditd audispd-plugins -y
systemctl enable --now auditd

# Watch sensitive files
auditctl -w /etc/passwd -p wa -k passwd_changes
auditctl -w /etc/sudoers -p wa -k sudoers_changes
auditctl -w /var/log/auth.log -p r -k auth_log_read

# Make rules persistent
ausearch -k passwd_changes

Quick Reference Checklist

TaskStatus
System fully updated
SSH: root login disabled
SSH: password auth disabled
Firewall (UFW) enabled
Fail2Ban configured
Kernel params hardened
Auditd logging enabled

Next Steps

  • Configure AppArmor or SELinux for mandatory access control.
  • Deploy Wazuh or OSSEC for host-based intrusion detection.
  • Set up centralised log shipping with rsyslog → SIEM.