en

Advanced Nginx Configuration for Tor Hidden Services

Nginx serves as the web server and reverse proxy for most Tor hidden services. Proper Nginx configuration prevents information leakage, implements rate limiting to defend against abuse, and sets security headers appropriate for the onion environment. This guide covers production Nginx hardening for hidden services.

Need this done for your project?

We implement, you ship. Async, documented, done in days.

Start a Brief

Binding Nginx to Localhost Only

Nginx for a hidden service must listen only on localhost (127.0.0.1) or on Unix sockets - never on public IPs. In your Nginx server block: listen 127.0.0.1:80; (not listen 0.0.0.0:80;). Using Unix sockets is even better: listen unix:/run/nginx/hidden-site.sock;. In your Tor torrc: HiddenServicePort 80 unix:/run/nginx/hidden-site.sock. Unix sockets are faster than localhost TCP (no TCP overhead) and more secure (filesystem permission-controlled access). Verify binding after configuration: ss -tlnp | grep nginx should show only 127.0.0.1:80 or the Unix socket path, no 0.0.0.0 or public IPs.

Security Headers for Onion Sites

Hidden service security headers differ from clearnet sites because HTTPS is implicit (traffic is encrypted by Tor). Set: add_header X-Content-Type-Options nosniff always; (prevents MIME-type sniffing). add_header X-Frame-Options DENY always; (prevents clickjacking). add_header X-XSS-Protection '1; mode=block' always; (legacy XSS filter). add_header Referrer-Policy 'no-referrer' always; (prevents referrer leakage). For Content-Security-Policy: configure carefully to prevent loading external resources that could leak the user's location or deanonymize them. default-src 'self'; prevents all external resource loading. script-src 'self' 'nonce-RANDOM'; with per-request nonces prevents inline script injection.

Rate Limiting to Prevent Abuse

Rate limiting protects hidden services from scraping, DoS, and brute-force attacks. Nginx rate limiting via limit_req_zone: define zone in http context: limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s; Apply to location: limit_req zone=api_limit burst=20 nodelay; For login endpoints: limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m; This limits login attempts to 5 per minute per IP (useful against password brute force). For Tor hidden services: the 'IP address' of all Tor clients appears as 127.0.0.1 (they connect through the Tor process on localhost). Rate limiting by IP is therefore ineffective - all users appear from the same IP. Use session-based or token-based rate limiting in the application layer instead of Nginx IP-based rate limiting for hidden services.

Removing Information-Leaking Headers

Nginx default configuration reveals version information. Remove it: server_tokens off; (removes version from Server header and error pages). Additionally remove: add_header Server ''; or use nginx_more_headers module to set a custom Server header (Server: nginx works, or remove it entirely). Remove X-Powered-By if your application framework sets it (in PHP-FPM: fastcgi_hide_header X-Powered-By;). Check all response headers for information leakage: curl -I http://127.0.0.1/ from the server itself to see what headers are returned. Every revealed version number is a potential vulnerability targeting vector. Attackers scanning for vulnerable software versions need server/version information to target attacks.

Connection Limits and Slow Client Protection

Nginx handles slow HTTP attacks (Slowloris) and connection floods with: limit_conn_zone $binary_remote_addr zone=conn_limit:10m; in http context. Apply: limit_conn conn_limit 20; (maximum 20 simultaneous connections per IP). Again, for hidden services all connections appear from 127.0.0.1, so IP-based connection limits do not work. Use: limit_conn_zone $server_name zone=server_limit:10m; limit_conn server_limit 1000; (total server connection limit). For slow client attacks: client_body_timeout 10; client_header_timeout 10; keepalive_timeout 65; send_timeout 10; These timeouts disconnect clients that do not send or receive data within the timeout period, freeing connections from slow or malicious clients.

Why Anubiz Host

100% async — no calls, no meetings
Delivered in days, not weeks
Full documentation included
Production-grade from day one
Security-first approach
Post-delivery support included

Ready to get started?

Skip the research. Tell us what you need, and we'll scope it, implement it, and hand it back — fully documented and production-ready.

Anubiz Chat AI

Online