Back to articles
LinuxJan 202613 min

Hardening a Linux server for production: the practical checklist nobody writes down

SSH key-only auth is table stakes. This goes further — UFW rules, fail2ban tuning, unattended-upgrades, sysctl hardening, process limits, log rotation, and the specific things that will save you at 2am when something goes wrong.

Server hardening is often presented as an abstract security chore. On bare-metal or container hosts, however, correct system-level configuration directly controls system stability, protecting server processes from raw exhaustion during automated scanner sweeps and malicious connection spikes.

Baseline SSH Containment

Standard SSH configurations expose authentication routines to brute-force attacks. Restrict authentication to cryptographic keys, and disable weak cipher algorithms to ensure standard security compliance.

/etc/ssh/sshd_config.d/security.conf
# Restrict protocols and force modern cryptographic keys
Protocol 2
PasswordAuthentication no
PubkeyAuthentication yes
PermitEmptyPasswords no
PermitRootLogin no

# Enforce secure connection algorithms
KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,diffie-hellman-group16-sha512
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com
MACs hmac-sha2-512-etm@openssh.com

Network Containment

Run a minimal firewall to drop invalid packets before they consume local connection buffers. On modern Linux installations, use nftables directly instead of legacy iptables to manage high packet rates with minimum overhead.

/etc/nftables.conf
table inet filter {
    chain input {
        type filter hook input priority 0; policy drop;

        # Accept loopback traffic
        iif "lo" accept

        # Accept established network tracks
        ct state established,related accept

        # Drop invalid network packets early
        ct state invalid drop

        # Strict port restrictions
        tcp dport { 22, 80, 443 } accept
    }
}

Sysctl Kernel Tuning

Under peak traffic, the default Linux socket queue bounds are easily overwhelmed. Tune virtual memory and TCP socket buffers to sustain heavy network loads without dropping packets.

/etc/sysctl.d/99-network-tuning.conf
# Increase maximum socket backlog
net.core.somaxconn = 65535

# Increase connection tracking table limit
net.netfilter.nf_conntrack_max = 262144

# Enable TCP SYN cookies to mitigate SYN flood attacks
net.ipv4.tcp_syncookies = 1

# Reduce TCP connection timeout steps
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_keepalive_time = 300

Systemd Resource Limits

A runaway backend process should never be allowed to drain host system memory and freeze secondary operations. Set exact process execution parameters in system service unit definitions.

/etc/systemd/system/php-fpm.service.d/limits.conf
[Service]
# Set strict memory usage ceilings
MemoryMax=8G
MemoryHigh=7.5G

# Allow scaling file descriptors
LimitNOFILE=65535

# Restart the service instantly if it experiences OOM crashes
Restart=always
RestartSec=5s
Written By
SK
Sagar Kapasi
Software Engineer

Sagar builds operational systems and developer hosting infrastructure from the ground up, specializing in Linux, PHP, and high-performance architectures.

Tags
LinuxSecurityOperationsSSH