DEV Community

Ramer Labs
Ramer Labs

Posted on

7 Tips for Hardening Nginx and Linux Servers in Environments

Introduction

If you’re responsible for a production‑grade web stack, the difference between a well‑hardened server and a vulnerable one can be measured in minutes of downtime or a costly data breach. This tutorial walks through seven practical steps to lock down Nginx and the underlying Linux host without sacrificing performance.


1. Enforce Strong TLS Everywhere

TLS is the first line of defense against eavesdropping. Modern browsers expect TLS 1.3 or at least TLS 1.2 with strong ciphers.

# /etc/nginx/conf.d/ssl.conf
ssl_protocols TLSv1.3 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers \
    "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_stapling on;
ssl_stapling_verify on;

# Enable HTTP/2 for better multiplexing
listen 443 ssl http2;
Enter fullscreen mode Exit fullscreen mode
  • Use a certificate from a trusted CA (Let’s Encrypt works fine for most use‑cases).
  • Enable OCSP stapling to reduce latency.
  • Turn off SSLv3, TLS 1.0, and TLS 1.1.

2. Restrict Inbound Traffic with a Minimal Firewall

A host‑level firewall should only allow the ports you actually need. Below is a concise iptables rule set that blocks everything by default and opens only HTTP, HTTPS, SSH, and health‑check ports.

# 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 and established connections
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# Open required ports
iptables -A INPUT -p tcp --dport 22 -j ACCEPT   # SSH
iptables -A INPUT -p tcp --dport 80 -j ACCEPT   # HTTP
iptables -A INPUT -p tcp --dport 443 -j ACCEPT  # HTTPS
iptables -A INPUT -p tcp --dport 9100 -j ACCEPT # Prometheus metrics (optional)

# Log and drop everything else (optional)
iptables -A INPUT -j LOG --log-prefix "iptables-drop: "
iptables -A INPUT -j DROP
Enter fullscreen mode Exit fullscreen mode

Persist the rules with iptables-save > /etc/iptables/rules.v4 (Debian/Ubuntu) or the appropriate service for your distro.

3. Thwart Brute‑Force Logins with Fail2Ban

Fail2Ban watches log files for repeated failed authentication attempts and injects temporary iptables bans.

# /etc/fail2ban/jail.local
[sshd]
enabled = true
port    = ssh
logpath = %(sshd_log)s
maxretry = 5
bantime = 3600

[nginx-http-auth]
enabled = true
port    = http,https
logpath = /var/log/nginx/error.log
maxretry = 3
bantime = 7200
Enter fullscreen mode Exit fullscreen mode

After editing, restart the service: systemctl restart fail2ban. Adjust maxretry and bantime to match your security posture.

4. Harden SSH Access

  • Disable password authentication – enforce key‑based logins only.
  • Change the default port (optional but adds obscurity).
  • Limit users with the AllowUsers directive.
  • Enable PermitRootLogin no.
# /etc/ssh/sshd_config
Port 2222
Protocol 2
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
AllowUsers deployer admin
Enter fullscreen mode Exit fullscreen mode

Reload SSH: systemctl reload sshd.

5. Automate Secure Backups

Never rely on a single point of failure. A simple rsync‑over‑SSH script combined with cron can provide daily snapshots.

#!/bin/bash
# /usr/local/bin/backup.sh
SRC="/var/www/html"
DEST="backup@backup‑server:/backups/$(hostname)/$(date +%F)"
rsync -a --delete -e ssh "$SRC" "$DEST"
Enter fullscreen mode Exit fullscreen mode

Add to crontab (run at 02:30 AM):

30 2 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1
Enter fullscreen mode Exit fullscreen mode

For added resilience, rotate snapshots with logrotate‑style retention policies.

6. Keep the System Patched Automatically

Enable unattended upgrades for security patches while leaving major version upgrades manual.

# Debian/Ubuntu
apt install unattended-upgrades
dpkg-reconfigure unattended-upgrades
Enter fullscreen mode Exit fullscreen mode

On RHEL‑based systems, enable yum-cron:

yum install yum-cron
systemctl enable --now yum-cron
Enter fullscreen mode Exit fullscreen mode

Review /etc/apt/apt.conf.d/50unattended-upgrades to ensure only -security repos are auto‑installed.

7. Deploy a Lightweight WAF with Nginx

Nginx’s ngx_http_modsecurity_module (or the open‑source ModSecurity with the OWASP CRS) can block common OWASP Top 10 attacks.

# /etc/nginx/modsecurity.conf
Include /usr/local/modsecurity-crs/base_rules/*.conf;
SecRuleEngine On
SecRequestBodyAccess On
SecResponseBodyAccess Off
SecRuleRemoveById 950005  # Example: disable a noisy rule
Enter fullscreen mode Exit fullscreen mode

Enable the module in your main config:

load_module modules/ngx_http_modsecurity_module.so;

server {
    listen 443 ssl;
    modsecurity on;
    modsecurity_rules_file /etc/nginx/modsecurity.conf;
    # ... other directives ...
}
Enter fullscreen mode Exit fullscreen mode

Test the configuration with nginx -t and reload.


Conclusion

Hardening a Linux box that runs Nginx doesn’t require a massive overhaul; it’s a series of incremental, repeatable steps. By enforcing TLS 1.3, locking down the firewall, automating fail2ban, tightening SSH, scheduling encrypted backups, keeping the OS patched, and adding a modest WAF, you’ll raise the security bar dramatically while preserving the low‑latency performance that Nginx is known for.

If you’re looking for a reliable partner to review or host your hardened stack, consider checking out https://lacidaweb.com for a no‑pressure conversation.

Top comments (1)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.