I know this question has been asked historically, but the answers I have yet to find are not all too helpful in this one niche use case.
I currently have one router running DD-WRT on 192.168.0.1, one router connected to the previous with IP 192.168.0.2 that runs as a VPN client, and one Raspberry Pi set up to run https://pi-hole.net DNS filtering on 192.168.0.21.
Ultimately, my goal here is just to block all DNS requests on my network from any device to any DNS server except for my second router and my pihole, and to allow only those two devices to make DNS requests.
On my router, my current Firewall(iptables) rules are as follows:
#####Keep network on pi-hole
iptables --table nat --insert PREROUTING --in-interface br0 --protocol tcp --source ! 192.168.0.2,192.168.0.21 --destination-port 53 --jump DNAT --to-destination 192.168.0.21:53
iptables --table nat --insert PREROUTING --in-interface br0 --protocol udp --source ! 192.168.0.2,192.168.0.21 --destination-port 53 --jump DNAT --to-destination 192.168.0.21:53
#####Punch DNS hole for pi-hole
iptables --table nat --insert PREROUTING --in-interface br0 --protocol tcp --source 192.168.0.2,192.168.0.21 --destination-port 53 --jump ACCEPT
iptables --table nat --insert PREROUTING --in-interface br0 --protocol udp --source 192.168.0.2,192.168.0.21 --destination-port 53 --jump ACCEPT
Now, I had just assumed this was all working fine and dandy. However, I never actually went in and tried to test the rules. Upon trying to execute the commands, I find that rules 3 and 4 work fine. However, rules 1 and 2 do not:
root@ddwrt:~# iptables --table nat --insert PREROUTING --in-interface br0 --protocol tcp --source ! 192.168.0.2,192.168.0.21 --destination-port 53 --jump ACCEPT
Bad argument `192.168.0.2,192.168.0.21'
Some research led to me thinking maybe the !
should go before the --source
, so I tried that, which might have worked, except multiple source IP addresses are disallowed by my version of iptables:
root@ddwrt:~# iptables --table nat --insert PREROUTING --in-interface br0 --protocol tcp ! --source 192.168.0.2,192.168.0.21 --destination-port 53 --jump ACCEPT
iptables v1.8.5 (legacy): ! not allowed with multiple source or destination IP addresses
More research led me to attempt using ipset to solve the problem:
root@ddwrt:~# ipset -N piholeAndVpnPassthrough iphash
root@ddwrt:~# ipset -A piholeAndVpnPassthrough 192.168.0.2
root@ddwrt:~# ipset -A piholeAndVpnPassthrough 192.168.0.21
That part went fine. However, having never used ipset, I couldn't get it to work in any manner I tried:
root@ddwrt:~# iptables --table nat --insert PREROUTING --in-interface br0 --protocol tcp ! --source --match-set "piholeAndVpnPasshthrough" --destination-port 53 --jump DNAT --to-destination 192.168.0.21:53
Bad argument `piholeAndVpnPasshthrough'
Try `iptables -h' or 'iptables --help' for more information.
root@ddwrt:~# iptables --table nat --insert PREROUTING --in-interface br0 --protocol tcp ! --source -m set --match-set piholeAndVpnPasshthrough --destination-port 53 --jump DNAT --to-destination 192.168.0.21:53
Bad argument `set'
Try `iptables -h' or 'iptables --help' for more information.
root@ddwrt:~# iptables --table nat --insert PREROUTING --in-interface br0 --protocol tcp -m set --match-set piholeAndVpnPasshthrough ! --source --destination-port 53 --jump DNAT --to-destination 192.168.0.21:53
iptables v1.8.5 (legacy): --match-set requires two args.
Try `iptables -h' or 'iptables --help' for more information.
root@ddwrt:~# iptables --table nat --insert PREROUTING --in-interface br0 --protocol tcp -m set --match-set piholeAndVpnPasshthrough src ! --source --destination-port 53 --jump DNAT --to-destination 192.168.0.21:53
iptables v1.8.5 (legacy): Set piholeAndVpnPasshthrough doesn't exist.
Thus, I have no idea how to accomplish this. How does one use two negated source addresses in iptables?