PiHole DHCP not working for ESP8266

Ive used PiHole (DNS and DHCP) for a few years without issue with around 30 connected devices.

Im trying to connect an ESP8266 commercial controller. Pihole DHCP assigns an IP, correctly registers the device in the lease table. However the device does not connect to wifi and keeps retrying. The vendor suggests that there is something amiss with the DHCP dialogue.

So I switch DHCP to my router on the same network. With no other changes the ESP8266 connects immediately. The new IP is likewise shown in the routers lease table.

Pihole DHCP is set up to Cloudflare, listen only on eth0, never forward options both ticked.

There dont seem to be many config options to fix this aside from abandoning pihole as DHCP. The router that works with DHCP is a cheap TP-Link archer C7.

Anyone have any suggestions?

  Pi-hole version is v5.2.4 (Latest: v5.2.4)
  AdminLTE version is v5.4 (Latest: v5.4)
  FTL version is v5.7 (Latest: v5.7)

Could you elaborate on that?

Can you put a protocol monitor like wireshark on the network segment and capture the actual DHCP offers so we can see the difference between the two servers?

pihole-FTL uses dnsmasq at it's core so I would be surprised if it's lacking in any functions.

DHCP transactions are recorded in the dnsmasq log file at /var/log/pihole.log.

Look in there and see if any DHCP errors are reported for that client.

The following command will record all traffic on the DHCP ports:

sudo tcpdump -w /tmp/dhcp.pcap port 67 or 68

Run this on your Pi-hole and connect the ESP-device. Try again with some other device you have (where DHCP negotiation works as expected).

Once you are done with testing, terminate the command above using Ctrl+C. This should print a summary saying how many packets were captured and stored. The shorter your capturing period is, the easier it will be to analyze them.

Next, you can use tcpdump to analyze your recording, like

tcpdump -n -ttt -r /tmp/dhcp.pcap -vvv

(-n shows IP addresses, -ttt shows the time relative to the first recorded package and -vvv shows as much information as possible).

You can also share the file with us for further analysis and/or use wireshark to analyze your recording.


One more question: Did you enable rapid commits on the Pi-hole Settings -> DHCP page?
Screenshot from 2021-03-24 19-20-30

Could you try toggeling this option? The ESP may not support it and the router may not be able to do it (so they match).

1 Like

With both "enable" options unchecked (I also tried with just IPv6 checked, but no change.
) and tcpdump running on pihole as per your syntax, I see this in the pihole query log which is indeed the ESP device. It remains without a wifi connection in a continual connection attempt loop. This entry repeats periodically in the phhole log.

Mar 25 10:11:06 dnsmasq-dhcp[14325]: DHCPDISCOVER(eth0) c8:2b:96:30:0b:0b 
Mar 25 10:11:06 dnsmasq-dhcp[14325]: DHCPOFFER(eth0) 192.168.4.146 c8:2b:96:30:0b:0b 
Mar 25 10:11:06 dnsmasq-dhcp[14325]: DHCPREQUEST(eth0) 192.168.4.146 c8:2b:96:30:0b:0b 
Mar 25 10:11:06 dnsmasq-dhcp[14325]: DHCPACK(eth0) 192.168.4.146 c8:2b:96:30:0b:0b ESP_300B0B
Mar 25 10:11:08 dnsmasq-dhcp[14325]: DHCPREQUEST(eth0) 192.168.4.146 c8:2b:96:30:0b:0b 
Mar 25 10:11:08 dnsmasq-dhcp[14325]: DHCPACK(eth0) 192.168.4.146 c8:2b:96:30:0b:0b ESP_300B0B

