Once you have HTTPS enabled and HTTP redirected to HTTPS, the next critical security step is enabling HSTS (HTTP Strict Transport Security).
HSTS is often misunderstood, sometimes misconfigured, and occasionally enabled too early—causing serious production issues. In this article, we’ll explain what HSTS really does, how to enable it safely in Nginx on Ubuntu, and how to avoid breaking your website.
This guide is written in a practical, infra-engineer-friendly way, not theory-heavy, and uses infrarunbook.com as the working example throughout.
What Is HSTS (In Simple Terms)?
HSTS tells browsers:
“Always connect to this website using HTTPS. Never try HTTP again.”
Once a browser receives the HSTS header:
- It will never send HTTP requests to your domain
- Even if a user types
http://
- Even before redirects happen
This protects users from:
- SSL stripping attacks
- Man-in-the-middle attacks
- Accidental insecure access
⚠️ Important Warning Before You Enable HSTS
HSTS is not reversible immediately.
Once a browser stores HSTS:
- You cannot disable it instantly
- Users may be locked into HTTPS until it expires
- A broken SSL setup will make your site unreachable
👉 Only enable HSTS if:
- HTTPS is working perfectly
- SSL certificate auto-renewal is configured
- HTTP → HTTPS redirection is already in place
If you haven’t done HTTP → HTTPS redirect yet, do that first.
Prerequisites Checklist
Before enabling HSTS, confirm:
- ✅ Nginx is installed and running
- ✅ HTTPS is working on port 443
- ✅ HTTP redirects to HTTPS
- ✅ Firewall allows port 443
- ✅ SSL certificate is valid and auto-renewed
If any of these are missing, stop here.
Understanding the HSTS Header
The HSTS header looks like this:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preloadLet’s break it down:
- max-age → How long (in seconds) browsers remember HTTPS
- includeSubDomains → Apply to all subdomains
- preload → Allows domain to be added to browser preload lists
Each option has serious implications, which we’ll handle carefully.
Step 1: Locate Your HTTPS Server Block
HSTS must be added only inside the HTTPS (port 443) server block.
Your config file should be here:
/etc/nginx/sites-available/infrarunbook.comOpen it:
sudo nano /etc/nginx/sites-available/infrarunbook.comMake sure you are editing the SSL-enabled server block (
listen 443 ssl;).
Step 2: Add HSTS Header (Safe Initial Setup)
Recommended Safe Start (NO preload yet)
Add this inside the HTTPS server block:
add_header Strict-Transport-Security "max-age=86400" always;Why This Is the Right First Step
86400
= 1 day (safe testing period)- No subdomain enforcement yet
- Easy to recover if something goes wrong
👉 Never start with 1 year directly.
Step 3: Test Nginx Configuration
Always test before reload:
sudo nginx -tIf successful:
sudo systemctl reload nginxStep 4: Verify HSTS Is Working
Using Browser DevTools
- Open website in HTTPS
- Open Developer Tools → Network
- Check response headers
You should see:
Strict-Transport-Security: max-age=86400Using CLI
curl -I https://infrarunbook.comStep 5: Increase HSTS Duration (After Verification)
After 24–48 hours of stable operation, increase the duration:
add_header Strict-Transport-Security "max-age=31536000" always;This enforces HTTPS for 1 year.
Step 6: Enable HSTS for Subdomains (Carefully)
Only do this if ALL subdomains support HTTPS.
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;⚠️ If any subdomain is HTTP-only, do not enable this.
Step 7: HSTS Preload (Advanced – Optional)
Preload means browsers ship your domain hardcoded as HTTPS-only.
Requirements for Preload
- HTTPS enabled everywhere
- HTTP → HTTPS redirect active
max-age
≥ 31536000includeSubDomains
enabledpreload
directive added
Config:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;Then submit your domain to:
👉 https://hstspreload.org/
⚠️ Preload is extremely hard to undo. Only do this if you are 100% sure.
Common HSTS Mistakes (Very Important)
❌ Enabling HSTS Before HTTPS
Result: Site becomes inaccessible.
❌ Using HSTS in Port 80 Block
HSTS is ignored on HTTP.
❌ Enabling includeSubDomains Without Checking
Breaks APIs, mail, or legacy subdomains.
❌ Starting With Long max-age
No rollback option if SSL fails.
Troubleshooting HSTS Issues
Browser Still Using HTTP?
- Clear browser HSTS cache
- Try incognito mode
- Test from a new device
Site Not Loading After HSTS?
- SSL certificate issue
- Expired certificate
- Incorrect certificate path
Check logs:
sudo tail -f /var/log/nginx/infrarunbook.com.error.logFirewall & HSTS (Often Overlooked)
If HTTPS is blocked:
sudo ufw allow 443/tcp
sudo ufw reloadWithout port 443 open, HSTS will lock users out.
Best Practices for HSTS in Nginx
- Start with low max-age
- Test thoroughly
- Enable subdomains only when ready
- Preload only for mature domains
- Ensure SSL auto-renewal
- Monitor logs regularly
Final Thoughts
HSTS is one of the strongest security improvements you can add to a website—but it must be done carefully and deliberately. When implemented correctly, it permanently protects users from insecure access and strengthens trust in your site.
For infrarunbook.com, HSTS is a logical next step after HTTPS redirection, and once fully deployed, it ensures browsers never downgrade security.
