Reverse Proxy Nginx - sparkycz1/honeypot-shelf GitHub Wiki
🔒 Reverse proxy: nginx
Already run nginx? It can front this too — it just needs to know about WebSockets.
Use this if you already run nginx on the host where Honeypot Shelf's
docker compose up -d --build (the base file, without
docker-compose.caddy.yml) is running, exposing the app on
127.0.0.1:8080 (or whatever APP_PORT you set). Once working, consider
also setting APP_BIND_ADDRESS=127.0.0.1 (no docker-compose.yml edit
needed) so the app is only reachable through this proxy.
✅ Prerequisites
- A certificate for your domain. Easiest via
certbot (webroot or nginx plugin). HTTP/3
additionally requires nginx built with
--with-http_v3_module— check withnginx -V 2>&1 | grep -o with-http_v3_module. This ships in nginx mainline releases; some distro-packaged builds omit it, in which case TLS 1.3 over HTTP/2 (below, without the HTTP/3 section) works fine and is much simpler to set up.
⚙️ Base config: TLS 1.3 only, reverse proxy to Honeypot Shelf
server {
listen 80;
listen [::]:80;
server_name your-domain.example.com;
# For certbot's HTTP-01 challenge.
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
server_name your-domain.example.com;
ssl_certificate /etc/letsencrypt/live/your-domain.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your-domain.example.com/privkey.pem;
# Only TLS 1.3 — no 1.2/1.1/1.0 fallback.
ssl_protocols TLSv1.3;
server_tokens off;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer" always;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Reload nginx after installing this:
sudo nginx -t && sudo systemctl reload nginx
🚀 Optional: adding HTTP/3
Only if your nginx build includes the QUIC/HTTP-3 module. Add to the HTTPS server block:
server {
listen 443 ssl;
listen [::]:443 ssl;
listen 443 quic reuseport;
listen [::]:443 quic reuseport;
http2 on;
http3 on;
quic_retry on;
add_header Alt-Svc 'h3=":443"; ma=86400' always;
# ... rest of the block as above ...
}
The Alt-Svc header is what tells browsers an HTTP/3 endpoint is
available so they can upgrade on a subsequent request. Directive names
for QUIC/HTTP-3 have shifted across nginx releases — if http3 on; isn't
recognized, check nginx -v and the changelog for your specific version.
🔎 Verifying
curl -sIv https://your-domain.example.com/healthz 2>&1 | grep -Ei 'HTTP/|strict-transport|server:'
openssl s_client -connect your-domain.example.com:443 -tls1_2 </dev/null # should fail
openssl s_client -connect your-domain.example.com:443 -tls1_3 </dev/null # should succeed
🔄 Certificate renewal
If using certbot, its systemd timer/cron job handles renewal; add a post-renewal hook to reload nginx:
echo "systemctl reload nginx" | sudo tee /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh