PiHole – Nginx reverse proxy virtual host configuration

descriptionStandard

This post contains a PiHole virtual host configuration for Nginx that uses Nginx as a reverse proxy to connect to a PiHole instance.

What does this configuration do?

This nginx configuration sets up the following:

  • A server block is configured to listen on port 80 and redirects all incoming requests to the same URL but with HTTPS (port 443).
  • Another server block is defined to listen on port 443 with SSL enabled.
  • The SSL certificate and key paths are specified.
  • TLS protocols 1.2 and 1.3 are allowed, and a specific set of SSL ciphers is chosen.
  • The server prefers the server ciphers over the client ciphers.
  • The location block is set up to handle requests for the root (“/”) URL path.
  • It proxies the requests to the internal IP address of a Pi-hole server, specifically to the “/admin/” path.
  • Various proxy headers are set in order to pass along client information.
  • The X-Frame-Options header is hidden and then set to “SAMEORIGIN” to prevent clickjacking attacks.
  • Proxy SSL session reuse is enabled.
  • The proxy_ssl_name directive specifies the domain name used for SSL/TLS handshakes.
  • The proxy_http_version is set to 1.1 and the Upgrade and Connection headers are set to allow for HTTP/2 protocol and WebSocket upgrades.
  • There is an additional location block for requests made to the “/admin” path, which redirects them to the root URL of the same domain using HTTPS.

Nginx site configuration

Ensure you update and replace the following:

  • <domain-name> with the domain name you are targeting.
  • <pihole-internal-ip> the IP address for the device running PiHole (this should be an internal IP).
  • ssl_certificate should be the Private certificate and Certificate Authority pairs combined (if required).
  • ssl_certificate_key should be the path to the required SSL key (if required).
server {
    listen 80;
    server_name <domain-name>;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl;
    server_name <domain-name>;
    listen [::]:443 ssl;

    ssl_certificate /var/certs/<ca-cert-with-site-cert-combined>.crt;
    ssl_certificate_key /var/certs/<cert-key>.key;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;

    location / {
        proxy_pass http://<pihole-internal-ip>/admin/;
        proxy_redirect    off;
        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_hide_header X-Frame-Options;
        proxy_set_header X-Frame-Options "SAMEORIGIN";

        proxy_ssl_session_reuse on;
        proxy_ssl_name <domain-name>;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }

    location /admin {
        rewrite ^/admin(.*)$ https://<domain-name>/$1 redirect;
    }

}