The wonderful world of iptables[Was: Samba help]

Bevan C. Bennett bevan at fulcrummicro.com
Fri Jan 9 04:15:07 UTC 2004


Andrew Robinson wrote:

> Please explain. OK, this is a request for an iptables tutorial. And BTW, 
> I'm buying, but I'm still asking for the sales pitch ;).

There's a few good (if occassionally complex) ones out there already, 
particularly:

http://iptables-tutorial.frozentux.net/iptables-tutorial.html

You may want to skip to chapter 3 and go from there.
Chapter 4 explains how connection tracking works for both TCP and UDP 
packets.

For a quick quick overview, lets go over the default FC1 iptables and 
what it does for us.

-A INPUT -j RH-Firewall-1-INPUT
# send all incoming packets through the RH-Firewall-1-INPUT chain.
-A FORWARD -j RH-Firewall-1-INPUT
# ditto for any incoming packets that we plan to forward out another 
interface.

# Now we start the RH-Firewall-1-INPUT chain. Packets will pass through 
this from top to bottom, trying to match each rule in turn. When a 
packet does match, it's sent to wherever -j (jump) tells it to go, which 
in a simple filter will be either ACCEPT, REJECT or DROP.
-A RH-Firewall-1-INPUT -i lo -j ACCEPT
# allow anything coming in my loopback interface. (I trust me)
-A RH-Firewall-1-INPUT -p icmp --icmp-type any -j ACCEPT
# allow any ICMP packets
-A RH-Firewall-1-INPUT -p 50 -j ACCEPT
-A RH-Firewall-1-INPUT -p 51 -j ACCEPT
# allow any packets of protocol type 50 or 51. /etc/protocols says these 
are:
ipv6-crypt      50      IPv6-Crypt      # Encryption Header for IPv6
ipv6-auth       51      IPv6-Auth       # Authentication Header for IPv6
So if you aren't doing any IPv6 stuff you could safely remove those rules.
-A RH-Firewall-1-INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# allow any packet that's part of an established connection, for example 
a reply to a packet we sent. The 'RELATED' bit gets a little fancier and 
tries to figure out things like if a new ftp-data connection request is 
related to your existing ftp-control connection. This is what allows 
your system to function as a client.
-A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited
# this rule matches anything, and says to reject the connection by 
sending an appropriate ICMP reply to the originator. We've also 
specified that we want to send a reply of 'prohibited' rather than the 
default of 'port unreachable' (more on this later).

That's it for the default... pretty tight.
Most people these days will, however, also have the following:
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j 
ACCEPT
# If it's a NEW TCP packet heading for port 22 (ssh), let it in. This 
rule is always listed after the -m state --state ESTABLISHED,RELATED 
rule, which means that, since there are only four possible states, all 
packets below this point are either NEW or INVALID. By specifying that 
the packet must be NEW, all we're really doing here is saying that it 
shouldn't be INVALID. The -m tcp says that we're going to be using the 
tcp matching rules, but -m tcp is automatically implied by -p tcp, which 
means it's not strictly neccessary.

If you want to run servers on your box they need to respond to NEW 
packets, and you'll need to add one or more lines like this to your 
configuration, depending on what ports that server uses.

For example, if we wanted to run ssh (tcp port 22), smtp (tcp port 25) 
and http (tcp port 80), we might have the following:

-A RH-Firewall-1-INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state INVALID -j DROP
-A RH-Firewall-1-INPUT -p tcp --dport 22 -j ACCEPT
-A RH-Firewall-1-INPUT -p tcp --dport 25 -j ACCEPT
-A RH-Firewall-1-INPUT -p tcp --dport 80 -j ACCEPT

I chose here to explicitly drop INVALID packets rather than repeating 
the NEW test over and over. Incidently, if you wanted to restrict ssh so 
that only certain systems can connect, you could do that with rules like 
this:
# only the system with IP 10.1.2.3
-A RH-Firewall-1-INPUT -p tcp --dport 22 -s 10.1.2.3 -j ACCEPT
# any system in the 10.1.2.x network
-A RH-Firewall-1-INPUT -p tcp --dport 22 -s 10.1.2.0/24 -j ACCEPT
# any system NOT in the 10.1.2.x network
-A RH-Firewall-1-INPUT -p tcp --dport 22 -s ! 10.1.2.0/24 -j ACCEPT

Are we having fun or what?

One thing some people noticed earlier on this list, is that traceroute 
output to a fedora system looks odd, with !<10> showing up in the 
results. That indicates that traceroute received an unexpected type of 
reply, ICMP reject code 10 "administratively prohibited". This is 
because traceroute by default sends not ICMP ping packets (which would 
have been accepted by our icmp rule) but UDP packets to the usually 
unused ports 33434 and up. It expects to get an ICMP 'port unreachable' 
reply, which would be the default if we hadn't overridden it. You can 
make your system "traceroute friendly" by removing "--reject-with 
icmp-host-prohibited" from that last line, or by inserting the following 
line directly above it:
-A RH-Firewall-1-INPUT -p udp --dport 33434:33534 -j REJECT

In the case of SAMBA, it's a complex server that deals with several 
different protocols on several different ports, so you need to open them 
all up.
-A RH-Firewall-1-INPUT -p udp --dport 137:138 -j ACCEPT
-A RH-Firewall-1-INPUT -p tcp --dport 139 -j ACCEPT

You cannot say something like:
-A RH-Firewall-1-INPUT --dport 137:139 -j ACCEPT # WRONG
because --dport is only enabled by the -m tcp or -m udp matching filters 
  (the appropriate one is incorporated automatically when we do a -p tcp 
or -p udp, as mentioned earlier).

Since MS protocols are dangerous stuff, I'd recommend restricting those 
to the network that your local clients are on using -s.

And that's probably enough iptables babble for one evening...





More information about the fedora-list mailing list