tcpdump, however, shows only 2 entries for seemingly a different device, or at least MAC. However at the time of testing there wouldnt be any other devices asking for DHCP. I ran the test a few times just in case a lease for a different device had expired, but each time this is the only tcpdump captured.

 00:00:00.000000 IP (tos 0x0, ttl 64, id 47833, offset 0, flags [none], proto UDP (17), length 379)
    0.0.0.0.68 > 255.255.255.255.67: [udp sum ok] BOOTP/DHCP, Request from 62:d7:42:2c:71:69, length 351, xid 0xcdff836a, secs 65535, Flags [none] (0x0000)
	  Client-Ethernet-Address 62:d7:42:2c:71:69
	  Vendor-rfc1048 Extensions
	    Magic Cookie 0x63825363
	    DHCP-Message Option 53, length 1: Discover
	    Client-ID Option 61, length 19: hardware-type 255, 42:2c:71:69:00:01:00:01:23:dc:4f:f5:62:cb:2f:a2:4a:53
	    SLP-NA Option 80, length 0""
	    MSZ Option 57, length 2: 1472
	    Vendor-Class Option 60, length 50: "dhcpcd-6.11.5:Linux-4.19.62-sunxi:armv7l:Allwinner"
	    Hostname Option 12, length 6: "pihole"
	    T145 Option 145, length 1: 1
	    Parameter-Request Option 55, length 15: 
	      Subnet-Mask, Classless-Static-Route, Static-Route, Default-Gateway
	      Domain-Name-Server, Hostname, Domain-Name, MTU
	      BR, NTP, Lease-Time, Server-ID
	      RN, RB, Option 119
	    END Option 255, length 0
 00:01:04.092837 IP (tos 0x0, ttl 64, id 653, offset 0, flags [none], proto UDP (17), length 379)
    0.0.0.0.68 > 255.255.255.255.67: [udp sum ok] BOOTP/DHCP, Request from 62:d7:42:2c:71:69, length 351, xid 0xcdff836a, secs 65535, Flags [none] (0x0000)
	  Client-Ethernet-Address 62:d7:42:2c:71:69
	  Vendor-rfc1048 Extensions
	    Magic Cookie 0x63825363
	    DHCP-Message Option 53, length 1: Discover
	    Client-ID Option 61, length 19: hardware-type 255, 42:2c:71:69:00:01:00:01:23:dc:4f:f5:62:cb:2f:a2:4a:53
	    SLP-NA Option 80, length 0""
	    MSZ Option 57, length 2: 1472
	    Vendor-Class Option 60, length 50: "dhcpcd-6.11.5:Linux-4.19.62-sunxi:armv7l:Allwinner"
	    Hostname Option 12, length 6: "pihole"
	    T145 Option 145, length 1: 1
	    Parameter-Request Option 55, length 15: 
	      Subnet-Mask, Classless-Static-Route, Static-Route, Default-Gateway
	      Domain-Name-Server, Hostname, Domain-Name, MTU
	      BR, NTP, Lease-Time, Server-ID
	      RN, RB, Option 119
	    END Option 255, length 0

Turning off DHCP on pihole and enabling it on a router gives this dump and a successful wifi connection for the ESP

 00:00:00.000000 IP (tos 0x0, ttl 255, id 0, offset 0, flags [none], proto UDP (17), length 336)
    0.0.0.0.68 > 255.255.255.255.67: [udp sum ok] BOOTP/DHCP, Request from c8:2b:96:30:0b:0b, length 308, xid 0xccfeedf1, Flags [none] (0x0000)
	  Client-Ethernet-Address c8:2b:96:30:0b:0b
	  Vendor-rfc1048 Extensions
	    Magic Cookie 0x63825363
	    DHCP-Message Option 53, length 1: Discover
	    MSZ Option 57, length 2: 1500
	    Parameter-Request Option 55, length 5: 
	      Subnet-Mask, Default-Gateway, BR, Domain-Name-Server
	      NTP
	    END Option 255, length 0
	    PAD Option 0, length 0, occurs 53
 00:00:01.536308 IP (tos 0x0, ttl 255, id 1, offset 0, flags [none], proto UDP (17), length 336)
    0.0.0.0.68 > 255.255.255.255.67: [udp sum ok] BOOTP/DHCP, Request from c8:2b:96:30:0b:0b, length 308, xid 0xccfeedf1, Flags [none] (0x0000)
	  Client-Ethernet-Address c8:2b:96:30:0b:0b
	  Vendor-rfc1048 Extensions
	    Magic Cookie 0x63825363
	    DHCP-Message Option 53, length 1: Discover
	    MSZ Option 57, length 2: 1500
	    Parameter-Request Option 55, length 5: 
	      Subnet-Mask, Default-Gateway, BR, Domain-Name-Server
	      NTP
	    END Option 255, length 0
	    PAD Option 0, length 0, occurs 53
 00:00:04.301637 IP (tos 0x0, ttl 255, id 2, offset 0, flags [none], proto UDP (17), length 336)
    0.0.0.0.68 > 255.255.255.255.67: [udp sum ok] BOOTP/DHCP, Request from c8:2b:96:30:0b:0b, length 308, xid 0xccfeedf1, Flags [none] (0x0000)
	  Client-Ethernet-Address c8:2b:96:30:0b:0b
	  Vendor-rfc1048 Extensions
	    Magic Cookie 0x63825363
	    DHCP-Message Option 53, length 1: Discover
	    MSZ Option 57, length 2: 1500
	    Parameter-Request Option 55, length 5: 
	      Subnet-Mask, Default-Gateway, BR, Domain-Name-Server
	      NTP
	    END Option 255, length 0
	    PAD Option 0, length 0, occurs 53
 00:00:00.000010 IP (tos 0x0, ttl 255, id 3, offset 0, flags [none], proto UDP (17), length 336)
    0.0.0.0.68 > 255.255.255.255.67: [udp sum ok] BOOTP/DHCP, Request from c8:2b:96:30:0b:0b, length 308, xid 0xccfeedf1, Flags [none] (0x0000)
	  Client-Ethernet-Address c8:2b:96:30:0b:0b
	  Vendor-rfc1048 Extensions
	    Magic Cookie 0x63825363
	    DHCP-Message Option 53, length 1: Request
	    MSZ Option 57, length 2: 1500
	    Requested-IP Option 50, length 4: 192.168.4.183
	    Server-ID Option 54, length 4: 192.168.4.1
	    Parameter-Request Option 55, length 5: 
	      Subnet-Mask, Default-Gateway, BR, Domain-Name-Server
	      NTP
	    Hostname Option 12, length 10: "ESP_300B0B"
	    END Option 255, length 0
	    PAD Option 0, length 0, occurs 29
 00:00:58.370832 IP (tos 0x0, ttl 255, id 46710, offset 0, flags [none], proto UDP (17), length 336)

