Multiple websites on one IP address

How to Set Up a Raspberry Pi as a Reverse Proxy for Multiple Domains with SSL

A reverse proxy is a powerful way to route traffic for multiple websites hosted on different machines but accessible through a single public IP. In this guide, we’ll configure a Raspberry Pi to act as a reverse proxy, forwarding requests to different internal servers based on the requested domain name and using Let’s Encrypt SSL certificates for secure connections.


Use Case Example

  • Domain 1: domain1.com → Hosted on Server 1 (192.168.1.75)
  • Domain 2: domain2.com → Hosted on Server 2 (192.168.1.71)
  • Public IP: Same for both domains.

The Raspberry Pi will sit between the internet and your internal web servers to manage incoming requests and securely forward them to the correct backend server.







Step 1: Prerequisites

  1. Raspberry Pi:

    • A Raspberry Pi with Raspbian or Raspberry Pi OS installed.
    • Static internal IP for the Raspberry Pi (e.g., 192.168.1.100).
  2. Web Servers:

    • Two or more web servers running on different internal IPs:
      • Server 1: 192.168.1.75
      • Server 2: 192.168.1.71
  3. Domain Names:

    • Domains pointing to your home’s public IP via DNS.
  4. Router Configuration:

    • Forward port 80 (HTTP) and 443 (HTTPS) to your Raspberry Pi’s internal IP (192.168.1.100).

Step 2: Install Nginx and Certbot

  1. Update and install Nginx and Certbot:

    sudo apt update
    sudo apt install nginx certbot python3-certbot-nginx -y
    
  2. Enable and start Nginx:

    sudo systemctl enable nginx
    sudo systemctl start nginx
    

Step 3: Obtain SSL Certificates with Certbot

  1. Obtain SSL certificates for your domains using Certbot. This command automatically configures SSL for your Nginx server:

    For Domain 1:

    sudo certbot --nginx -d domain1.com -d www.domain1.com
    

    For Domain 2:

    sudo certbot --nginx -d domain2.com -d www.domain2.com
    
  2. Verify your domains in a browser to check that SSL is working properly:

    • Visit https://domain1.com and https://domain2.com. You should see a secure connection.

Step 4: Configure Nginx as a Reverse Proxy

  1. Navigate to the Nginx configuration directory:

    cd /etc/nginx/sites-available
    
  2. Create a new file for your reverse proxy configuration:

    sudo nano /etc/nginx/sites-available/reverse_proxy
    
  3. Add the following configuration to redirect HTTP to HTTPS and set up reverse proxy for both domains:

    # Redirect HTTP to HTTPS
    server {
        listen 80;
        server_name domain1.com www.domain1.com domain2.com www.domain2.com;
    
        return 301 https://$host$request_uri;
    }
    
    # Reverse Proxy for domain1.com
    server {
        listen 443 ssl;
        server_name domain1.com www.domain1.com;
    
        ssl_certificate /etc/letsencrypt/live/domain1.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/domain1.com/privkey.pem;
    
        location / {
            proxy_pass https://192.168.1.75;  # Forward to Backend Server 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;
        }
    }
    
    # Reverse Proxy for domain2.com
    server {
        listen 443 ssl;
        server_name domain2.com www.domain2.com;
    
        ssl_certificate /etc/letsencrypt/live/domain2.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/domain2.com/privkey.pem;
    
        location / {
            proxy_pass https://192.168.1.71;  # Forward to Backend Server 2
            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;
        }
    }
    
  4. Create a symbolic link to enable the configuration:

    sudo ln -s /etc/nginx/sites-available/reverse_proxy /etc/nginx/sites-enabled/
    
  5. Remove the default Nginx configuration:

    sudo rm /etc/nginx/sites-enabled/default
    

Step 5: Test and Restart Nginx

  1. Test the Nginx configuration to ensure there are no syntax errors:

    sudo nginx -t
    
  2. Restart Nginx to apply the changes:

    sudo systemctl restart nginx
    

Step 6: Configure DNS for Your Domains

  1. Go to your domain registrar’s DNS management panel.

  2. Add an A record for each domain, pointing to your public IP address:

    • domain1.comYour Public IP
    • domain2.comYour Public IP
  3. (Optional) Add CNAME records for subdomains (e.g., www.domain1.comdomain1.com).


Step 7: Verify Connectivity

  1. Test domain resolution using nslookup:

    nslookup domain1.com
    nslookup domain2.com
    

    Both domains should resolve to your public IP.

  2. Open a browser and test the domains:

    • Navigate to https://domain1.com.
    • Navigate to https://domain2.com.

Step 8: Troubleshooting

  • Issue: Default Nginx page appears for the second domain

    • Ensure the server_name values match the exact domain names.
    • Restart Nginx after any changes:
      sudo systemctl restart nginx
      
  • Issue: Traffic is not reaching your Raspberry Pi

    • Verify port 80 and 443 are forwarded to the Raspberry Pi’s internal IP in your router.
  • Issue: Logs show errors

    • Check Nginx logs for clues:
      sudo tail -f /var/log/nginx/access.log
      sudo tail -f /var/log/nginx/error.log
      

Step 9: Optional Enhancements

  • Automatic SSL Renewal: Certbot automatically sets up a cron job to renew SSL certificates. You can verify this by running:

    sudo certbot renew --dry-run
    
  • Monitor Traffic: Install monitoring tools like htop or ngxtop to analyze server performance and traffic.


Conclusion

By using Let’s Encrypt SSL certificates, your Raspberry Pi acts as a secure reverse proxy, forwarding traffic to backend servers based on domain names. This setup ensures that your websites are served over HTTPS with valid, trusted certificates and offers the flexibility to host multiple domains.

Enjoy your enhanced, secure, home-hosted web setup! 🚀


Comments

Popular posts from this blog

Tutorial: Using Raspberry Pi as an OpenVPN Client Router with Ethernet Sharing

How to Use a Raspberry Pi 4 as a Firewall to Block Adult Content and Protect Your Family

Tutorial: Using Raspberry Pi Pico and HW-488 Infrared Obstacle Avoidance Sensor to Play/Pause a Video on Your PC via USB