What's the right way to "expose" v6 beta via swag (nginx reverse proxy)?

First of all:

  • pihole is completely firewalled: ports 53 and 5335 (unbound) are NOT forwarded / accessible to/from WAN.
  • access to the pihole subdomain is only allowed for LAN-IPs
  • access to the login is protected via authelia (only allowed for LAN)
  • the only forwarded ports are 80, 443 to the rev. proxy
  • the domain is redirected via unbound(localhost) to the servers LAN-IP (NOT public IP)
  • only used for local dns, but I'd like to be able to use a domain

I'm currently testing v6 beta but I'm not quite sure if my proxy config is correct this way...

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    server_name pihole.*;

    include /config/nginx/ssl.conf;> 
    client_max_body_size 0;
	
    if ($lan-ip = yes) { set $geo-whitelist yes; }
    if ($geo-whitelist = no) { return 404; }

    # enable for Authelia (requires authelia-location.conf in the location block)
    include /config/nginx/authelia-server.conf;

    location = / {
        # enable for Authelia (requires authelia-server.conf in the server block)
        include /config/nginx/authelia-location.conf;

        include /config/nginx/proxy.conf;
        include /config/nginx/resolver.conf;
		
        set $upstream_app pihole;
        set $upstream_port 80;
        set $upstream_proto http;
        proxy_pass $upstream_proto://$upstream_app:$upstream_port/admin;
    }
	
	location /admin {
        include /config/nginx/proxy.conf;
        include /config/nginx/resolver.conf;
		
        set $upstream_app pihole;
        set $upstream_port 80;
        set $upstream_proto http;
        proxy_pass $upstream_proto://$upstream_app:$upstream_port;
    }
	
	location /api {
        include /config/nginx/proxy.conf;
        include /config/nginx/resolver.conf;
		
        set $upstream_app pihole;
        set $upstream_port 80;
        set $upstream_proto http;
        proxy_pass $upstream_proto://$upstream_app:$upstream_port;
	}
}

Is it okay to do it like that? With this config the UI is fully functional, but I'm afraid I'm exposing too many locations.
I'm still learning about rev. proxy configs... An official config would be much appreciated!

Thanks a lot!

I'm not nginx expert but to me it looks like

isn't fully true, you are only prxying port 80 and nginx does the TLS (443) for you, right?

You will only have to allow /admin and /api, no need for /

Actually I've forwarded 80 and 443 from the router to the rev. proxy server so I can access other services directly via https, but I'm redirecting everything to https in the default server block, too:

# redirect all traffic to https
server {
    listen 80 default_server;
    listen [::]:80 default_server;

    server_name _;

    if ($lan-ip = yes) { set $geo-whitelist yes; }
    if ($geo-whitelist = no) { return 404; }

    location / {
        return 301 https://$host$request_uri;
    }
}
location = / {
    ....
    proxy_pass $upstream_proto://$upstream_app:$upstream_port/admin;
}

Is just used to "redirect" the domain to the actual pihole-GUI .../admin.
Because of the " = " after "location" this block is only executed if the domain root is requestet (if I understood that right). Otherwise I'm stuck in a loop ("too many redirections").

Is there a way to make the GUI accessible at / (and not /admin) via pihole settings ?

I found in Github a comment about a similar issue (reverse proxy and redirecting to /admin).

That issue is about Pi-hole v5 and Caddy, but the last comment has a suggestion for nginx.

Maybe it could help you finding a solution:
https://github.com/pi-hole/pi-hole/issues/5306#issuecomment-2159219680

1 Like

Thanks for those links. I actually learned some neat tricks there, but no foolproof answer to my rev. proxy question... :smiley:

Still using this Nginx-Config for Pihole v6 beta and until now everything is working fine...

"dns" is locally resolved to x.x.x.254 which is shared by 2 different piholes via keepalived.
Works quite nice..

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    http2 on;

    server_name dns.*;

    include /config/nginx/ssl.conf;

    client_max_body_size 0;
	
    if ($lan-ip = yes) { set $geo-whitelist yes; }
    if ($geo-whitelist = no) { return 404; }

    # enable for Authelia (requires authelia-location.conf in the location block)
    include /config/nginx/authelia-server.conf;
	
	location = / {
        # enable for Authelia (requires authelia-server.conf in the server block)
        include /config/nginx/authelia-location.conf;

        include /config/nginx/proxy.conf;
        include /config/nginx/resolver.conf;
		
        set $upstream_app dns;
        set $upstream_port 80;
        set $upstream_proto http;
        proxy_pass $upstream_proto://$upstream_app:$upstream_port/admin;
    }
	
	location /admin {
        # TODO: check, ob Authelia schläft, wenn's exakt nur im root Block gelistet is ..
        include /config/nginx/authelia-location.conf;

        include /config/nginx/proxy.conf;
        include /config/nginx/resolver.conf;
		
        set $upstream_app dns;
        set $upstream_port 80;
        set $upstream_proto http;
        proxy_pass $upstream_proto://$upstream_app:$upstream_port;
    }
	
	location /api {
        include /config/nginx/proxy.conf;
        include /config/nginx/resolver.conf;
		
        set $upstream_app dns;
        set $upstream_port 80;
        set $upstream_proto http;
        proxy_pass $upstream_proto://$upstream_app:$upstream_port;
	}
	
	 # deny access to .htaccess/.htpasswd files
    location ~ /\.ht {
        deny all;
    }
}