Iptables rule to block all web requests to domain.com

I know this is not the best solution, and it's not a production server, however, I'm still trying to drop requests to a domain if it doesn't match the domain string.

So far it works if I apply the rule by itself, but it won't work in conjunction with the other rules. I'm guessing is due Iptables being sensitive to the order.

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

   # Allow unlimited traffic on loopback
   iptables -A INPUT -i lo -j ACCEPT
   iptables -A OUTPUT -o lo -j ACCEPT

   # Allow full outgoing connection but no incomming stuff
   iptables -A INPUT -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
   iptables -A OUTPUT -o eth0 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT

   # Block sites
   iptables -I INPUT -p tcp --dport 80 -j ACCEPT 
   iptables -I INPUT 1 -p tcp --dport 80 -m string --string ! "sub.domain.com" --algo kmp -j DROP

   iptables -A INPUT -i eth0 -j DROP
   iptables -A OUTPUT -j DROP

Solution 1:

Iptables is definitely sensitive to the rule ordering. The first match decides the fate of the packet.

What may be happening is that you have a rule matching and accepting ESTABLISHED packets before the string DROP rule. It's very common for the ESTABLISHED rule be one of the first rules in an iptables setup.

A connection gains the ESTABLISHED state right after the first SYN packet, if I'm not mistaken. And the SYN packet does not contain the host-header-name with "sub.domain.com". Only the packet with the GET request will contain that, and it will already match the ESTABLISHED rule.

The solution would be to place the string DROP before the ESTABLISHED one.

Having said that, you solution is quite unusual, and might even put the server to some trouble, if by any chance the volume of these blocked requests got high. The connection is established but then the client quiets down. The server will be waiting, until some timeout terminates the thing. I don't exactly what will happen, but watch out.

I supposed you for some reason can't change the server config to block those specifics connection there. In apache it's piece of cake setting that kind of control.