Setup Nginx Reverse Proxy and Force HTTP to HTTPS Redirect
Introduction
Nginx is a powerful, high-performance web server and reverse proxy. While its primary goal is serving static content, it is frequently used as a reverse proxy to sit in front of application servers (like Python/Django, Node.js, or Go) to handle incoming traffic, load balancing, and SSL termination.
In this tutorial, we will configure Nginx as a reverse proxy for a web application running on port 8000. We will also secure the traffic by generating a self-signed SSL certificate and forcing a redirect from HTTP to HTTPS using HSTS (HTTP Strict Transport Security) principles.
Step 1: Install Nginx
First, ensure your package manager is up to date and install the web server.
Update package index:
xinit@localhost:~$ sudo apt update
Install Nginx from the official repositories:
xinit@localhost:~$ sudo apt install nginx -y
Step 2: Configure firewall
If you are using UFW (Uncomplicated Firewall), you need to allow traffic on both HTTP (port 80) and HTTPS (port 443). Nginx provides a profile for this.
Allow Nginx full access:
xinit@localhost:~$ sudo ufw allow 'Nginx Full'
Step 3: Generate SSL certificate
For this tutorial, we will create a self-signed certificate. This is useful for testing, development environments, or internal services.
Important Note: Self-signed certificates will cause "Privacy Error" warnings in browsers because they are not signed by a trusted Certificate Authority. For a production website accessible to the public, you should use a trusted certificate.
For instructions on obtaining a free trusted certificate, see: How to Secure Nginx with Let's Encrypt on Debian and Ubuntu.
If you still wish to proceed with a self-signed certificate for testing purposes, use OpenSSL.
Generate the certificate and key (valid for 365 days):
xinit@localhost:~$ sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/nginx-selfsigned.key -out /etc/ssl/certs/nginx-selfsigned.crt
The command will ask for details like Country, State, and Organization. You can fill them in or leave them blank, but ensure the Common Name (CN) matches your server's IP address or domain name.
Step 4: Configure Nginx as reverse proxy
Now we will create a configuration file that does two things:
- Redirects all unencrypted HTTP traffic to HTTPS.
- Proxies the secure HTTPS traffic to your backend application running on localhost:8000.
Create a new configuration file for your project:
xinit@localhost:~$ sudo nano /etc/nginx/sites-available/your-project.com
Add the following configuration (pay attention to the comments explaining the parameters):
server {
# Block for handling standard HTTP traffic (Port 80)
listen 80;
server_name your-project.com www.your-project.com;
# Force redirect all traffic to HTTPS
# 301 Moved Permanently is best for SEO and caching
return 301 https://$host$request_uri;
}
server {
# Block for handling HTTPS traffic (Port 443)
listen 443 ssl;
server_name your-project.com www.your-project.com;
# SSL Configuration
# Paths must match the files we generated in Step 3
ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;
# Reverse Proxy Configuration
location / {
# Pass the request to the application server (e.g., Gunicorn/Django)
proxy_pass http://localhost:8000;
# Forward original client headers to the application
# This is crucial for the app to know the real client IP and protocol
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;
}
}
Save and close the file.
Step 5: Enable configuration
To enable the site, create a symbolic link from sites-available to sites-enabled.
Link the configuration file:
xinit@localhost:~$ sudo ln -s /etc/nginx/sites-available/your-project.com /etc/nginx/sites-enabled/
Before restarting, always check the Nginx configuration for syntax errors.
Test Nginx configuration:
xinit@localhost:~$ sudo nginx -t
You should see an output confirming the syntax is "ok" and the test is "successful".
Restart Nginx to apply changes:
xinit@localhost:~$ sudo systemctl restart nginx
Conclusion
Your Nginx server is now configured. When you visit your domain via http://, you will be automatically redirected to https://.
Since we used a self-signed certificate, your browser will display a warning (e.g., "Your connection is not private"). This is expected behavior. You can click "Advanced" and "Proceed" to access your site. For public users, remember to replace this with a Let's Encrypt certificate as mentioned in Step 3.