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;
- 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;
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
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
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; }
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
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; } }
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)