← Harden & defendfive settings to harden any nginx server

five settings to harden any nginx server

your nginx box is probably running wide open right now

most nginx installs work fine out of the box, which is exactly the problem. "works fine" and "secure" are not the same thing. the default config is built for compatibility, not defense, so it happily hands out version numbers, accepts ancient tls handshakes, and lets bots hammer your login page all day. none of that is a bug. it's just a default nobody told you to change. here are five settings that actually move the needle, plus the config to make it real.

1. force modern tls only

tls 1.0 and 1.1 are still enabled on a lot of servers because "it might break something." what it actually does is let attackers downgrade connections to protocols with known weaknesses (think poodle, beast). if you're not supporting decade-old browsers, you don't need them.

ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers HIGH:!aNULL:!MD5;

this tells nginx to refuse to negotiate anything older than tls 1.2, and to lean on strong cipher suites instead of whatever the client suggests first.

2. add security headers, starting with hsts

hsts (http strict transport security) tells browsers "never talk to this site over plain http, ever, even if someone tricks you into trying." that shuts down a whole category of downgrade and mitm attacks where a user gets bounced to an insecure connection without noticing.

add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;

the max-age is in seconds, 63072000 is two years. don't set this on a domain unless you're fully committed to https everywhere, because browsers will refuse http even if you change your mind later.

3. turn off server_tokens

by default nginx sticks its exact version number in every response header and error page. that's a free gift to anyone scanning for known cves. you're not hiding nginx itself, you're just not printing "here's the exact version and known exploit list to try."

server_tokens off;

one line, drop it in your http block, done. it's not a magic invisibility cloak, it's just removing a label that makes an attacker's job easier for zero benefit to you.

4. rate-limit requests

login pages, search bars, and api endpoints get hit by bots doing brute force or scraping around the clock. rate limiting doesn't stop a determined attacker, but it kills the lazy automated stuff instantly and buys you time to notice the rest.

limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;

location /login {
    limit_req zone=login burst=10 nodelay;
}

this caps requests to your login route at 5 per minute per ip, with a small burst allowance. tune the number based on real traffic, not guesswork, check your access logs first so you don't lock out legit users.

5. block hidden and dot-files

.env, .git, .htaccess, backup files with a trailing tilde, these leak credentials and source code constantly because someone forgot they were sitting in a public web root. nginx will serve them just like any other file unless you tell it not to.

location ~ /\. {
    deny all;
    access_log off;
    log_not_found off;
}

this regex catches any path starting with a dot and refuses it outright. pair this with actually checking what's in your web root, because the fix for "don't serve .env" is also "don't put .env there in the first place."

the takeaway

none of these five changes require you to be a security expert, they're just settings nobody remembers to flip. pull up your nginx.conf, check it against this list, and reload once you've tested (nginx -t before you touch prod, always). hardening isn't one big dramatic fix, it's a handful of boring lines that quietly remove the easy wins an attacker was counting on. do the boring stuff. it works.

watch the reel ↗
the weekly drop

one command a week that makes you harder to hack.

a single tool, explained in plain english, every week. straight to your inbox.

no spam. one email a week. unsubscribe anytime.