Device as DHCP server only: why injecting DNS from the gateway?

I am using a TP-Link device with OpenWRT installed. The TP-Link is not being used as a router, just as a DHCP server. The main router for this network is the AT&T Fiber gateway that they provided to me.

AT&T does not allow you to change the DNS server on the gateway, so I was hoping to use DHCP to inject the desired DNS servers to clients.

I have one of the TP-Link's LAN ports plugged into one of the AT&T LAN ports, and the AT&T gateway has DHCP turned off. The TP-Link successfully assigns IP addresses to clients.

TP-Link: 192.168.0.1
AT&T Gateway: 192.168.0.2

The DHCP server specifies that 192.168.0.2 is the default route / gateway. The internet works and traceroute shows the first hop as 192.168.0.2, which is what I want.

What I don't want is this: Even though OpenWRT is acting as the DHCP server, it's somehow still also providing AT&T's DNS:

# Generated by resolvconf
domain lan
search lan attlocal.net
nameserver 192.168.0.1
**nameserver 2600:1700:... (etc)**

Here are my settings. peerdns is turned off everywhere I can possibly think to do it.

root@OpenWrt:~# uci show network.lan
network.lan=interface
network.lan.device='br-lan'
network.lan.proto='static'
network.lan.ip6assign='60'
network.lan.dns='208.67.222.222' '208.67.220.220'
network.lan.ipaddr='192.168.0.1/24'
network.lan.gateway='192.168.0.2'

root@OpenWrt:~# uci show network.wan
network.wan=interface
network.wan.device='eth0.2'
network.wan.proto='dhcp'
network.wan.peerdns='0'
network.wan.dns='208.67.222.222' '208.67.220.220'

root@OpenWrt:~# uci show network.wan6
network.wan6=interface
network.wan6.device='eth0.2'
network.wan6.proto='dhcpv6'
network.wan6.reqaddress='try'
network.wan6.reqprefix='auto'
network.wan6.peerdns='0'
network.wan6.dns='2620:119:35::35' '2620:119:53::53'

root@OpenWrt:~# uci show dhcp.@dnsmasq[0]
dhcp.cfg01411c=dnsmasq
dhcp.cfg01411c.domainneeded='1'
dhcp.cfg01411c.localise_queries='1'
dhcp.cfg01411c.rebind_protection='1'
dhcp.cfg01411c.rebind_localhost='1'
dhcp.cfg01411c.local='/lan/'
dhcp.cfg01411c.domain='lan'
dhcp.cfg01411c.expandhosts='1'
dhcp.cfg01411c.dhcp_option='3,192.168.0.2' '6,192.168.0.1'
dhcp.cfg01411c.readethers='1'
dhcp.cfg01411c.leasefile='/tmp/dhcp.leases'
dhcp.cfg01411c.resolvfile='/tmp/resolv.conf.d/resolv.conf.auto'
dhcp.cfg01411c.localservice='1'
dhcp.cfg01411c.ednspacket_max='1232'
dhcp.cfg01411c.confdir='/tmp/dnsmasq.d'
dhcp.cfg01411c.authoritative='1'

root@OpenWrt:~# uci show dhcp.lan
dhcp.lan=dhcp
dhcp.lan.interface='lan'
dhcp.lan.start='100'
dhcp.lan.limit='150'
dhcp.lan.leasetime='12h'
dhcp.lan.dhcp_option='6,192.168.0.1'
dhcp.lan.dhcpv4='server'
dhcp.lan.dhcpv6='server'
dhcp.lan.ra='server'
dhcp.lan.ra_flags='managed-config' 'other-config'
dhcp.lan.force='1'
dhcp.lan.dns='2620:119:35::35' '2620:119:53::53'

root@OpenWrt:~# uci show dhcp.wan
dhcp.wan=dhcp
dhcp.wan.interface='wan'
dhcp.wan.ignore='0'
dhcp.wan.dhcp_option='6,192.168.0.1'
dhcp.wan.ra_flags='none'

Any help would be appreciated here. The only DNS I want the DHCP server to give to clients is 192.168.0.1. Thank you!

Double check to make sure that the AT&T gateway has DHCP disabled. One easy way to do this (beyond verifying the configuration of the gateway) is to unplug your OpenWrt device from the network and make sure that a DHCP request fails on a computer/phone. Then plug OpenWrt back into the network and run a DHCP lease request again from that same computer/phone.

Then, once you have a fresh lease, show us the complete network configuration from that computer/phone (i.e. the IP, subnet mask, DNS, gateway)

Don't use lan->wan routing here. What you're trying to do is have a separate DHCP server, so it should be an appendage on the LAN which is just a DHCP server. Use DHCP options to advertise the AT&T router as the gateway, and either external DNS servers or the OpenWrt router as the DNS server (which will forward to the external DNS you've configured).

The IPs of DNS servers advertised through DHCP are only advisory-- endpoints are free to use other DNS if they want to. Unless you do route and firewall every packet through OpenWrt (which on a fiber line, will take more CPU horsepower than the C7 has) you can't block them.

I think that's what I've already done here. I'm not using the WAN port on the TP-Link at all. One of its LAN ports is connected to one of the AT&T Gateway's LAN ports (that makes them peers, no?). I did this because I don't want to introduce latency by routing packets through the TP-Link device.

I've already done this above:

3,... specifies the gateway and 6,... specifies the DNS server.

It went as expected. With the OpenWRT/TP-Link device disconnected, my phone didn't receive an IP address. I plugged the device back in and reconnected from the phone.

On the phone, with a new lease:
IP address: 192.168.0.242
Gateway: 192.168.0.2
Subnet mask: 255.255.255.0
DNS:

  • 2600:1700:... (I don't want this one, it's from AT&T)
  • 192.168.0.1 (OpenWRT DNS)

Since this network is dual stack, endpoints will generally use IPv6 first, and your IPv4 configuration is ignored.

IPv6 doesn't use a DHCP server, it works through "advertisement" anycast packets. You need to determine how to stop the AT&T router from sending those.

Thank you for that. Just so I'm clear, do you mean anycast packets from router -> client? IIRC, In IPv4 DHCP, the client sends a message to the broadcast address, which the DHCP server receives. Then the DHCP server responds with an IP, the gateway, and DNS. Do I have that right?

How does IPv6 differ from that?

So far, the only way I can fully disable that DNS server injection is by throwing the baby out with the bathwater: I have to disable IPv6 on the LAN entirely. That results in the single DNS server (the OpenWRT device) I'm looking for, but I'd like to be able to use IPv6, if only to learn.