3

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
2
  • While I don't have an answer for you, this isn't going to work like you hope. IPTables works on a per-packet level. Are you sure that every possible HTTP request is going to have 'sub.domain.com' in every single packet? On a normal web request, that's not going to be the case. The better solution is to find the IP for sub.domain.com, and only allow traffic to/from that.
    – devicenull
    Jun 14, 2012 at 1:54
  • Perhaps I didn't explain well. sub.domain.com is hosted on one of our server among other websites, requesting any other website but sub.domain.com shouldn't be allowed. I'm not sure what do you mean with the IP for sub.domain.com? our server IP? Thanks
    – Blake S.
    Jun 14, 2012 at 2:08

3 Answers 3

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.

0

This will not do what you want. You can effectively limit access to a host with iptables. In your case limit access to the IP address of the server hosting the site. This will still allow access to other domains hosted by that server.

You could use a proxy like squid in transparent proxy mode and use an ACL in it to limit access to the site you allow. Use a DNAT rule to redirect all HTTP accesses to your proxy. A rule like this should redirect web traffic to the proxy on port 3129:

iptables -t nat -A PREROUTING -p tcp --dport 80 ! -d 127.0.0.1 -j DNAT --to-destination $SQUID:3129
1
  • Currently all domains are sharing the same IP (virtualhosts), so I can't limit access to the IP address of the server hosting sub.domain.com. I was thinking a simpler way than using squid, but thanks for the proxy idea.
    – Blake S.
    Jun 14, 2012 at 4:12
0

Use squid to limit all the domain you want on http protocol, easy to configure

and for https protocols use: iptables -A FORWARD -m string --string "facebook.com" --algo bm --from 1 --to 600 -j REJECT

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .