[Dnsmasq-discuss] dnsmasq dhcp relay not relaying response from upstream to client

Nicolas Cavallari nicolas.cavallari at green-communications.fr
Sat Jun 26 11:26:10 UTC 2021


Let's look at the reply from freeradius:

> (14) Sent code 1026 Id 24307805 from 10.10.254.1:67 to 10.10.253.1:67
> length 0
> (14)   DHCP-Relay-IP-Address = 10.10.253.1
> (14)   DHCP-Client-Identifier = 0xff2784511b000100012867cc8108002784511b
> (14)   DHCP-IP-Address-Lease-Time = 7200
> (14)   DHCP-Client-IP-Address = 255.255.255.255

This is suspicious. RFC 2131 Table 3 says ciaddr (Client IP Address) 
should be 0.0.0.0 in a DHCPOFFER, and should otherwise mirror the ciaddr 
sent by the client, which, in this case, was 0.0.0.0 too.

> (14)   DHCP-Your-IP-Address = 10.10.253.3
> (14)   DHCP-Subnet-Mask = 255.255.255.0
> (14)   DHCP-Router-Address = 10.10.253.1
> (14)   DHCP-Domain-Name-Server = 8.8.8.8
> (14)   DHCP-Message-Type = DHCP-Offer
> (14)   DHCP-Gateway-IP-Address = 10.10.253.1
> (14)   DHCP-DHCP-Server-Identifier = 255.255.255.255

This is HIGHLY suspicious. This is supposed to be the address of the 
server. The rules are set in section 4.1 of the RFC, and most notably:

"a server MUST choose an address as a 'server identifier' that, to the 
best of the server's knowledge, is reachable from the client."

This is not going to work well in this case.

> (14)   DHCP-Opcode = Server-Message
> (14)   DHCP-Hardware-Type = Ethernet
> (14)   DHCP-Hardware-Address-Length = 6
> (14)   DHCP-Hop-Count = 1
> (14)   DHCP-Transaction-Id = 24307805
> (14)   DHCP-Flags = 0

The "broadcast" flag is not set. This means that the client supports 
unicast replies, so the relay should unicast the reply to yiaddr using 
chaddr...

So what would dnsmasq do with such a response ?

relay_reply4() would correctly detect that this is a server-to-relay 
response, so is_relay_reply = 1,

but ciaddr is not zero, and dnsmasq will trust ciaddr over yiaddr (this 
makes perfect sense for a DHCP server, a relay should not see anything 
with ciaddr != 0 anyway). so the destination is set to 
255.255.255.255:68, and we skip all the destination selection code (the 
one that looks at the broadcast flag), as well as the interface 
selection code.

dnsmasq would probably sends the packet to 255.255.255.255:68 without 
telling on which interface it should be sent or which source address 
should be used, because ciaddr is supposed to be a unicast address. What 
the kernel would do in this case is anyone's guess.

Even if such a message could be forwarded verbatim to the client, it 
would probably confuse it. When a client receives a lease from a DHCP 
server, it will renew it by sending unicast packets directly to the 
server's "server identifier" address, without involving the relay. But 
here, "server identifier" is set to 255.255.255.255...

On the other hand, the ISC DHCP server/relay/client have probably seen 
their share of nonsensical DHCP implementations, and can probably see 
through freeradius's nonsense packets.



More information about the Dnsmasq-discuss mailing list