Raspberry Pi Reverse Proxy with NGNIX and Letsencrypt SSL Encryption

Photo by Yannick Pipke on Unsplash

One IP address and many or sometimes too may websites hosted on your environment comes with the problem “How to uses standard SSL / HTTPs or HTTP for all of these instead of custom TCP Ports?”. A Raspberry Pi (B3+) in my case Reverse Proxy provide excellent solution to the problem . It is easy to manege Secured by Lets encrypt SSL and energy efficient.

To begin with lets just update the Raspbian to the latest version .

sudo apt update
sudo apt upgrade

Next step is install NGINX on Pi and verify the installed version

sudo apt install nginx
pi@raspberrypi:~ $ sudo nginx -v
nginx version: nginx/1.14.2

Install the certbot for NGINX

sudo apt install python-certbot-nginx

Before proceeding to next step please make sure the raspberry pi is running on static IP and your firewall or router is forwarding the ports TCP/80 and TCP/443 to that IP. Assuming that the domain which will be proxied is already setup to the IP address of your router /firewall. In case of dynamic DNS please refer to the previous post https://www.affan.info/google-domain-ddns-raspberry-pi-or-linux-systems/. Certbot need bot port 80 and 443 to be redirected to the NGINX web server . Once this is done move to next step creation of SSL certificate for the domain.

sudo certbot --nginx --domain demo2.affan.info

Follow the instructions on the console and create the certificate. Next step is to create a NGINX configuration for your website and attach the SSL certificate generated above with it.Verify the certificates created.

pi@raspberrypi:~$ sudo ls /etc/letsencrypt/live/demo1.affan.info/
cert.pem chain.pem fullchain.pem privkey.pem README

Create a configuration file for NGINX in sites-available directory .

sudo vi /etc/nginx/sites-available/demo1.affan.info.conf

Create the following configuration in the above file and assign the ssl_certificate and ssl_certificate_key parameters. Set the internal IP address for the web server where website is hosted.

server {
listen 80;
listen 443 ssl;
server_name demo1;
index index.php index.html index.html; #Depend on your Webserver
#ssl on;
ssl_certificate /etc/letsencrypt/live/demo1/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/demo1/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
location / {
proxy_set_header Host $http_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-Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://10.10.0.11; # Internal IP of web server
}
}

Save the config file and create the link in Sites-enabled directory for NGINX.

sudo ln -s /etc/nginx/sites-available/demo1.affan.info.conf /etc/nginx/sites-enabled/demo1.affan.info.conf

Test NGINX Configuration and Reload id test is ok

pi@raspberrypi:~$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
pi@raspberrypi:~$ sudo nginx -s reload

Check your website form WAN to make sure everything works. I have run Raspberry-pi B3+ using Ethernet connection to host 5 Websites including a nextcloud instance and depending on internet connection it works fine.

IT Infrastructure Specialist , Open-source enthusiast

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store