Created
April 14, 2023 09:04
-
-
Save will/d98519cd7e3d26e4f549994cf0b2e636 to your computer and use it in GitHub Desktop.
iptable rule maker
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
### Generate a list of iptables rules to redirect port 53 traffic (tcp+udp) and echo to console. | |
### This version of the script does NOT apply anything to the iptables on the machine it is run on. | |
### IPv4 DNS traffic is redirected to $PRIMARYDNS_IPV4 on port 53 | |
### IPv6 DNS traffic is redirected to $PRIMARYDNS_IPV6 on port 53 | |
# This is the DNS that you want clients to be forced to use on your network | |
# If you have a secondary DNS, add it to the whitelist below and it will still work. | |
PRIMARYDNS_IPV4="192.168.1.12" | |
# Add ALL your whitelisted DNS servers to this variable, separated by a space | |
# These are any name servers that will not be rerouted to the primary DNS. | |
# Recommend you include your router address so that DNS for local machines will still work. | |
# if left blank (""), PRIMARYDNS_IPV4 will still be whitelisted. | |
# e.g. "192.168.1.1 192.168.1.2" etc. | |
DNSWHITELIST_IPV4="192.168.1.12 192.168.1.1" | |
# Leave this blank if you don't use IPv6. | |
PRIMARYDNS_IPV6="" | |
# Add ALL your whitelisted DNS servers to this variable, separated by a space. | |
# In my experience it is best practice to include every ipv6 address that each | |
# DNS server uses. I have observed packets sent to my pi-hole by all 3 ipv6 addresses it obtains | |
# even though only one is listed in DHCP. | |
# e.g. "ffff::1234 ffff:ffff:ffff:ffff::5678" etc. | |
DNSWHITELIST_IPV6="" | |
# Set this to add exception mac addresses that will not be forced to use the primary DNS server | |
# Separate MAC addresses with spaces. | |
EXCEPTION_MACS="" | |
# Set this to the interfaces you want to force through the DNS IP. | |
# Separate interfaces with spaces. | |
# on most routers this is br0. | |
# if you have multiple subnets you might need to add more bridge interfaces to this list. | |
# e.g. "br0" or "br0 br1" etc. | |
FORCED_INTFC="br0" | |
# Enable this if your pihole is on the same subnet as the devices/interfaces | |
# you are forwarding. This will allow the return traffic to work on the same | |
# subnet, but will make the pihole think the requests are coming from the router. | |
# You will lose client information in the pihole dashboard if you enable this. | |
# It is preferable to put the pihole on a different subnet and disable this. | |
ENABLE_MASQUERADE=1 | |
###IPV4 SECTION### | |
#using ipsets to make whitelists lets us limit wasteful rerouting and reduce potential for DNS loops | |
# create dnsv4 ipset | |
echo "ipset create dnsv4 hash:ip family inet" | |
echo "ipset add dnsv4 ${PRIMARYDNS_IPV4}" | |
if [ -n "${DNSWHITELIST_IPV4}" ]; then | |
for ip in ${DNSWHITELIST_IPV4}; do | |
echo "ipset add dnsv4 ${ip}" | |
done | |
fi | |
#create new DNSCONTROL chain with exceptions | |
echo "iptables -t nat -N DNSCONTROL" | |
#add exceptions that won't get forcibly routed - their DNS requests get routed based on their internal settings. | |
if [ -n "${EXCEPTION_MACS}" ]; then | |
for mac in ${EXCEPTION_MACS}; do | |
dnscontrol_rule="DNSCONTROL -m mac --mac-source ${mac} -j RETURN" | |
echo "iptables -t nat -A ${dnscontrol_rule}" | |
done | |
fi | |
#Everything else is DNAT'd into the pihole. | |
for proto in tcp udp; do | |
dnscontrol_rule="DNSCONTROL -p ${proto} -j DNAT --to ${PRIMARYDNS_IPV4}:53" | |
echo "iptables -t nat -A ${dnscontrol_rule}" | |
done | |
# rules to push DNS traffic into DNSCONTROL chain | |
for intfc in ${FORCED_INTFC}; do | |
for proto in tcp udp; do | |
prerouting_rule="PREROUTING -i ${intfc} -p ${proto} --dport 53 -m set ! --match-set dnsv4 src -m set ! --match-set dnsv4 dst -j DNSCONTROL" | |
echo "iptables -t nat -A ${prerouting_rule}" | |
done | |
done | |
#MASQUERADE rules for ipv4 | |
if [ "$ENABLE_MASQUERADE" = "1" ]; then | |
for proto in udp tcp; do | |
postrouting_rule="POSTROUTING -p ${proto} --dport 53 -m set ! --match-set dnsv4 src -m set --match-set dnsv4 dst -j MASQUERADE" | |
echo "iptables -t nat -A ${postrouting_rule}" | |
done | |
fi | |
###IPV6 SECTION### | |
# This section is skipped entirely if PRIMARYDNS_IPV6 is not set! | |
if [ -n "${PRIMARYDNS_IPV6}" ]; then | |
# create dnsv6 ipset | |
echo "ipset create dnsv6 hash:ip family inet6" | |
echo "ipset add dnsv6 ${PRIMARYDNS_IPV6}" | |
if [ -n "${DNSWHITELIST_IPV6}" ]; then | |
for ip in ${DNSWHITELIST_IPV6}; do | |
echo "ipset add dnsv6 ${ip}" | |
done | |
fi | |
# create new DNSCONTROL chain with exceptions | |
echo "ip6tables -t nat -N DNSCONTROL" | |
# add exceptions that won't get forcibly routed - their DNS requests get routed based on their internal settings. | |
if [ -n "${EXCEPTION_MACS}" ]; then | |
for mac in ${EXCEPTION_MACS}; do | |
dnscontrol_rule="DNSCONTROL -m mac --mac-source ${mac} -j RETURN" | |
echo "ip6tables -t nat -A ${dnscontrol_rule}" | |
done | |
fi | |
# Everything else is DNAT'd into the pihole. | |
for proto in tcp udp; do | |
dnscontrol_rule="DNSCONTROL -p ${proto} -j DNAT --to [${PRIMARYDNS_IPV6}]:53" | |
echo "ip6tables -t nat -A ${dnscontrol_rule}" | |
done | |
# rules to push DNS traffic into DNSCONTROL chain | |
for intfc in ${FORCED_INTFC}; do | |
if [ -d "/sys/class/net/${intfc}" ]; then | |
for proto in tcp udp; do | |
prerouting_rule="PREROUTING -i ${intfc} -p ${proto} --dport 53 -m set ! --match-set dnsv6 src -m set ! --match-set dnsv6 dst -j DNSCONTROL" | |
echo "ip6tables -t nat -A ${prerouting_rule}" | |
done | |
fi | |
done | |
# MASQUERADE rules for ipv4 | |
if [ "$ENABLE_MASQUERADE" = "1" ]; then | |
for proto in udp tcp; do | |
postrouting_rule="POSTROUTING -p ${proto} --dport 53 -m set ! --match-set dnsv6 src -m set --match-set dnsv6 dst -j MASQUERADE" | |
echo "ip6tables -t nat -A ${postrouting_rule}" | |
done | |
fi | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment