DEV Community

Ramer Labs
Ramer Labs

Posted on

7 Tips for Securing Nginx with TLS and Firewall Rules on Servers

Introduction

If you’re a DevOps lead responsible for high‑traffic web services, securing the front‑end proxy is non‑negotiable. Nginx sits at the edge of most modern stacks, acting as a reverse proxy, load balancer, and static file server. A single misconfiguration can expose sensitive data or open the door to denial‑of‑service attacks. This checklist walks you through seven practical steps to harden Nginx with TLS, firewall rules, and complementary security tools.


1. Enforce Strong TLS Settings

TLS is the first line of defense against eavesdropping. Use the latest stable OpenSSL version and configure Nginx to prefer modern cipher suites.

# /etc/nginx/conf.d/ssl.conf
ssl_protocols TLSv1.3 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers \
    "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256";
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1h;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
Enter fullscreen mode Exit fullscreen mode
  • Why it matters – Disabling TLS 1.0/1.1 eliminates known weaknesses. The cipher list above follows Mozilla’s "Intermediate" recommendation and avoids RSA key‑exchange, which is vulnerable to log‑jam attacks.

2. Redirect All HTTP Traffic to HTTPS

A stray HTTP endpoint can leak cookies and allow man‑in‑the‑middle attacks. Add a catch‑all server block that issues a 301 redirect.

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name _;
    return 301 https://$host$request_uri;
}
Enter fullscreen mode Exit fullscreen mode

Make sure the block is placed before any other server directives, otherwise Nginx may never evaluate it.

3. Harden the Underlying Linux Firewall

Even with TLS in place, you should restrict which ports are reachable from the internet. A typical Nginx host only needs ports 80, 443, and SSH (22) for admin access.

# Using ufw (Ubuntu/Debian)
ufw default deny incoming
ufw default allow outgoing
ufw allow 80/tcp
ufw allow 443/tcp
ufw allow 22/tcp comment "SSH for admin"
ufw enable
Enter fullscreen mode Exit fullscreen mode

If you prefer iptables:

iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
Enter fullscreen mode Exit fullscreen mode

Tip: Keep a copy of your firewall rules in version control. It makes rollback after a bad change painless.

4. Deploy Fail2Ban to Thwart Brute‑Force SSH Attempts

While Nginx itself isn’t vulnerable to password guessing, a compromised SSH key can give an attacker full control of the server. Fail2Ban monitors log files and bans IPs that exceed a threshold.

# /etc/fail2ban/jail.local
[sshd]
enabled = true
port    = ssh
logpath = /var/log/auth.log
maxretry = 5
bantime = 3600
Enter fullscreen mode Exit fullscreen mode

Restart the service:

systemctl restart fail2ban
Enter fullscreen mode Exit fullscreen mode

You can add a similar jail for Nginx’s error.log to block repeated 404 or 403 responses that look like scanning attempts.

5. Enable HTTP Security Headers

Headers such as Content‑Security‑Policy, X‑Content‑Type‑Options, and Referrer-Policy reduce the attack surface for XSS and click‑jacking.

add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options SAMEORIGIN;
add_header Referrer-Policy "no-referrer-when-downgrade";
add_header Content-Security-Policy "default-src 'self' https:; script-src 'self' 'unsafe-inline'";
Enter fullscreen mode Exit fullscreen mode

Apply these directives inside the server block that serves your public site.

6. Regularly Rotate TLS Certificates and Automate Renewal

Manual certificate updates are error‑prone. Use certbot (Let’s Encrypt) or a commercial ACME client to schedule automatic renewal.

# Install certbot and obtain a cert for example.com
apt-get install certbot python3-certbot-nginx
certbot --nginx -d example.com -d www.example.com

# Verify renewal works
certbot renew --dry-run
Enter fullscreen mode Exit fullscreen mode

Add a cron job (or rely on the systemd timer installed by certbot) to run certbot renew twice daily.

7. Keep Nginx and System Packages Patched

Security patches are released frequently. Enable unattended upgrades for non‑critical updates, but schedule a weekly maintenance window for major Nginx version bumps.

# Ubuntu example – enable unattended upgrades
apt-get install unattended-upgrades
dpkg-reconfigure unattended-upgrades
Enter fullscreen mode Exit fullscreen mode

During the maintenance window, run:

apt-get update && apt-get upgrade -y
systemctl restart nginx
Enter fullscreen mode Exit fullscreen mode

Always test the new binary in a staging environment before production rollout.


Checklist Summary

Action
1 Use TLS 1.2/1.3 with a modern cipher suite
2 Force HTTP → HTTPS redirects
3 Lock down the firewall to only required ports
4 Deploy Fail2Ban for SSH and Nginx logs
5 Add essential security headers
6 Automate TLS certificate renewal
7 Apply regular OS and Nginx patches

Following these seven steps will give you a robust, production‑ready Nginx deployment that resists common network‑level attacks while staying performant.


For deeper dives into server hardening, consider checking out the resources on https://lacidaweb.com, which offers practical guides tailored for developers and SREs.

Top comments (0)