The ESP device gets IP 192.168.4.145 and works as expected.

The device uses standard calls so the vendor is not aware of the exact wifi connection negotiation that takes place. But based on the device being successfully used in many other installations, and this being the only one with a stand alone DHCP server, I agree its a reasonable hypothesis. The fact the device connects to my router-based DHCP, but not pihole DHCP, strongly suggests the problem is in this area. Trouble is neither of us are networking experts :slight_smile:

Do you have any OrangPi hardware, or Armbian running devices?

Please run pihole -d and post the URL/token that is printed at the end of the process.

That looks like a DHCP discover from the Pi-hole device itself?
Are you positive no other DHCP traffic was registered during that period?

An ESP8266 can operate as an access point itself.
192.168.4.1 happens to be the default address an ESP8266 assigns to itself when operating as AP.

Are you operating your ESP8266 as AP?

If so, it would thus be unclear whether your router or your troublesome ESP8266 (or yet another ESP8266, maybe embedded in an ill-configured IoT device) in your network is answering those DHCP broadcasts.

You could try to detect active DHCP servers on your link by running the folllowing command on your Pi-hole machine:

pihole-FTL dhcp-discover

Results for that command are also contained in the debug log Dan asked you to upload and provide a token for, but you may have to run the command twice in short succession in order to wake up ESP8266 and allow it to answer the DHCP broadcast in time.

If your normal network would also run a 192.168.4.0/24 subnet, that would cause problems, and results may be inconclusive.
You should adjust the subnet of either your router or your ESP8266 in that case, or switch the latter to client / station mode only.

1 Like

https://tricorder.pi-hole.net/wqgmhrwd30

Yes, PiHole itself runs on one.

My whole network is a single 192.168.4.0/24 setup. 192.168.4.1 is the gateway router. If the ESP is trying to act as an AP using the gateways 192.168.4.1 address, it works perfectly correctly if DHCP is managed by the router. Only when DHCP is switched to PiHole does it fail to connect. The fact it works in one case suggests to me the ESP isnt trying to default to 192.168.4.1 but I could be wrong.

Received 300 bytes from eth0:192.168.4.1
Offered IP address: 192.168.4.179
Server IP address: 192.168.4.1
Relay-agent IP address: N/A
BOOTP server: (empty)
BOOTP file: (empty)
DHCP options:
Message type: DHCPOFFER (2)
server-identifier: 192.168.4.1
lease-time: 89280 ( 1d 48m )
renewal-time: 44640 ( 12h 24m )
rebinding-time: 78120 ( 21h 42m )
netmask: 255.255.255.0
broadcast: 192.168.4.255
dns-server: 192.168.4.200
dns-server: 1.1.1.1
router: 192.168.4.1
--- end of options ---

Thats with the router doing DHCP, where the ESP connects immediately. The debug trace is for the fault condition ie PiHole is DHCP, and the ESP cannot connect. The only change I make is turn DHCP off on the router and on for PiHole. That makes the difference between it getting wifi connectivity and not.

Its perhaps worth noting in both cases PiHole is DNS. And that there is only ever 1 DHCP active at any time, as per the debug trace (well they are turned off in the router settings, Im rashly assuming it does as its told!)

