Iptables – Making iptables easier to maintain

domain-name-systemfirewallhostnameip addressiptables

My network is completely locked down except for a few sites which are whitelisted. This is all done through iptables, which looks something like this:

# Allow traffic to google.com
iptables -A zone_lan_forward -p tcp -d 1.2.3.0/24 -j ACCEPT
iptables -A zone_lan_forward -p udp -d 1.2.3.0/24 -j ACCEPT
iptables -A zone_lan_forward -p tcp -d 11.12.13.0/24 -j ACCEPT
iptables -A zone_lan_forward -p udp -d 11.12.13.0/24 -j ACCEPT
iptables -A zone_lan_forward -p tcp -d 101.102.103.0/24 -j ACCEPT
iptables -A zone_lan_forward -p udp -d 101.102.103.0/24 -j ACCEPT
...

Obviously those addresses are hypothetical, but you get the idea. My firewall is becoming enormous. It would be much easier to maintain if I could just do this:

# Allow traffic to google.com
iptables -A zone_lan_forward -p tcp -d google.com -j ACCEPT
iptables -A zone_lan_forward -p udp -d google.com -j ACCEPT

I believe this is possible, since man iptables says:

Address can be either a network name, a hostname (please note that specifying any name to be resolved with a remote query such as DNS is a really bad idea), a network IP address (with /mask), or a plain IP address.

But what I'm concerned about is the part that says "specifying any name to be resolved with… DNS is a really bad idea". Why is this a bad idea? Does it just slow everything down?

If I really shouldn't use hostnames in iptables rules, then what should I do to simplify my firewall?

Best Answer

  • DNS Names are resolved when the rules are added, not, when packets are checked. This violates the expectations most people have.
    • The rule does not get updated to reflect changed DNS results. It is resolved when added and that is it. You will need to either periodically reload rules, or some sites may break.
  • There is a bit of a security issue in that you are basically delegating control of your firewall rules to an external entity.
    • What if your parent DNS server is compromised and returns false data.

If your purpose is to block HTTP access, then you are usually far better of setting up a piece of software designed to filter at that level (e.g. squid+squidquard).