Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

I have a couple of public webservers and some home based Ubuntu machines. I maintain a couple of domains specifically to monitor things like MySQL and Memcache. Ideally I'd be able to connect to MySQL, Memcache, etc from my home machines while denying everyone else access.

So my iptables currently are:

ACCEPT     tcp  --  home ip              0.0.0.0/0            tcp dpt:3306
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:222
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:80
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:443
ACCEPT     all  --  server 1 ip          0.0.0.0/0
ACCEPT     all  --  server 2 ip          0.0.0.0/0
ACCEPT     all  --  server 3 ip          0.0.0.0/0
DROP       all  --  198.245.49.225       0.0.0.0/0
DROP       all  --  0.0.0.0/0            0.0.0.0/0

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

I'd like to extend my iptables such that I can access everything from home. I figure it is probably good practice to add a line for my home ip for each port I want rather than giving my home ip access to every port. But maybe it doesn't matter. Additionally I want to run things like phpMemcachedAdmin without requiring a password.

So I have run a couple of Google searches on how to deny access to a domain to the whole world. I figure I put in a line allowing my ip on port 80 just above the line denying access to the domain to the whole world and (fingers crossed) I should be blocking everyone but me.

The posts I've seen in my Google searches said you could block a domain via -m string "Host: domain.com" or via --string "domain.com". Neither appears to work. Here's what I've tried:

sudo iptables -I 9 -p tcp --dport 80 -m string "Host: domain.com" --algo bm -j DROP
sudo iptables -I 9 -p tcp --dport 80 -m string "domain.com" --algo bm -j DROP
sudo iptables -I 9 -p tcp --dport 80 --string "domain.com" --algo bm -j DROP

The first two error out with Bad argument 'Host:...' and the last one errors out on unknown option "--string".

To make matters a little more complicated my home IP is dynamic not static. So it would be nice to have (but not essential) the ability to allow my home ip via a DynDNS domain I've setup. I've got a script for stopping and starting iptables so if I need to I can always stop and restart it to force the IP to update. (I've read in several places that iptables only checks for an IP for domain at startup.)

I welcome any security related advice on the use of iptables for your standard webserver as well.

Thanks


3/17/14 Additions: I found the syntax error in my iptables line - the -m string should be -m string --string. Now it appears that I have iptables recognizing the domain I want to keep people out of. However, the issue then became the order of the iptables rules.

My new iptables became:

Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0
ACCEPT     all  --  Server 1 IP          0.0.0.0/0
ACCEPT     all  --  Server 2 IP          0.0.0.0/0
ACCEPT     all  --  Server 3 IP          0.0.0.0/0
DROP       all  --  198.245.49.225       0.0.0.0/0
DROP       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:80 STRING match  "str_for_matching" ALGO name bm TO 65535
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:222
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:80
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:443
DROP       all  --  0.0.0.0/0            0.0.0.0/0

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

The idea would be to catch my IP before the DROP that matches the string. If the DROP is the first line then it catches it and I get a 502 error. However, if the iptables are as I've listed then the requests get through - my home IP isn't in the rule table yet.

The one that works looks like this:

Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all  --  Server 1 IP          0.0.0.0/0
ACCEPT     all  --  Server 2 IP          0.0.0.0/0
ACCEPT     all  --  Server 3 IP          0.0.0.0/0
ACCEPT     all  --  My Home IP           0.0.0.0/0
ACCEPT     all  --  My Laptop IP         0.0.0.0/0
DROP       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:80 STRING match  "str_to_match" ALGO name bm TO 65535
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0
DROP       all  --  198.245.49.225       0.0.0.0/0
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:222
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:80
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:443
DROP       all  --  0.0.0.0/0            0.0.0.0/0

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

I was able to get my dynamic IPs included by simply using their DynDNS domain name instead of an IP.

I could probably make this the answer but I'd like some advice on best practice with regards this problem.

share|improve this question

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.