Iptables: Allow connections on a port to only “safe” hosts

iptables

I have a centos machine and wish to only allow outbound connections to port 587 to certain remote machines, and drop packets trying to connect to all other hosts.

I only want to allow access on port 587 if they are going to access gmail's SMTP servers (all IPs behind smtp.gmail.com). Is there a way I can implement this?

Best Answer

You can use the -d switch to iptables rules which makes the rule work for just the address supplied and then block everything else e.g.

iptables -I OUTPUT -p tcp --dport 587 -j DROP
iptables -I OUTPUT -d smtp.gmail.com -p tcp -m tcp --dport 587 -j ACCEPT

should do what you want. This initially inserts a DROP all outgoing connections on port 587 rule into the beginning of the OUTPUT chain. It then inserts an allow rule for smtp.gmail.com port 587 into the beginning of the OUTPUT chain. This has the effect of allowing connections to smtp.gmail.com:587 and blocking everything else on port 587 e.g.

iptables -L OUTPUT -n
Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     tcp  --  0.0.0.0/0            173.194.66.109      tcp dpt:587
ACCEPT     tcp  --  0.0.0.0/0            173.194.66.108      tcp dpt:587
DROP       tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:587

Note that smtp.gmail.com resolves to two ip addresses which is why there are two ACCEPT rules above. The name is only resolved once when the rule is added to the kernel so if the addresses are changed then connections to gmail will be blocked too and you would need to reload the rules.