DEV Community

Ramer Labs
Ramer Labs

Posted on

7 Tips for Securing Nginx with TLS and Firewall Rules Today

Introduction

When you run a web service behind Nginx, TLS and a well‑crafted firewall are the first line of defense. As a DevOps lead, you’re probably juggling performance, reliability, and security on the same server. This tutorial walks you through seven concrete steps that lock down Nginx without sacrificing speed.


1. Use Modern TLS Settings

Older ciphers and protocols are a common attack surface. Replace the default ssl_protocols and ssl_ciphers with a hardened suite.

# /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_ecdh_curve X25519:secp384r1;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1h;
Enter fullscreen mode Exit fullscreen mode
  • Why it matters: TLS 1.3 cuts handshake latency and drops weak cipher suites.
  • Test: Run openssl s_client -connect yourdomain.com:443 -tls1_3 to verify.

2. Enable HTTP Strict Transport Security (HSTS)

HSTS tells browsers to only use HTTPS for your domain, preventing downgrade attacks.

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
Enter fullscreen mode Exit fullscreen mode

Add the header in a server block that handles HTTPS only. Remember to submit your domain to the HSTS preload list once you’re confident.


3. Restrict Access with a Minimal Firewall

A lightweight ufw (Uncomplicated Firewall) configuration reduces the attack surface.

# Allow SSH from a trusted IP only
ufw allow from 203.0.113.42 to any port 22 proto tcp

# Open HTTP/HTTPS for the public
ufw allow 80/tcp
ufw allow 443/tcp

# Deny everything else
ufw default deny incoming
ufw default allow outgoing

ufw enable
Enter fullscreen mode Exit fullscreen mode

Tip: Keep a separate SSH bastion if you need broader admin access.


4. Deploy Fail2Ban for Brute‑Force Protection

Fail2Ban monitors Nginx logs and bans IPs that trigger too many 4xx responses.

apt-get install fail2ban -y
cat > /etc/fail2ban/jail.local <<'EOF'
[nginx-http-auth]
enabled = true
filter = nginx-http-auth
logpath = /var/log/nginx/error.log
maxretry = 5
bantime = 3600
EOF
systemctl restart fail2ban
Enter fullscreen mode Exit fullscreen mode

The built‑in nginx-http-auth filter catches repeated authentication failures.


5. Separate Static Content with a Dedicated Location Block

Serving static assets from a read‑only directory reduces the impact of a compromise.

location /static/ {
    alias /var/www/static/;
    autoindex off;
    add_header Cache-Control "public, max-age=31536000, immutable";
    # No PHP processing here
    try_files $uri $uri/ =404;
}
Enter fullscreen mode Exit fullscreen mode

Set the filesystem permissions to chmod 755 for the directory and chmod 644 for files. The web server can read them, but a malicious script cannot write.


6. Automate Certificate Renewal with Certbot

Let’s Encrypt certificates expire after 90 days. Automate renewal to avoid downtime.

apt-get install certbot python3-certbot-nginx -y
certbot --nginx -d example.com -d www.example.com --agree-tos --redirect --no-eff-email

# Verify the systemd timer is active
systemctl list-timers | grep certbot
Enter fullscreen mode Exit fullscreen mode

Certbot drops a cron job or systemd timer that runs twice daily, checking for renewal.


7. Monitor TLS Handshake Metrics

A sudden spike in TLS handshake failures can indicate a scanning attack. Use nginx-module-vts or Prometheus exporter to collect metrics.

# In the http block
vhost_traffic_status_zone;

server {
    listen 443 ssl;
    ...
    location /status {
        vhost_traffic_status_display;
        allow 127.0.0.1;
        deny all;
    }
}
Enter fullscreen mode Exit fullscreen mode

Scrape /status with Prometheus, then set alerts on nginx_vts_handshake_errors_total.


Checklist Recap

Action
1 Harden TLS cipher suite and enable TLS 1.3
2 Add HSTS header and consider preload
3 Configure a minimal ufw firewall
4 Install Fail2Ban with Nginx filter
5 Serve static assets from a read‑only location
6 Automate Let’s Encrypt renewal with Certbot
7 Export TLS handshake metrics for alerting

Running through this checklist weekly keeps your Nginx gateway both fast and resilient.


Final Thoughts

Security is a moving target, but by applying these seven pragmatic steps you’ll dramatically raise the bar for attackers while keeping latency low. For deeper dives into Nginx hardening, community‑driven modules, and real‑world case studies, check out the resources at https://lacidaweb.com. Happy hardening!

Top comments (0)