Pi-hole interaction with iptables/BanIP

I am using ipset with Pi-hole for a long time. It is very performant and a lot better than what other popular script like fail2ban are doing with adding thousands of individual rules to the firewall.

The dnsmasq man page wrongly suggests that you need a domain for this to work but maybe this is only a Pi-hole enhancement. You can simply use

ipset=pihole

to add the IPs of all queries to the pihole ipset. You can see what happens as lines like ipset add ... are added to /var/log/pihole.log if you do it properly.

The ipset needs to exist, created by something like

ipset create pihole hash:ip

or you will see errors.

First, add a rule for the Pi-hole itself that allows the Pi-hole to connect to ports 53 worldwide to exclude the Pi-hole from being blocked to reach the DNS servers:

iptables -A INPUT -d 127.0.0.1 --sport 53 -m state --state ESTABLISHED -j ACCEPT
iptables -A OUTPUT -s 127.0.0.1 --dport 53 -m state --state NEW,ESTABLISHED -j ACCEPT

Finally, configure iptables to permit only addresses in that set:

iptables -I INPUT -m set --match-set pihole src -j ACCEPT
iptables -I FORWARD -m set --match-set pihole dst -j ACCEPT
iptables -I OUTPUT -m set --match-set pihole dst -j ACCEPT

and set the default policies to DROP:

iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP

This configures you firewall to only permit outgoing and forwarding to and incoming from traffic to IP addresses derived via DNS.

Pro tips:

  • You can check the IP addresses with ipset list pihole
  • Do the same for IPv6 using ip6tables
  • Add Pi-hole port 53 rules for IPv6, too
  • The ipset you have created is stored in memory for speed. It will be gone after reboot. Use ipset save > /some/backup.file to backup your ipset when rebooting or your clients may experience issues when rebooting the device.
4 Likes