My iptables tutorial
Securing your Linux-based computer with the best Linux firewall in the world... the kernel itself.
Effective iptables starters
In case you didn't know, iptables is built into the Linux kernel. It's provided with virtually every distro ever. And other than BSD's pf, it's the most powerful firewall around.
Getting started
You will want to start with the following commands to get your iptables rules laid out right: (The # means run as root here)
# iptables -A INPUT -i lo -j ACCEPT
# iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
# iptables -A INPUT -j DROP
What does this mean?
The first rule accepts all packets from yourself. lo refers to the Loopback adaptor. If you run a webserver or fileserver or any other network-accessible service and you want it available to yourself, you need this to accept.
The next rule matches all packets that are related to open connections or part of tcp connections in the ESTABLISHED state. In other words, this rule accepts all packets that are in response to packets you sent out. This includes webpages that come back in response to the http get request from your web browser.
The last rule applied to all packets that didn't match the rules before it. Any packet that came from another computer and wasn't RELATED or part of an ESTABLISHED connection gets checked against this rule. This rule doesn't check anything, so all packets that get that far will match. And they will get dropped.
The most
important thing to remember about internet security is that you want to
give as little information as possible to a potential attacker. That
means (among other things) stealthing every port you don't need opened.
Why do we want to drop everything else?
It's common sense. If you want someone to go away, you don't tell them to piss off (ie reject the packet with a RST). You ignore them. Give no response whatsoever. Pretend they don't exist.
When someone tries to portscan you, they will get nothing back. There will be no indication that there is a computer to scan and they will eventually leave. If, on the other hand, you tried to reject the unwanted packets, the person scanning you would know you are there and try harder to get your attention. Maybe they'll try some yet-unknown exploit and/or a DDoS attack (the latter would get my attention). It doesn't matter. You never want to respond to strange unsolicited traffic directed at you.
This leaves no ports open! I can't be a server!
Indeed. Here's what to add if you want to open a port:
# iptables -I INPUT 2 -p tcp --dport $portToOpen -j ACCEPT
Let's dissect that rule. The most obvious difference is that this rule will accept matching packets. Great. let's explain the more cryptic stuff.
The first diffrence is I used -I instead of -A. That means the rule will be inserted into the rules instad of getting appended to the end. You want this rule to check packets before the catch-all DROP rule we put at the end. In this case, we want to insert it before the second rule, hence the 2.
The next difference is the -p argument. This specifies the protocol to match. In this case, we specify Transmission Control Protocol (TCP). We could also specify User Datagram Protocol (UDP), Internet Control Message Protocol (ICMP), Internet Group Management Protocol (IGMP), and many others.
After that, we specify the port with --dport. There are 2**16-1 ports in IP packets (0 is not a legal port according to the IP spec). I used $portToOpen as a placeholder for the port you want to open. Depending on your environment settings, you can actually specify that variable (but I would recommend against that).
So this rule will accept all incoming packets on port $portToOpen. Incidentally, I recommend that if you open a port it be a non-standard port. If you open port 22, you will get constant attempts by outsiders to gain SSH access to your computer. And that's bad.
So I'm perfectly stealthed like a ninja now, huh?
Not so fast there. That port you opened defeats the purpose like wearing camouflage in a subway station. Moreover, your computer may still send out unwanted ICMP packets because of adherence to one spec or another. To be sure, go to ShieldsUp! (scroll down a little to find it) and proceed. Do a full scan and you will see that your iptables config is not perfectly stealthy yet.
So next up, I will how you how to block outgoing packets.
So how do I block outgoing packets?
In a way strikingly similar to blocking incoming packets:
# iptables -I OUTPUT -p icmp --icmp-type 0 -j DROP
ICMP type 0 is echo reply. It's the pong to a ping. When someone pings your machine (essentially "are you there?"), your machine sends a pong back (essentially "yes I'm here"). You don't want to do that on the internet, so we drop the packet.
But don't rest on your laurels yet. Pings aren't the only way to test a machine's existence. They can also send a timestamp message, which will make your computer send a timestamp reply. Block that too:
#iptables -I OUTPUT -p icmp --icmp-type 14 -j DROP
Whatever you do, don't put this in your iptables config:
# iptables -I OUTPUT -j DROP
Notice how that line doesn't qualify what to drop? Exactly. It will drop everything. No traffic will leave your machine, including yours.
One caveat to blocking ping and timestamp: you will be preventing legitimate use as well. Ping was invented as a way to check connections between computers. If you drop pings, you break this tool. I leave it as an exercise for the reader to work around this with iptables.
And that's it?
That's it for the basics. There's a lot more you can do, but this is enough of a crash course to keep your computer safe from most common threats. It's not super heavy-duty security, but it will block the Internet Background Radiation (Steve Gibson's term).
If you're ready, you can move on to the intermediate iptables configuration.