How to Whitelist a Domain and Subdomains in IPTABLES

bashiptables

#!/bin/bash
IPT="/sbin/iptables"

Using a drop all policy for IPTABLES

echo "Set default policy to 'DROP'"
$IPT -P INPUT   DROP
$IPT -P FORWARD DROP
$IPT -P OUTPUT  DROP

Trying to define specific rules for OUTPUT connections that include all subdomains of a domain. The reason being that in a multi step protocol, the server recieves a callback URL of a potentially unknown subdomain.

These niave rules don't work…

$IPT -A OUTPUT -p tcp -d "*.example.com" -m state --state NEW,ESTABLISHED -j ACCEPT
$IPT -A OUTPUT -p tcp -d "example.com" -m state --state NEW,ESTABLISHED -j ACCEPT

Reading around I see that wild cards do not work, and that IPTABLES is not a DNS resolver… !! waaaah! shouldn't the latter rule work for all ports and all subdomains?

So far my only solution is allowing all OUTPUT traffic like this

$IPT -I OUTPUT -o eth0 -d 0.0.0.0/0 -j ACCEPT
$IPT -I INPUT -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT

I'm thinking maybe using this 'conntrack' rule would be more appropriate?

#$IPT -A OUTPUT -m conntrack --ctstate NEW,ESTABLISHED,RELATED -j ACCEPT

I'd prefer to be more restrictive, how can I create a specific rule/ruleset for a domain and its subdomains?

Best Answer

Nope, iptables is the wrong tool for this task.
At the level that iptables works the hostname is not applicable. When you add a rule for "example.com" it is resolved to an IP address and stored that way. If the DNS for example.com changes, the rule is no longer working as intended.

If you are trying to limit outbound connections to DNS names, you will need to use something involved in resolving DNS. For example, to blacklist a domain name, say "coinhive.com" as an example, I have this in my /etc/hosts file: 0.0.0.0 coinhive.com. This prevents anything from contacting that domain no matter what IP address is points to on the internet.

In order to white list by domain name, you could run a DNS resolver locally and only provide the entries you want and not forward unknown hostnames.

I'm sure there are a few more ways to accomplish this, but iptables is not one of them.

Related Topic