My Reverse Proxy with Raspberry 3B, Raspian Bullseye, NGINX
© Dr.-Ing. Rainer Knausenberger, March 2023

The use of a Reverse Proxy (based on a Raspberry 3B with Raspian Bullseye and NGINX installed) is a very user friendly solution, which is realizable with little financial and time consuming efforts.

What is the reason for using a Reverse Proxy?

From Wikipedia, the free encyclopedia

In computer networks, a reverse proxy is the application that sits in front of back-end applications and forwards client (e.g. browser) requests to those applications. Reverse proxies help increase scalability, performance, resilience and security. The resources returned to the client appear as if they are originated from the web server itself.[1]

Large websites and content delivery networks use reverse proxies, together with other techniques, to balance the load between internal servers. Reverse proxies can keep a cache of static content, which further reduces the load on these internal servers and the internal network. It is also common for reverse proxies to add features such as compression or TLS encryption to the communication channel between the client and the reverse proxy.[2]

Reverse proxies are typically owned or managed by the web service, and they are accessed by clients from the public Internet. In contrast, a forward proxy is typically managed by a client (or their company) who is restricted to a private, internal network, except that the client can ask the forward proxy to retrieve resources from the public Internet on behalf of the client.

Reverse proxy servers are implemented in popular open-source web servers such as ApacheNginx, and Caddy. This software can inspect HTTP headers, which, for example, allows it on a single IP address to relay requests to different internal servers based on the domain name of the HTTP request.

End of Wikipedia 

Die Verwendung eines Reverse-Proxy (basierend auf einem Raspberry 3b mit Raspian Bullseye und Nginx) ist eine sehr benutzerfreundliche, mit geringem finanziellen und zeitlichen Aufwand zu realisierende Lösung, da man sich als Anwender nicht um irgendwelche Ports kümmern muss. Ein weiterer Vorteil ist, dass auch der Windows-Server hinter dem Reverse-Proxy betrieben werden kann, dessen IIS-Zugangsports 80 und 443 nicht geändert werden dürfen, da sonst Funktionen „sterben“. Man sollte allerdings auf dem Reverse-Proxy und auf dem Windows-Server dasselbe Zertifikat verwenden. Der Windows-Server –unabhängig vom Einsatz eines Reverse Proxy, der dies ebenfalls tut – stellt jeden Webaufruf über HTTP auf HTTPS um. Da das Windows-Server-Zertifikat im .pfx-Format, das Zertifikat im Reverse Proxy aber im .pem-Format vorliegt, muss es ins .pfx-Format mittels OpenSSL konvertiert und dann in den Windows Server importiert werden. Diese Prozedur ist nicht aufwendig, muss aber für den Windows-Server nun quartalsweise statt vorher nur alle 2 Jahre durchgeführt werden.

Following domains are available via the Reverse Proxy with http (port 80) and https (port 443):

  • info (running IceWarp Mailserver, a php-system on Windows Server)
  • com (File-Server & Media-Center on Windows Home Server 2011, based on Windows Server 2008 R2)

Every access using http is redirected to https automatically.

 

Setup

For setup and configuration of the Raspberry 3B you need an OS on SD card. Use Raspberry Pi Imager and select RASPBERRY PI OS LITE (64 BIT). Then write image to SD Card.

Insert the SD card into the Raspberry, connect display, keyboard and mouse and also a network cable. After first startup open raspi-config for

  • change of the password for user ´pi´ (´12345RaspiUser´), -> menu item 1, then S3
  • change of hostname (´raspi-proxy´), -> menu item 1, then S4
  • selection of language, time zone, keyboard and WLAN Country, -> menu item 5
  • activate SSH and if needed VNC, -> menu item 3, then I2 (and/or I3)
    You can also use: sudo systemctl enable ssh

Now shutdown Raspberry (´shutdown´), then disconnect power supply, display, keyboard and mouse and finally start again with ethernet connected again. Further settings and installations can be done using Power ShellSSH´) from a Windows-Computer in LAN.

 

Setup static IP-Address under Raspian Bullseye (Debian 11):

Configure Static IP (optional). Alternatively you can also assign fixed IP address on your router.

First check the actual settings:

    ip addr show

   To change IP address from dhcp mode to static you need to do the following:
    - Login to raspi-proxy using these credentials:
       user: pi
       password: 12345RaspiUser (originally: raspberry)

    - Open file /etc/dhcpcd.conf (use nano or vim)
      Add at the end of the file:

  # RASPI-PROXY IP
  interface eth0
  static ip_address=10.163.54.50/24   <- your static IP address here
  static routers=10.163.54.1   <- your default gateway here
  static domain_name_servers=10.163.54.1 8.8.8.8   <- your domain name servers (DNS) here

Save the file using Strg-x and Y/J.
Reboot raspi-proxy.

