Running Pi-hole on Linux Router (RPi)

Hi All

I’m currently working on setting up an RPi to take over routing duties. I have two interfaces - eth0, with static IP of 192.168.0.1, which is the lan, and eth1, which is connected to DSL and manages the wan. The RPi is using firewalld for NAT and isc-dhcp-server for DHCP. eth1 is not running via another router, it’s connected to a modem in bridge mode.

Expected Behaviour:

When running the setup, when I select eth0 as the interface to listen on, it should pick up 192.168.0.1/24 as the IP. I’m not sure what the gateway would be as eth0 has no gateway - it handles internal lan traffic only.

Actual Behaviour:

When I select eth0 as the interface, the Pi-hole setup wants to use the wan IP on eth1 as the static IP. If I change the IP and set the gateway to 192.168.0.1, when setup completes, eth0 has lost the 192.168.0.1 IP and no clients on the lan can see the RPi. Removing Pi-hole and rebooting the Pi gives the IP back to eth0.

Debug Token:

No debug token as I’ve removed Pi-hole, and I’m assuming this is user error rather than a fault.

TIA

Si

Why? Is your current router not able to do this?

I’m in the UK with Sky.
The equipment they provide is poor. I’d also like to be able to monitor the bandwidth usage of each device on the network, and this is a much cheaper way to do it than purchasing an expensive prosumer piece of kit. Plus Sky don’t use standard authentication - they use DHCP option 61, which not all 3rd party routers support.
Plus I thought it would be an interesting project. I actually have the routing all working, it’s just adding Pi-hole into the mix that’s being a bit problematic.

What makes you expect that eth0 should pick up that IP address?
Did you set a static IP? Is there any DHCP server that would assign that IP to your RPi's eth0 interface?

If your RPi really is to become the router for devices connected to its eth0 interface, it should also be the gateway for those devices, unless you'd really want them to be restricted to local traffic exclusively. Without a gateway, devices would be restricted to link-local communications, i.e. they would not be able to access the internet

This isn't a Pi-hole issue:
For the most part, you'd have to figure your RPi's router side for yourself, i.e. you should find some tutorials about how to turn your RPi into a router.

Once you've succeeded in doing so, you can then try to install Pi-hole.
You'd likely have to find a way how to make pihole-FTL (Pi-hole's tailored dnsmasq variant) coexist with the DHCP server used by your router setup, as they would then be hosted on the same machine.
If that would happen to be dnsmasq as well, chances are that you may instead be able to replace that with pihole-FTL.

In any case, this would likely involve custom configuration of both your router's chosen DHCP server and pihole-FTL to some extent.

We may be able to supply some configuration hints if you provide us with respective details of your working(!) router configuration.

"What makes you expect that eth0 should pick up that IP address?
Did you set a static IP? Is there any DHCP server that would assign that IP to your RPi's eth0 interface?"
When I've setup Pi-hole in the past, the setup selects whatever static IP is assigned to the NIC that I select. isc-dchp-server is handing out the IPs on eth0, but I've never seen a DHCP install set up to provide an IP to itself - in all the examples I've seen the interface on the lan side is given a static IP in the network config (in the DHCP client config files).

"If your RPi really is to become the router for devices connected to its eth0 interface, it should also be the gateway for those devices, unless you'd really want them to be restricted to local traffic exclusively. Without a gateway, devices would be restricted to link-local communications, i.e. they would not be able to access the internet"
The lan is served by eth0. It handles local traffic only so has no gateway in the Pi. It is of course the gateway for any device connected on eth0 external to the Pi. There is only one default route on the Pi, which leads to the wan - any addresses in the 192.168 space have their own route set. The wan is on eth1. Flow between the two is handled by firewalld which provides the NAT. The routing currently is working without issue, as is DHCP and IP address assignment to client machines.

"You'd likely have to find a way how to make pihole-FTL (Pi-hole's tailored dnsmasq variant) coexist with the DHCP server used by your router setup"
Slightly confused here, as surely if I don't have DHCP enabled in Pi-hole, FTL / dnsmasq is not in play? At least for DHCP? Or does it provide other functionality?

Happy to post configs etc if that would make things easier to understand.

Almost - the setup doesn't apply that selection, it rather makes a proposition for that IP that a user can accept or reject to go forward with, and it only does so on Raspberry Pi OS.
Did you try both options?