Ok, that probably means your ESP is not configured to act as an AP.
To be sure, you'd have to check the current software on your ESP.
Just keep in mind to switch your ESP to another subnet if you consider to use it as AP at some time in future projects.

Your dhcp-discover results also look ok.
Note that your router distributes a public DNS server alongside Pi-hole. Your clients may thus choose that 1.1.1.1 to by-pass Pi-hole if your router is your DHCP server.

Your debug log also doesn't show any hints why your ESP may fail to join your network.
It does show an issue with your ULA IPv6 address - your interface only lists a link-local IPv6.
This may prevent your ESP to talk to Pi-hole's DNS via IPv6.
It wouldn't interfere with DHCP, as that is a strictly IPv4 protocol.

That leaves us with the lead from your tcpdump:
When trying to capture traffic when Pi-hole was your DHCP server, your ESP didn't show up in the tcpdumps.

On the other hand, Pi-hole's logs do register several DHCPREQUEST messages from your ESP MAC address.

But normally, the DHCPACK -as correctly issued by Pi-hole- would be the final step in a DHCP lease negotiation.
However, your ESP is repeating the request, which it shouldn't.
I am at a loss explaining what would cause that. :thinking:

The most likely explanation would be an error in the ESP's DHCP software.
But that wouldn't explain why it works with your router as DHCP.

The only real difference I see is 1 day (router) vs. 62 days (Pi-hole). 62 days is 5356800 seconds which is a number which needs at least 23 bits to be stored. I wonder if there is some overflow because someone tried to be clever in the ESP code and assumed he can save some bits because nobody would even hand out leases with such a long validity. This is a wild guess, but it may be worth testing.

The other difference is that the Pi-hole hands out only one DNS server and the router two (as mentioned). Maybe the ESP firmware expects two DNS servers (may be a bug) and thinks the DHCPACK is truncated? Yet another wild guess.

I like that one.
Now that you mention it, I faintly recall reports for ESPs going into a perpetual 5 minute DHCP lease renewal cycle because the variable holding the lease time was overflowing.
(edit: That's from a hackathon project at my nephew's school. I didn't participate, so this is second-hand information to be verified ;))

Hmmm, interesting! Thanks for the replies. I will try the lease time when I'm back on site next week. It's only that long because the devices don't really change, so I'll drop it down and retest.

Hmmm. Unfortunately that doesnt seem to have fixed it. I dropped the lease time down to the same as on the router (which successfully negotiates DHCP with the ESP), but it still wont connect.

However, that comment lead me to discover the cause (but not the solution) to the problem. If PiHole is the only DNS server, the ESP does not successfully connect to wifi. With 1.1.1.1 as secondary DNS it works fine. With either my pihole IP or blank as secondary DNS it fails.

At the moment the only solution that works is not to have pihole as DNS (or to provide a different secondary), which is less than ideal.

How about 0.0.0.0 or just some IP in your local network that does not exist?

NO, it doesn't like that either. The router wouldnt accept 0.0.0.0 but it took a non existent but valid local IP. ESP failed to connect again.

Okay, so can you confirm that the router actually send two IP addresses when you configure two times the Pi-hole IP address? Use

sudo pihole-FTL dhcp-discover

to check this.

Another solution could be to just add a second IP address to your Pi-hole. This is simple and easy. I cannot really give concrete hints as I'm not sure what your OS is but Google etc. should give you plenty of results when you search for "Linux virtual interface"

It does, as Bucking_Horn highlights from the tcp dump ...

Do you mean get PiHole to listen on a second IP address? I might have that wrong? I already know all devices except the ESP work with just one DNS server, ie that of PIHole. They all also work with two DNS servers, including the ESP provided the alternate to PiHole is valid.

Wouldnt doffering 2 PiHole addresses produce the exact same result ie the ESP doesn't like PiHole as DNS. Well unless for some reason the ESP specifically doesnt like x.x.x.200 as an IP address. Perhaps Ive misunderstood.

PS PiHole OS is armbian/linux

Yes, that's the suggestion.
Assuming the iproute2 package is available on your system (it most likely is), you could give that a try by executing a command similar to:

ip address add 192.168.4.201 dev eth0

Substitute IP address as well as interface eth0 with the correct values as required.

Note that those changes are not permanent, i.e. the additional IP address won't survive a reboot.

We don't know yet whether your ESP refuses to accept less than two DNS servers or to accept a private IP as DNS server.

A test with a second IP may confirm or reject those assumptions.