Nginx Reverse Proxy with SSL Termination
Configure Nginx as a reverse proxy with free Let's Encrypt SSL certificates. Covers installation, proxy configuration, SSL setup, and common patterns.
Nginx Reverse Proxy with SSL Termination
Nginx is the go-to reverse proxy for routing traffic to backend services with SSL termination. This guide sets up Nginx with free Let's Encrypt certificates.
Prerequisites
- Ubuntu/Debian server with a public IP
- A domain name pointing to your server
- Backend service running (e.g., on port 3000)
Step 1: Install Nginx
sudo apt update
sudo apt install nginx
sudo systemctl enable nginxStep 2: Basic Reverse Proxy Config
Create /etc/nginx/sites-available/myapp:
server {
listen 80;
server_name myapp.example.com; location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
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;
proxy_cache_bypass $http_upgrade;
}
}
sudo ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginxStep 3: Install Let's Encrypt SSL
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d myapp.example.comCertbot will automatically:
- Obtain the certificate
- Modify your Nginx config to use SSL
- Set up auto-renewal
Verify auto-renewal:
sudo certbot renew --dry-runStep 4: Optimized SSL Config
After Certbot runs, enhance the SSL settings:
server {
listen 443 ssl http2;
server_name myapp.example.com; ssl_certificate /etc/letsencrypt/live/myapp.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/myapp.example.com/privkey.pem;
# Strong SSL settings
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
# Security headers
add_header Strict-Transport-Security "max-age=63072000" always;
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
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;
}
}
Redirect HTTP to HTTPS
server {
listen 80;
server_name myapp.example.com;
return 301 https://$host$request_uri;
}Step 5: Common Patterns
Multiple backends:
location /api/ {
proxy_pass http://127.0.0.1:4000/;
}location / {
proxy_pass http://127.0.0.1:3000;
}
Load balancing:
upstream backend {
server 127.0.0.1:3001;
server 127.0.0.1:3002;
server 127.0.0.1:3003;
}server {
location / {
proxy_pass http://backend;
}
}
WebSocket support:
location /ws {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 86400;
}Troubleshooting
# Test config
sudo nginx -tCheck error logs
sudo tail -f /var/log/nginx/error.logCheck access logs
sudo tail -f /var/log/nginx/access.logCommon issue: 502 Bad Gateway = backend is down
Common issue: 504 Gateway Timeout = backend too slow
Conclusion
Nginx reverse proxy with SSL is the foundation of modern web hosting. With this setup, you can securely expose any number of backend services through a single server with free SSL certificates that auto-renew.