Iptables and OpenVZ

Da My-Lab.


The fact is: iptables are a nasty beast. You'll have to be very careful about them. But in order to achieve a secure linux installation it is important to master the beast.

There are quite some alternatives, scripts which act as a frontend to iptables. Ufw (built by the Ubuntu team) is great. Quite a few commands and you're done, nice messages, debug made easy. But it will not work on an OpenVZ contained Ubuntu or Debian installation; 'cause the system has a different setup than that of a standalone machine. And, even if it worked, it generates a lot of rules in your iptables which might slow down your system while performing tasks you don't even know about.

Another alternative is shorewall, which claims to work on an OpenVZ contained installation, but it's not as easy as ufw is; and one might wonder if it's worth the pain to learn it, when one can learn iptables and do more with them. Debian also has some hosts.allow/hosts.deny rules, but you're better keep away from them, since only some software is built to work with them. And, no, by default Apache is not built to cope with those rules.

So here we are, alone in the firewall world, left with nothing but naked iptables to rely on. But if what we want to do is simple, our rule will be simple as well. But please ear this words of caution:

DON'T MESS WITH IPTABLES IF YOU DON'T HAVE A PYHSICAL/KVM ACCESS TO YOUR MACHINE

OR

YOU WILL BE KICKED OUT, WITH NO CHANCES TO GAIN BACK YOUR ACCESS!!!

Damn, that's true. You'll know it's true. Anyway, let's go on. These are my rules:

# reset
iptables -F
iptables -X
# default policy
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
# openvz policy
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
# open ports
# ssh
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# smtp (incoming mail)
iptables -A INPUT -p tcp --dport 25 -j ACCEPT
# web
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
# ssl
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# pop
iptables -A INPUT -p tcp --dport 110 -j ACCEPT
# imap
iptables -A INPUT -p tcp --dport 143 -j ACCEPT

Let's analyze them block by block.

# reset
iptables -F
iptables -X

This resets everything. Word of caution: this might be enough to kick you out from any ssh session.

# default policy
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

This establish default rules (if no specific rule is given, this will suffice). In this case, no input is allowed, no forward is allowed, any output is allowed. Our linux box will act as a lamp with no switch: it will still emit signals, but it won't accept any input. You will be kicked out from any ssh session.

# openvz policy
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

Yet this is important for how OpenVZ works. You'll need to ensure that your machine is still able to communicate with its container. If you don't, no matter what the rules who follow say, nothing will get inside your virtual machine.

# open ports
# ssh
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# smtp (incoming mail)
iptables -A INPUT -p tcp --dport 25 -j ACCEPT
# web
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
# ssl
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# pop
iptables -A INPUT -p tcp --dport 110 -j ACCEPT
# imap
iptables -A INPUT -p tcp --dport 143 -j ACCEPT

And last, but not least, open the port which will enable our users to put some request to our server, those are, in order: ssh (vital, you know...), smtp, http, ssl, pop3 and imap2. You'll might need different port if you use secured pop/imap. If your server does not act as a mail server, you won't need smtp, pop and imap as open ports. In some cases other port might need to be open, for services such as vnc (are you lazy and don't you like the shell?) (5800, 5900 tcp), dns (53 tcp&udp), ftp, (20, 21 tcp). Take a look here for more informations: http://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers

When you're done, remember to save your rules, so that they will be brought back when you'll (have to) restart your machine. See here: http://wiki.debian.org/iptables

A last word is, if you add some rule, for example a DENY over an ACCEPT, it won't delete the old rule, unless you ask for it: use

iptables -R

instead.

iptables -R INPUT 5 -p tcp --dport 80 -j DROP
iptables -R INPUT 5 -p tcp --dport 80 -j ACCEPT

would turn the 5th rule into a WWW rule, and accept or deny it.

Use

iptables -L

to check.

That's all. Hope this helps you! Don't fear the beast, rule it!