(I'll add that older versions of Pi-hole indeed used dhcpcd as a dependency for all OSs, but that dependency has since been removed. Currently, configuring an on-device static IP is available as a convenience option on RPi OS only.
You haven't revealed details about your OS yet.)

It would help to know more details of your setup.

I don't know about your network. 'Static IP' may refer to an on-device configuration or a DHCP lease reservation for a static IP in a DHCP server somewhere on your network, which my questions sought clarification for.
Where is that DHCP server running?
It would help to know more details of your setup.

Does that mean you intend devices connected through eth0 to talk only to those other devices also connected through eth0?

If not, assuming that your eth0 link establishes a 192.168.0.0/24 subnet, its clients would need a respective route to reach any IP outside of that subnet - including the respective client IP of the Pi-hole host machine.
At least, Pi-hole's host should have a route to a public DNS server IP in order to forward non-blocked DNS requests.
It would help to know more details of your setup.

On one hand, I don't know where your DHCP server is located, or whether you've enabled Pi-hole's DHCP server, and whether you'd want them to coexist.
On the other hand, I am aware that some AP/router tutorials would use dnsmasq to provide DHCP services. As pihole-FTL is a drop-in replacement for dnsmasq, having those run in parallel would mean they may share the same configuration at /etc/dnsmasq.d/, which is bound to conflict.

Apologies - didn't get chance to pick this up again until now.
Networking in general isn't my strong point so I'll try and provide as much information as I can that seems it might be relevant.

The PI has two NICs - the build in ethernet, which is eth0, and handles the lan side of the network. The second NIC is a USB adapter - eth1 - which handles the wan via a connection to a DSL modem in bridge mode. The PI itself authenticates and obtains the wan IP.

This is the output of ifconfig for eth0 and eth1:

eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.0.1  netmask 255.255.255.0  broadcast 192.168.0.255
        inet6 xxxxxxx  prefixlen 64  scopeid 0x20<link>
        ether XX:XX:XX:XX:XX:XX  txqueuelen 1000  (Ethernet)
        RX packets 14010  bytes 1684344 (1.6 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 22796  bytes 26779794 (25.5 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 2.XXX.X.3  netmask 255.255.252.0  broadcast 2.XXX.X.255
        inet6 xxxxxxx  prefixlen 64  scopeid 0x20<link>
        ether XX:XX:XX:XX:XX:XX txqueuelen 1000  (Ethernet)
        RX packets 33160  bytes 41412493 (39.4 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 19050  bytes 2059954 (1.9 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

This is the routing table for the Pi:

Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         2.XXX.X.1       0.0.0.0         UG    203    0        0 eth1
2.XXX.X.0       0.0.0.0         255.255.252.0   U     203    0        0 eth1
169.254.0.0     0.0.0.0         255.255.0.0     U     203    0        0 eth1
192.168.0.0     0.0.0.0         255.255.255.0   U     202    0        0 eth0

So, as I understand it, lan traffic is routed internally. Any wan traffic takes the default route (the top line of the routing table).

At this point - before I installed isc-dhcp-server - so there was no DHCP server at all running on the Pi - when I installed Pi-hole I selected eth0 as the adapter that Pi-hole would listen on. The default IP for that adapter, rather than 192.168.0.1, was the wan IP. At this point I don't know what the gateway should be, as there is no gateway configured on eth0, and eth1 is not a static IP as it's provided by the ISP. When I've installed Pi-hole in the past with a separate router, the static IP of the relevant NIC is the default, along with the gateway which is the router IP.

Whatever I enter for the gateway value here, when Pi-hole completes the install, eth0 has lost the 192.168.0.1 IP completely. At that point all clients lose connectivity to the Pi.

The IP of eth0 is assigned in the config file for the adapter - not by DHCP:
interface eth0

static ip_address=192.168.0.1/24
static routers=192.168.0.1
static domain_name_servers=192.168.0.1
nogateway

Hopefully that's a bit clearer. Happy to post firewalld and isc-dhcp-server configs but I don't believe they are part of this issue, which seems related to the routing and / or NIC config.

TIA

Si

This is what I'm offered when I select eth0 as the interface for Pihole:

Try to use the current toolstack (iproute2) and dont use the depreciated ifconfig & route commands.
To list all IPv4 addresses:

ip -4 address

Or shorter:

ip -4 a

Or less verbose:

ip -br -4 a

Or for a particular <INTERFACE_NAME> (the s argument for show):

ip -br -4 a s <INTERFACE_NAME>

List IPv4 routes:

ip -4 r

To isolate showing only the default route(s) (the s argument for show):

ip -4 r s default

To add an IP to an interface (a argument for add):

sudo ip a a <IP_ADDRESS>/<MASK> dev <INTERFACE_NAME>

To remove an IP from an interface (d argument for delete):

sudo ip a d <IP_ADDRESS>/<MASK> dev <INTERFACE_NAME>

To add a default route (a for add):

sudo ip r a default via <GATEWAY_IP> dev <INTERFACE_NAME> src <OWN_IP_ADDRESS>

To remove a default route (d for delete):

sudo ip r d default via <GATEWAY_IP> dev <INTERFACE_NAME> src <OWN_IP_ADDRESS>

When in sh.t creek, try make it so that only one default route exists via the WAN interface.
Test with the ping and traceroute -n commands.
And when get it to work like this, you'll have to look into who/which piece of software is borking your IP stack.

EDIT: Ow forgot to ask, did you already apply below for actual forwarding?

$ sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 1

And below for masquerading outbound traffic?

$ sudo nft -n list table nat
table ip nat {
        chain POSTROUTING {
                type nat hook postrouting priority 100; policy accept;
                oifname "<WAN_INTERFACE_NAME>" counter packets 8068 bytes 728001 masquerade
        }
}

EDIT2: Ow and ditch isc-dhcp-server and let pihole-FTL do DNS plus DHCP for your clients.
Makes things allot easier ... KISS.
Ow and setup a proper firewall to allow, or not, only particular services coming in via the WAN interface! (EDIT: Eg a VPN service)

I'm not sure you've cleared the router configuration yet.

Link-locals/APIPAs (range 169.254.0.0/16) appearing in your routing table make your network configuration appear dodgy to me. Link-locals should only show up as a last resort, i.e. if the network stack has failed using other means to assign an IP address (which doesn't seem to be the case for you).

It's still not clear which route (not network-related :wink: ) you have taken to make your RPi a router.

When turning your RPi into a router, it won't be enough to just configure your individual network interfaces - you'd probably need to bridge interfaces and to enable IP forwarding for your OS, and you'd likely need to install and configure hostapd, bridge utils and dnsmasq (and probably other tools I don't recall or even may not know), or you may have a take at configuring systemd-networkd to the same effect.

I haven't tried this, but it may be possible to coerce access point utilities like RaspAP to serve a properly bridged wired network as well.

Or you may opt for a full router OS setup like OpenWRT, which would allow you fine grained control of the features you'd want your router to support with its over 3,000 packages (adding things like a VPN gateway, guest networks, home automation,...).
Caution, though: As OpenWRT may use dnsmasq for DNS/DHCP, it may only be possible to host Pi-hole on your OpenWRT device as a Docker container when you go down this road.

But as said before, turning your RPi into a router is not a Pi-hole issue.

You may increase your chances for quicker and better advice by consulting forums most specfic for your chosen path , e.g. OpenWRT's community seems quite active as well.

Hi
Just to clarify as I may not have been clear:
Currently the RPi is working as expected as far as the router side goes - lan and wan traffic is flowing as expected, devices on eth0 are issued IPs via the dhcp server.
It’s only when pi-hole is installed and configured that the problems start.
Si

Above one looks wrong.
The static routers= line installs a default route.
But the nogateway directive conflicts because its there to not install a default route.

Also you can use the loopback IP 127.0.0.1 for the domain_name_servers= field instead of the eth0 IP 192.168.0.1.
That way local processes will use the loopback IP for DNS lookups instead of broadcasting the query on the eth0 interface.
Plus the loopback interface named lo is way faster as the 100/1000 mbit eth0 interface and not dependent on if connected or not.

Try fix this so it resembles below:

  static ip_address=192.168.0.1/24
  static domain_name_servers=127.0.0.1
  nogateway

Am not sure if you knew already but if you dont configure any IP details in dhcpcd.conf for the WAN interface eth1, the dhcpcd daemon will try acquire IP details, including DNS server(s), automatically via DHCP for this interface.
Default for dhcpcd is to acquire IP details via DHCPv4, and IPv6 SLAAC, for all detected interfaces except when configured otherwise (like static ip_address=).

Once you fixed above and still not working, could you post output for below ones?

cat /proc/device-tree/model

lsb_release -d

And below ones when its not working:

ip -br l | awk '{print $1,$2,$4}'

ip -br -4 a

ip -4 r

journalctl --full -u dhcpcd | tail -40

sysctl net.ipv4.ip_forward

sudo nft -n list table nat

EDIT: Ow and might I ask why you deploy isc-dhcp-server instead of letting the pihole-FTL daemon do DHCP services for your LAN?

EDIT2: Ow I realised that if you run a DHCP service on the Raspi host and the WAN interface is configured to acquire IP details via DHCP, then the own DHCP service needs to be configured to not answer/listen/bind to the WAN interface or else the WAN interface could take on settings advertised from the own DHCP service instead of the one present on the WAN segment.
With dnsmasq, which is embedded into the pihole-FTL binary/daemon, you have below two directive that can be used:

pi@ph5b:~ $ man dnsmasq
[..]
       -I, --except-interface=<interface name>
              Do not listen on the specified interface. Note that  the  order  of
              --listen-address  --interface  and  --except-interface options does
              not matter and that --except-interface options always override  the
              others.  The  comments  about interface labels for --listen-address
              apply here.
[..]
       -2, --no-dhcp-interface=<interface name>
              Do not provide DHCP or TFTP on the specified interface, but do pro‐
              vide DNS service.

To be clearer: Did you opt to NOT to configure a static IP when installing Pi-hole?

This fixed the issue. Thank you!

1 Like

My understanding (which could be wrong) was that ics is more powerful and established than dnsmasq / FTL. As the Pi is acting as the router I wanted to 'future-proof' the machine against any further enhancements I might want to make later.

Maybe isc-dhcp-server is more powerful/feature rich for DHCP but it certainly is not more established.
Though isc-dhcp-server is one of the oldest, many home router manufacturers apply dnsmasq for their routers.
Heck even my own Asus router runs dnsmasq:

dehakkelaar@RT-N66U:/tmp/home/root# ps
[..]
 9559 nobody    1040 S    dnsmasq --log-async

From my understanding (which also could be wrong) and from what I've read about this subject is that isc-dhcp-server is well suited for larger sized networks like corporate ones.
But dnsmasq excels for smaller to medium sized networks in regard to speed and resources used.

If it were my choice, I would have started of with pihole-FTL's own embedded dnsmasq for DHCP for simplicity ... KISS.
Only one daemon running instead of two.
You can always at a later stage decide to additionally install isc-dhcp-server if so required.

Also with pihole-FTL doing DHCP, you dont have to configure additional settings/hooks for the client hostnames that are advertised during the DHCP lease transaction to be registered automatically in DNS like you have to do with isc-dhcp-server.
You have not mentioned how these client hostnames are now registered in DNS?

EDIT: Ow and dnsmasq runs in more places than you think:

dnsmasq has low requirements for system resources,[6][7] can run on Linux, BSDs, Android and macOS, and is included in most Linux distributions. Consequently, it "is present in a lot of home routers and certain Internet of Things gadgets"[4] and is included in Android.[5]

For your specific configuration, I wouldn't think so.

In addition to what deHakkelaar already explaned, ISC DHCP would not register hostnames as proposed by clients during DHCP lease negotiation with a co-located DNS server by default.

dnsmasq -and thus pihole-FTL- happens to be both a DHCP and a DNS server and would do so automatically, i.e. it does create the necessary A and PTR records for a DHCP client. It would also make an effort to associate that name to certain observed IPv6 addresses, i.e. it would create the respective AAAA and PTR records.
This can partially mitigate IPv6's lack of hostname registration for certain auto-configuration procedures.

I'd support deHakkelaar's recommendation to make use of Pi-hole's DHCP server, at least for your current configuration.

I tried to anticipate that you would not stick with those eth0 clients, but you would want wifi clients to be able join your network as well. That's why I mentioned RaspAP as a possible configuration option.

But a router's duties and capabilities are not limited to DHCP.
If you'd want your RPi router to also handle stuff like VLANs, guest networks, home automation etc. etc., you may as well consider a full router OS like OpenWRT straight away.
Note however that OpenWRT would also employ dnsmasq for DHCP and DNS, and you'd have to research if and how that could coexist with or be replaced by Pi-hole on the same device. Other router OSs may pose similar problems.

If your main concern is routing, I'd probably focus on picking the optimal software support for that field of application first, and worry about how to integrate Pi-hole later.

1 Like