Support changing admin bind address to something else than $FTLCONF_LOCAL_IPV4

When using the docker image in host networking mode (as documented here), lighttpd is automatically configured to listen on $FTLCONF_LOCAL_IPV4 (if it is set) and there seem to be no other way to change this behaviour than to manually change lighttpd.conf.

I would like to change the bind address of lighttpd so it can serve traffic from other interfaces than my main lan (a docker bridged network specifically), however setting $FTLCONF_LOCAL_IPV4 to 172.17.0.1 or even 0.0.0.0 is not an option since this value is also used to set the pi-hole's own IP on the network (dig pi.hole would also return 0.0.0.0).

So it seems like the meaning of $FTLCONF_LOCAL_IPV4 is overloaded and is used to represent two different values. Could we introduce another configuration variable (eg. $WEB_BIND_ADDR, similar to the existing $WEB_PORT) to control lighttpd's bind address separately from $FTLCONF_LOCAL_IPV4? When unset, this variable could default to $FTLCONF_LOCAL_IPV4 to maintain backward compatibility.

I could give a shot at a PR if this sounds like a worthwhile feature. :slight_smile:

Would Pi-hole's optional environment variable VIRTUAL_HOST meet your requirement?

Variable Default Value Description
VIRTUAL_HOST $FTLCONF_LOCAL_IPV4 <Custom Hostname> What your web server 'virtual host' is, accessing admin through this Hostname/IP allows you to make changes to the whitelist / blacklists in addition to the default 'http://pi.hole/admin/' address

I don't think so, lighttpd still wouldn't listen on other addresses than my main one, so it wouldn't even receive requests coming from the docker bridge network, no matter which Host value they use.

lighttpd binds the wildcard address by default:

$ sudo ss -tulpn src :80
Netid  State   Recv-Q  Send-Q   Local Address:Port     Peer Address:Port
tcp    LISTEN  0       1024           0.0.0.0:80            0.0.0.0:*      users:(("lighttpd",pid=592,fd=4))
tcp    LISTEN  0       1024              [::]:80               [::]:*      users:(("lighttpd",pid=592,fd=5))

Note that VIRTUAL_HOST defaults to $FTLCONF_LOCAL_IPV4.

I'd give changing it to your aspired IP address a try. :wink:

It looks like $FTLCONF_LOCAL_IPV4 is also the value returned by the DNS resolver for the pi-hole host.

When I unset $FTLCONF_LOCAL_IPV4 and run dig pi.hole, it returns:

[...]
;; ANSWER SECTION:
pi.hole.		0	IN	A	0.0.0.0
[...]

Similarly, with $FTLCONF_LOCAL_IPV4=172.17.0.1 (docker network IP address), it returns:

[...]
;; ANSWER SECTION:
pi.hole.		0	IN	A	172.17.0.1
[...]

In both cases it does allow hosts on the docker bridged network to connect to Pi-hole (so initial problem is solved!) but then the DNS side breaks and I can't connect to the Pi-hole host using a domain name anymore.

You're right that lighttpd binds on wildcard by default, except in one case: when --net=host and $FTLCONF_LOCAL_IPV4 is set (which is my use case). This is currently implemented here, I did a bit of digging to understand why this was needed and found issue #154 and pr #155 which provided the original implementation. The use case at the time was to be able to limit which interfaces pi-hole would bind on on a host with multiple interfaces. The decision at the time was to use $ServerIP (ancestor of $FTLCONF_LOCAL_IPV4 I guess?), which I think is wrong in retrospect as this variable already had a different meaning.

Hence why I think this variable should be "split" in two as it tries to represent two (maybe more?) fundamentally different values (listen address for the admin and IP of the Pi-hole host).

I'm relatively new to Pi-hole so I'm probably missing something else. Thanks for your help @Bucking_Horn! :slight_smile:

Just to be sure I understand your issue:

  • Your Pi-hole is running on Docker on a host with a single network interface (or multiples?).
  • Your Pi-hole host has several IP addresses, attached to one of its network interfaces (or to separate different ones?)
  • You want your Pi-hole container to accept DNS request via a given single IP?
  • You want your Pi-hole container to accept HTTP requests via another given single IP, which is different from the IP used for DNS services?

Is this about right?

Your actual host configuration detailing the IPs and network interfaces may help to better understand your configuration. :wink:

TBH, this is probably not a bad idea. I think the who lighttpd binding section could do with looking at

I could give a shot at a PR if this sounds like a worthwhile feature. :slight_smile:

Feel free, we don't bite!

My host has several interfaces but, to simplify, the two that matter to this discussion are:

  • eth0: IP is something like 10.0.0.10, that's the physical link to my home lan
  • docker0: IP is 172.17.0.1, that's the virtual interface to the docker bridged network.

I mainly want my Pi-hole container to accept DNS requests from the eth0 interface (10.0.0.10). This works well. Looks like, by default, FTL binds to 0.0.0.0. :+1:

Exactly! I need Pi-hole to accept HTTP requests from the docker0 interface (172.17.0.1), I don't care too much whether it also accepts requests from eth0. So binding to either 0.0.0.0 or 172.17.0.1 would be an option for me, unfortunately doing so breaks the DNS side as I explained previously.

Hope that clarifies it. :slight_smile:

Great! I'll look into it this week-end and take a look at the lighttpd binding section at the same time.

I'm not sure if this would be helpful in your specific case, but did you try a different network mode, like mavlan?

Using macvlan the container would have it's own IP (10.0.0.50 for example) and no port forwarding. Every device on the network would see Pi-hole container as another machine on the same network. The DNS would be at 10.0.0.50:53 and the web interface at 10.0.0.50.

I haven't tried macvlan no, would that allow another container running in a bridge network on the same host to connect to pi-hole? Sounds like pointing the other container to Pi-hole's IP might just work.
I'm also using Pi-hole as a DHCP server, I assume that's not an issue with macvlan networking? I just went with the "simplest way to get DHCP working" in the docs. :slight_smile:

Thanks for the recommendation @rdwebdesign! looks like I have some reading to do...

I opened a PR to add support for $WEB_BIND_ADDR here: Add support for changing admin bind address indepentendly of $FTLCONF_LOCAL_IPV4 by n6g7 · Pull Request #1293 · pi-hole/docker-pi-hole · GitHub

Yes. It would work as if Pi-hole was on a different machine, with a different IP.

Containers using bridge/host network will still use the same DNS server used by the host. If the host uses Pi-hole as DNS server, then these containers will use it as well.

Would be nice if someone could expand this for IPv6 that I am not forced to use this dirty little thing anymore in my docker-compose file:

entrypoint: /bin/bash -c 'sed -i "s/\[::\]/[fd00::xxxx:yyyy::zzzz]/" /usr/share/lighttpd/use-ipv6.pl ; /s6-init'

Otherwise the Pi-hole Webadmin will bind to every IPv6 Interface which it can find on the system while using Dockers host network mode.

There is already an old bug report on Github for this problem/request but I cannot find it...

Ah, there is this PR which I've been putting off looking at because IPv6 confuses me, and it was an old PR with merge conflicts anyway.

Looks like stalebot took it out of action

If you want to take a stab at fixing it, please be my guest - I'll try to review quicker, but we might have to take it on faith because IPv6 confuses the hell out of me.

Edit: I've also pinged the OP of that PR to see if they want to bring it up to date