DNS Filter in LEDE

Hello,

I've been trying to replicate the DNS Filter functionality of the ASUSWRT/Merlin firmware in WRT3200ACM with LEDE latest davidc502 build (r5113):

but I'm failing, probably beacuse I'm not so experienced user in LEDE/Openwrt environment. Basically the DNS Filter allows to configure the global DNS that router assign to all clients (both in LAN/WLAN and guest WLAN) and some exception, for using either:

  1. DNS of the WAN interface
  2. 3 different custom DNS specified by the user (one at time)
  3. Custom defined by client DNS

Furthermore, the DNS filter enforces the DNS client assignment, not allowing the clients to modify the DNS the router assign to them (excpeting for special rule 2 and 3 above)

I enclose my dhcp, firewall and network configuration files; I've been trying to achieve partially those functionalities, by specifying TAGs on dhcp file, but it seems they are not retained correctly in some way.

DHCP:

config dnsmasq
option domainneeded '1'
option boguspriv '1'
option localise_queries '1'
option rebind_protection '1'
option rebind_localhost '1'
option local '/lan/'
option domain 'lan'
option expandhosts '1'
option authoritative '1'
option readethers '1'
option leasefile '/tmp/dhcp.leases'
option resolvfile '/tmp/resolv.conf.auto'
option nonwildcard '1'
option localservice '1'

config dhcp 'lan'
option interface 'lan'
option start '100'
option limit '150'
option dhcpv6 'server'
option ra 'server'
option leasetime '24h'
option ra_management '1'

config dhcp 'wan'
option interface 'wan'
option ignore '1'

config odhcpd 'odhcpd'
option maindhcp '0'
option leasefile '/tmp/hosts/odhcpd'
option leasetrigger '/usr/sbin/odhcpd-update'
option loglevel '4'

config host
option name 'pc-tati'
option dns '1'
option mac 'XX:XX:XX:XX:XX:XX'
option ip '192.168.1.10'
option tag 'google'

config tag 'google'
list dhcp_option '6,8.8.8.8,8.8.4.4'

config tag 'opendns'
list dhcp_option '6,208.67.222.222,208.67.220.220'

config dhcp 'languest'
option start '100'
option limit '150'
option interface 'languest'
option leasetime '3h'

I truncated all the host I configured in the environment; in this case I leave only one of them with the tag 'google'

Following the FIREWALL personal script for blocking the clients selecting different DNS than the ones of the router:

iptables -t nat -I PREROUTING -p tcp --dport 53 -j REDIRECT --to-ports 53
iptables -t nat -I PREROUTING -p udp --dport 53 -j REDIRECT --to-ports 53

And in the end the NETWORK file:

config interface 'loopback'
option ifname 'lo'
option proto 'static'
option ipaddr '127.0.0.1'
option netmask '255.0.0.0'

config globals 'globals'
option ula_prefix 'fdd9:ed74:2177::/48'

config interface 'lan'
option type 'bridge'
option ifname 'eth0.1'
option proto 'static'
option ipaddr '192.168.1.1'
option netmask '255.255.255.0'
option ip6assign '60'
option dns '208.67.222.222 208.67.220.220 8.8.8.8 8.8.4.4'

config interface 'wan'
option ifname 'eth1.2'
option _orig_ifname 'eth1.2'
option _orig_bridge 'false'
option proto 'pppoe'
option username 'aliceadsl'
option password 'aliceadsl'
option ipv6 'auto'
option peerdns '0'

config interface 'wan6'
option ifname 'eth1.2'
option proto 'dhcpv6'

config switch
option name 'switch0'
option reset '1'
option enable_vlan '1'

config switch_vlan
option device 'switch0'
option vlan '1'
option ports '0 1 2 3 5t'

config switch_vlan
option device 'switch0'
option vlan '2'
option ports '4 6t'

config interface 'languest'
option _orig_ifname 'wlan1-1'
option _orig_bridge 'false'
option proto 'static'
option ipaddr '192.168.2.1'
option netmask '255.255.255.0'
option dns '208.67.222.222 208.67.220.220'

config interface 'vpn0'
option ifname 'tun0'
option proto 'none'
option auto '1'

Unfortunately it seems the DNS have been assigned randomically and I can't allow some clients to select DNS by their own (rule 3).

So what I can do (or in which way i can modify those files) in order to have all the funcionalities of the DNS Filter?

That's not something dnsmasq can enforce, but you can redirect all traffic for port 53 to your router (and its listening dnsmasq instance). The easiest approach would be installing luci-app-adblock and enable forcedns, even if you don't enable any of its blocklists - but you can also replicate the firewall rules it would add yourself (see the relevant adblock source for details, you can also refine those rules for individual source addresses).

