Firewalling with IPTables

By Kurt Seifried [email protected]


 

IPTables (sometimes referred to as NETFILTER) is the current generation of packet firewalling for Linux. It is stateful, and easily extended, providing very powerful firewall capabilities to Linux. IPTables includes numerous new features, from advanced logging to the ability to do string matching. Backwards compatibility for ipfwadm and ipchains rules is provided with modules, allowing you to easily upgrade to IPTables with minimal effort. Unfortunately the majority of IPTables documents are not incredibly great, and the more advanced features can be difficult to use correctly.

Although the HOWTO's are far from perfect I can't really do justice to recreating the IPTables HOWTO's so instead I will just point you to them:

http://netfilter.samba.org/unreliable-guides/packet-filtering-HOWTO/packet-filtering-HOWTO.linuxdoc.html.

This is the most basic document, and will get you up and running.

http://netfilter.samba.org/documentation/HOWTO/NAT-HOWTO.html

This document cover NAT (Network Address Translation, sometimes referred to as IPMASQ in Linux).

http://netfilter.samba.org/documentation/HOWTO/netfilter-extensions-HOWTO.html

This document covers extensions available in IPTables.

http://netfilter.samba.org/documentation/index.html

This lists all the documents available in various languages.

 

A very basic example

For those of you that just want to get on with it here is a simple iptables firewall script I use that is suitable for machines with one interface:

#
# First set some default policies
#

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

#
# Then block the reserved network 10.* on the external interface eth0
#

-A INPUT -s 10.0.0.0/255.0.0.0 -d 0.0.0.0/0.0.0.0 -i eth0 -j DROP

#
# Then we allow SSH, SMTP and DNS
#
-A INPUT -s 0.0.0.0/0.0.0.0 -d 0.0.0.0/0.0.0.0 -i eth0 -p tcp -m tcp --dport 22:22 -j ACCEPT 
-A INPUT -s 0.0.0.0/0.0.0.0 -d 0.0.0.0/0.0.0.0 -i eth0 -p tcp -m tcp --dport 25:25 -j ACCEPT
-A INPUT -s 0.0.0.0/0.0.0.0 -d 0.0.0.0/0.0.0.0 -i eth0 -p udp -m udp --dport 53:53 -j ACCEPT
-A INPUT -s 0.0.0.0/0.0.0.0 -d 0.0.0.0/0.0.0.0 -i eth0 -p tcp -m tcp --dport 53:53 -j ACCEPT
#
# Now we block all incoming traffic to ports between 1 and 1024. For your system
#
-A INPUT -s 0.0.0.0/0.0.0.0 -d 0.0.0.0/0.0.0.0 -i eth0 -p tcp -m tcp --dport 1:1024 -j REJECT
-A INPUT -s 0.0.0.0/0.0.0.0 -d 0.0.0.0/0.0.0.0 -i eth0 -p udp -m udp --dport 1:1024 -j REJECT

 

Some more tricks with IPTables

 

Invalid packets

One of the nicest things about IPTables is that it is stateful, and there are several options for state: NEW, ESTABLISHED, RELATED and INVALID. INVALID is especially interesting as it will:

"A packet which could not be identified for some reason: this includes running out of memory and ICMP errors which don't correspond to any known connection. Generally these packets should be dropped."

Putting this rule first in your list may be a wise decision since it will prevent mangled packets from traversing your chains and additionally it may help with survivability of your server if someone attacks it.

-A INPUT -s 0.0.0.0/0.0.0.0 -d 0.0.0.0/0.0.0.0 -m state --state INVALID -j DROP

 

Listing Tables

Typically most of us will use:

iptables -L -v -n

However this will not show all the tables (most importantly it misses the pretrouting and postrouting tables, used for NAT among other things).

To list current NAT tables:

iptables -t nat -L -v -n

 

Dropping every second or third packet

This is guarenteed to drive network administrators a bit nutty, and amuse attackers to ne end. Using the "nth" rule (not supported by default in most kernels) you can drop every "nth" packet:

iptables -A INPUT -p tcp --dport 80 -m nth --every 2 -j DROP 

This rule would drop every second packet coming in to port 80 (the webserver usually).

 


Back

Last updated on 18/3/2002

Copyright Kurt Seifried 2001 [email protected]