The ethernet-interface name can be different from „eth0“ (i.e. for example „enxb827“). The given name has to be used!
The WiFi interface should be deactivated, because ist not needed in the Reverse Proxy.

    sudo ifconfig wlan0 down

The next steps I have taken from URL https://linuxize.com/post/secure-nginx-with-let-s-encrypt-on-debian-10/ (valid also for Debian 11):

- Begin of take over from linuxize.com –

This tutorial shows how to install a free Let’s Encrypt SSL certificate on Debian 10, Buster (Debian 11, Bullseye) running Nginx as a web server and Reverse Proxy. We’ll also show how to configure Nginx to use the SSL certificate and enable HTTP/2.

Prerequisites

Ensure the following prerequisites are met before proceeding with the guide:

  • Logged in as root or user with sudo privileges.
  • The domain for which you want to obtain the SSL certificate must point to your public server IP. We’ll use com.
  • Nginx installed. (Installation directions you get by pointing with mouse over to beginning of this line and then pressing [Strg]+[Left mouse button].

Installing Certbot

We’ll use the certbot tool to obtain and renew the certificates.

Certbot is a fully-featured and easy to use tool that automates the tasks for obtaining and renewing Let’s Encrypt SSL certificates and configuring web servers to use the certificates.

The certbot package is included in the default Debian repositories. Run the following commands to install certbot:

sudo apt updatesudo apt install certbot

Generating DH (Diffie-Hellman) Group

Diffie–Hellman key exchange (DH) is a method of securely exchanging cryptographic keys over an unsecured communication channel.

We’re going to generate a new set of 2048 bit DH parameters to strengthen the security:

sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048

You can also change the size up to 4096 bits, but the generation may take more than 30 minutes depending on the system entropy.

Obtaining a Let’s Encrypt SSL certificate

To obtain an SSL certificate for the domain, we’re going to use the Webroot plugin. It works by creating a temporary file for validating the requested domain in the ${webroot-path}/.well-known/acme-challenge directory. The Let’s Encrypt server makes HTTP requests to the temporary file to validate that the requested domain resolves to the server where certbot runs.

We’re going to map all HTTP requests for .well-known/acme-challenge to a single directory, /var/lib/letsencrypt.

Run the following commands to create the directory and make it writeable for the Nginx server:

sudo mkdir -p /var/lib/letsencrypt/.well-known
sudo chgrp www-data /var/lib/letsencrypt
sudo chmod g+s /var/lib/letsencrypt

To avoid duplicating code, we’ll create 3 snippets that will be included in all Nginx server block files.

Open your text editor and create the first snippet, letsencrypt.conf:

sudo nano /etc/nginx/snippets/letsencrypt.conf

/etc/nginx/snippets/letsencrypt.conf

location ~ /.well-known/acme-challenge/ {
  allow all;
  root /var/lib/letsencrypt/;
  default_type "text/plain";
  try_files $uri =404;
}

The second snippet ssl.conf includes the ciphers recommended by Mozilla, enables OCSP Stapling, HTTP Strict Transport Security (HSTS), and enforces few security‑focused HTTP headers.

sudo nano /etc/nginx/snippets/ssl.conf

/etc/nginx/snippets/ssl.conf

ssl_dhparam /etc/ssl/certs/dhparam.pem; 

ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;

ssl_protocols
TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;

# ssl_stapling
on;
# ssl_stapling_verify on;

resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 30s; 

add_header Strict-Transport-Security "max-age=63072000" always;
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;

The third snippet sockets.conf contains all orders and definitions needed for WinSockets.

/etc/nginx/snippets/sockets.conf

    proxy_http_version  1.1;
   proxy_cache_bypass  $http_upgrade;
 

   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_set_header X-Forwarded-Host  $host;
   proxy_set_header X-Forwarded-Port  $server_port;

Once done, open the domain server block file and include the letsencrypt.conf snippet as shown below:

sudo nano /etc/nginx/sites-available/example.com.conf

/etc/nginx/sites-available/example.com.conf

server {
  listen 80;
  listen [::]:80;
  server_name knausir.com www.knausir.com;

  include snippets/letsencrypt.conf;
}

Create a symbolic link to the sites-enabled directory to enable the domain server block:

sudo ln -s /etc/nginx/sites-available/example.com.conf /etc/nginx/sites-enabled/

Restart the Nginx service for the changes to take effect:

The file example.com.conf must contain a valid domain name (here knausir.com) for testing. Otherwise you will get an error.

sudo systemctl restart nginx
sudo systemctl status nginx.service

You’re now ready to obtain the SSL certificate files by running the following command:

sudo certbot certonly --agree-tos --email Diese E-Mail-Adresse ist vor Spambots geschützt! Zur Anzeige muss JavaScript eingeschaltet sein! --webroot -w /var/lib/letsencrypt/ -d example.com -d www.example.com