You can set the router DNS to either DHCP (the IPs DNS servers) or custom DNS servers in the GUI. In firewall rules you can prevent clients bypassing these (by setting their own DNS in the network properties on their machine) by redirecting to the router (as slh suggests) or by blocking port 53 i.e. it wont allow external DNS requests but will allow requests to the router. You can use the ip-range command in the firewall to limit this restriction to the ip address of the clients you want to force to use the routers dns.

Ok, I tried the rule to force DNS of Adblock and I understand in that way only the DNS defined for the interfaces have been used (not the ones I set with dhcp_option in the dhcp file), that are the ones on the resolv.conf file. If I don't use this rule on the firewall, then the dhcp assign correctly the DNS to each client.

If I use the rule to redirect the DNS of the client to the router (and I kindly ask you to make an example of this rule, since I'm not an expert), will the client use the DNS I specify for the dhcp or still the ones on resolv.conf?

Is that a way to define a resolv.conf file x IP or MAC-ADDRESS eventually?

I'm a novice at this, but I just worked through a similar issue requiring redirecting all DNS traffic back to the router. In my case, one of my devices was running it's own DNS server and ignoring the gateway DNS settings. The rule I'm using, which is working well, is:

iptables -t nat -I PREROUTING -i br-lan2 -p udp --dport 53 -j DNAT --to 192.168.2.1

I put this under Firewall - Custom Rules tab. br-lan2 is the name of the LAN interface (if you have a vanilla configuration, change it to br-lan.) 192.168.2.1 is the address of the router (any DNS address can be used.)

This rule rewrites the destination IP addresses of any incoming packets on port 53 to the address of your router instead. Your router will then forward the packets along to whatever DNS server you have set in the routers config. I also disabled IPv6 for different reasons. That is unlikely to affect this, but it's worth mentioning as it's the only part of my config that differs from the vanilla defaults. (I also have a WRT3200ACM.)

More info:


https://www.frozentux.net/iptables-tutorial/chunkyhtml/x4033.html

Once you have the firewall package, there's already a chain called 'prerouting_lan_rule' defined as part of the 'nat tablle' through which everything from the LAN side will go (it in turn is called from the PREROUTING chain with the lan side interface specified as the incoming interface - so you don't need to re-specify this as part of the rule set ).

You can then do something like this (i'm using this within an internal router with no other NATting - so could use either -A or -I, but using -I means that it will also come ahead of any rules defined as part of the firewall itself, which would include the default NATting when LEDE is used as the gateway).

iptables -t nat -N DNSFILTER
iptables -t nat -I prerouting_lan_rule -p tcp -m tcp --dport 53 -j DNSFILTER
iptables -t nat -I prerouting_lan_rule -p udp -m udp --dport 53 -j DNSFILTER

and then put the specific DNAT rules in the DNSFILTER chain thus defined - this replicates the arrangement that asuswrt uses.

iptables -t nat -A DNSFILTER -m mac --mac-source X:X:X:X:X:X -j DNAT --to-destination 199.85.126.30
iptables -t nat -A DNSFILTER -j DNAT <router.ip>

The example above shows a DNAT to one of the norton connectsafe DNS servers, and a catchall rule that redirects all other traffic to the router.ip.

1 Like

I'm now using these 'custom firewall rules', coupled with additional 'ip rules/routes' (listed in /etc/rc.local) + 'reserved IP addresses', to route DNS requests to specific DNS IP's based on IP address, instead of my WAN configured Privateinternetaccess VPN DNS servers.

Thanks you SO much cbz for this explanation!

There's only one caveat, I also need to disable IPV6 on the adapters/devices that support it for this to work as intended ¯ \(ツ)/ ¯ but it works beautifully!

This uci rule should work as well, without the need for any custom iptables chains:

config redirect
	option name 'Divert DNS'
	option proto 'udp tcp'
	option src 'lan'
	option src_dport '53'
	list src_mac '00:11:22:33:44:55'
	list src_mac 'aa:bb:cc:dd:ee:ff'
	option target 'DNAT'

I find it very easy to change the configuration within the 'LEDE firewall GUI', quickly altering then hitting the 'Restart Firewall' button, without the need of rebooting the router.

ATM I'm not sure how to implement your workaround with my objective.

My setup:
PC/devices => LEDE VPN router => ISP Modem/router => Internet

The idea is to have:
-all devices on the VPN (using VPN IP & VPN DNS),
-except some to appear as directly connected to my ISP (using ISP IP & ISP DNS),
-and others accessing US Netflix from abroad (using ISP supplied IP & SmartDNSProxy DNS)

The catalyst stemmed from trying to access US Netflix from abroad, and so far all working as planned!

How do I specify the DNAT target?