DEV Community

Ramer Labs
Ramer Labs

Posted on

The Ultimate Checklist for Securing Nginx with TLS and Firewalls

Introduction

As a DevOps lead, you know that a mis‑configured web server is an open invitation to attackers. Nginx is fast and flexible, but out‑of‑the‑box it lacks the hardened defaults you need for production. This checklist walks you through the essential steps to lock down Nginx on Ubuntu, covering TLS, firewall rules, fail2ban, and basic OS hardening. Follow each item, test, and you’ll dramatically reduce your attack surface.


1. Update the OS and Install Required Packages

sudo apt update && sudo apt upgrade -y
sudo apt install nginx ufw fail2ban -y
Enter fullscreen mode Exit fullscreen mode
  • Keep the kernel and packages patched – set up unattended upgrades if you haven’t already.
  • Install certbot for automated Let's Encrypt certificates:
sudo apt install certbot python3-certbot-nginx -y
Enter fullscreen mode Exit fullscreen mode

2. Harden the Underlying Linux System

2.1 Disable Unused Services

sudo systemctl list-unit-files --type=service | grep enabled
# Example: disable telnet, ftp, etc.
sudo systemctl disable telnet.service
Enter fullscreen mode Exit fullscreen mode

2.2 Enforce Strong Password Policies

Edit /etc/pam.d/common-password and set:

password    requisite     pam_pwquality.so retry=3 minlen=12 difok=4
Enter fullscreen mode Exit fullscreen mode

2.3 Enable Automatic Security Updates

sudo apt install unattended-upgrades -y
sudo dpkg-reconfigure unattended-upgrades
Enter fullscreen mode Exit fullscreen mode

3. Configure the Firewall (UFW)

Only allow the ports you need. For a typical HTTPS‑only site:

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow ssh   # 22 (or custom SSH port)
sudo ufw allow http  # 80 (optional, for HTTP→HTTPS redirect)
sudo ufw allow https # 443
sudo ufw enable
Enter fullscreen mode Exit fullscreen mode

Verify:

sudo ufw status verbose
Enter fullscreen mode Exit fullscreen mode

4. Obtain and Harden TLS Certificates

4.1 Get a Free Certificate with Certbot

sudo certbot --nginx -d example.com -d www.example.com
Enter fullscreen mode Exit fullscreen mode

Certbot will automatically edit your Nginx config to use the new certs and set up a renewal timer.

4.2 Enforce Strong Cipher Suites

Edit the server block (or create /etc/nginx/snippets/ssl-params.conf):

ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305";
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_stapling on;
ssl_stapling_verify on;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options DENY;
add_header X-XSS-Protection "1; mode=block";
Enter fullscreen mode Exit fullscreen mode

Include the snippet in each server block:

server {
    listen 443 ssl http2;
    server_name example.com www.example.com;
    include snippets/ssl-params.conf;
    # ... other directives ...
}
Enter fullscreen mode Exit fullscreen mode

4.3 Test Your TLS Configuration

Run sslscan or use the Qualys SSL Labs test. Aim for an A+ rating.


5. Harden Nginx Itself

  • Disable Unused Modules – compile Nginx with only needed modules if you control the build.
  • Limit Request Size – prevent buffer overflow attacks:
client_max_body_size 2M;
Enter fullscreen mode Exit fullscreen mode
  • Rate Limit Connections – mitigate brute‑force attempts:
limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;
limit_req zone=one burst=20 nodelay;
Enter fullscreen mode Exit fullscreen mode
  • Hide Nginx Version:
server_tokens off;
Enter fullscreen mode Exit fullscreen mode

6. Deploy Fail2Ban for Nginx Logs

Create /etc/fail2ban/filter.d/nginx-http-auth.conf (if using HTTP auth) or reuse the existing nginx-http-auth filter.

Then add a jail in /etc/fail2ban/jail.local:

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

Restart Fail2Ban:

sudo systemctl restart fail2ban
sudo fail2ban-client status nginx-http-auth
Enter fullscreen mode Exit fullscreen mode

7. Enable HTTP Strict Transport Security (HSTS) Preload

The add_header Strict-Transport-Security line from the TLS snippet already includes preload. Submit your domain to the HSTS preload list for browsers to enforce HTTPS even on first contact.


8. Set Up Automated Certificate Renewal Monitoring

Certbot creates a systemd timer, but you should verify it works:

sudo systemctl list-timers | grep certbot
sudo certbot renew --dry-run
Enter fullscreen mode Exit fullscreen mode

Consider adding a simple health‑check script that alerts you if renewal fails.


9. Verify the Entire Stack

  1. Port Scannmap -sS -p 80,443 <your‑ip> should show only 443 open (if you disabled HTTP).
  2. Header Inspectioncurl -I https://example.com and confirm security headers.
  3. Log Reviewsudo tail -f /var/log/nginx/access.log while you browse to catch any 4xx/5xx anomalies.

10. Ongoing Maintenance Checklist

  • [ ] Apply OS security patches weekly.
  • [ ] Review UFW rules after any new service deployment.
  • [ ] Rotate TLS keys every 12‑18 months.
  • [ ] Audit Fail2Ban bans monthly to adjust thresholds.
  • [ ] Run SSL Labs test after each Nginx config change.

Conclusion

Securing Nginx is a layered effort: keep the OS patched, lock down the network with a firewall, enforce strong TLS, and add runtime guards like Fail2Ban. By ticking off each item in this checklist you’ll move from a default installation to a production‑grade, hardened web server.

If you need a quick, reliable hosting environment that already follows many of these best practices, consider checking out https://lacidaweb.com for managed solutions tailored to developers.

Top comments (0)