Introduction
Running Nginx on a Linux host is a common pattern for high‑traffic web services, but a mis‑configured stack can become an easy target for attackers. This checklist walks you through seven practical steps you can apply today to tighten TLS, lock down the firewall, automate fail2ban, secure SSH, enable reliable backups, add a lightweight WAF, and keep the system patched. It’s written from the perspective of a DevOps lead who needs repeatable, auditable hardening procedures for production environments.
1. Enforce Strong TLS Settings
TLS is the first line of defense for any public‑facing service. Nginx’s ssl.conf
should be trimmed to modern ciphers only and HTTP/2 enabled.
# /etc/nginx/conf.d/ssl.conf ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers on; ssl_ciphers "\ TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256"; ssl_session_timeout 1d; ssl_session_cache shared:SSL:10m; ssl_stapling on; ssl_stapling_verify on; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
- Disable TLS 1.0/1.1 – they are deprecated.
- Prefer server ciphers to avoid weak client‑side selections.
- Enable HSTS to force browsers onto HTTPS.
After editing, test the configuration with openssl s_client -connect yourdomain.com:443 -tls1_2
and use tools like SSL Labs to verify the grade.
2. Harden the Host Firewall
A minimal iptables
(or nftables
) rule set reduces the attack surface. The example below blocks everything except HTTP/HTTPS, SSH (restricted to a known IP range), and loopback.
# /etc/iptables.rules *filter :INPUT DROP [0:0] :FORWARD DROP [0:0] :OUTPUT ACCEPT [0:0] # Allow loopback -A INPUT -i lo -j ACCEPT # Allow established connections -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT # HTTP/HTTPS -A INPUT -p tcp --dport 80 -j ACCEPT -A INPUT -p tcp --dport 443 -j ACCEPT # SSH from trusted subnet (e.g., 203.0.113.0/24) -A INPUT -p tcp -s 203.0.113.0/24 --dport 22 -j ACCEPT COMMIT
Load the rules with iptables-restore < /etc/iptables.rules
and make the file persistent using your distro’s firewall service (e.g., netfilter-persistent
).
3. Deploy Fail2Ban for Brute‑Force Protection
Fail2Ban monitors log files and bans IPs that show malicious signs. A typical jail for Nginx and SSH looks like this:
# /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
Restart the service with systemctl restart fail2ban
. Verify bans via fail2ban-client status sshd
.
4. Secure SSH with Key‑Based Authentication Only
Password logins are the weakest link. Enforce public‑key authentication and disable root login.
# /etc/ssh/sshd_config (excerpt) PasswordAuthentication no PubkeyAuthentication yes PermitRootLogin prohibit-password AllowUsers deploy@example.com
After editing, run ssh-keygen -t ed25519
on the admin machine, copy the ~/.ssh/id_ed25519.pub
to the server’s ~/.ssh/authorized_keys
, and reload SSH: systemctl reload sshd
.
5. Implement Automated Backups
A reliable backup strategy protects you from ransomware and accidental deletions. Below is a simple rsync
‑based script that snapshots /var/www
and /etc/nginx
to a remote SFTP server.
#!/bin/bash # /usr/local/bin/backup-nginx.sh set -euo pipefail REMOTE="backup@example.com" DEST="/backups/$(hostname)/$(date +%Y%m%d)" mkdir -p "$DEST" # Sync web root and config rsync -a --delete /var/www "$DEST/www" rsync -a /etc/nginx "$DEST/nginx" # Push to remote storage sftp "$REMOTE" <<EOF mkdir -p $DEST put -r $DEST/* $DEST/ EOF # Keep last 7 days locally find /backups/$(hostname) -mindepth 1 -maxdepth 1 -type d -mtime +7 -exec rm -rf {} +
Schedule the script with cron
(0 2 * * * /usr/local/bin/backup-nginx.sh
). Test restoration regularly to ensure integrity.
6. Add a Lightweight Web Application Firewall (WAF)
ModSecurity works well with Nginx and provides rule‑based request filtering. Install the module and enable the OWASP Core Rule Set (CRS).
# Ubuntu/Debian example apt-get install libnginx-mod-http-modsecurity # Enable in nginx.conf modsecurity on; modsecurity_rules_file /etc/modsecurity/modsecurity.conf;
Edit /etc/modsecurity/modsecurity.conf
to set SecRuleEngine On
and point Include
to the CRS rules directory. Restart Nginx and monitor the audit log (/var/log/modsec_audit.log
).
7. Automate Patch Management
Keeping the OS and packages up‑to‑date closes known vulnerabilities. Use unattended upgrades for security‑only updates.
# Install unattended-upgrades apt-get install unattended-upgrades # Enable and configure dpkg-reconfigure --priority=low unattended-upgrades
For Red Hat‑based systems, enable yum-cron
with yum-cron.conf
set to apply_updates = yes
. Combine this with a daily health check script that alerts on failed updates.
Conclusion
Hardening Nginx and its underlying Linux host is a layered effort: strong TLS, a locked‑down firewall, automated brute‑force mitigation, key‑only SSH, reliable backups, a modest WAF, and continuous patching. By following this checklist you’ll reduce the likelihood of a successful breach and improve compliance posture. For deeper dives into each topic and ready‑made Ansible roles, check out the resources at https://lacidaweb.com.
Top comments (0)