Personal tools
You are here: Home Team Members Jeroen van Meeuwen iptables Howto

iptables Howto

by kanarip last modified Jan 30, 2008 02:44 AM

A Howto on using iptables to configure your firewall

Firewalls

Firewalls are set-up primarily to filter and/or enhance packets which pass through the network. When a packet arrives at a firewall, it will either disregard or process the packet. The network device of a firewall only disregards packets which are invalid in some network-technical way. We won't get into the details of which packets are disregarded automatically, but consider these disregarded packets malformed in some way. The most important thing is: The rest is being processed!! Here's where firewalls really kick in. iptables is such a firewall, and a very powerfull one! It handles packets based on the type of packet activity, and enqueues the packet in one of its builtin 'tables'. There are three tables in total. The first is the mangle table which is responsible for the alteration of service bits in the TCP header. This is hardly used in basic setups (at home or in SOHO). The second table is the filter queue which is responsible for packet filtering. It has three built-in chains in which you can place your firewall policy rules. These are the:

  • Forward chain: Filters packets destined for networks protected by the firewall.
  • Input chain: Filters packets destined for the firewall.
  • Output chain: Filters packets originating from the firewall.

    The third table is the nat table which is where Network Address Translation (NAT) is performed. It has two built-in chains; these are:

    • Pre-routing chain: NATs packets when the destination address of the packet needs to be changed.
    • Post-routing chain: NATs packets when the source address of the packet needs to be changed.

      With each rule you set, you will need to specify the table. There is one exception, which is the 'filter' table. This exception is made because most of iptables' rules are filter rules. Therefore the filter table is the 'default' table.

      Packet Processing In iptables

      Below is a very simplified view of the way packets are processed by the chains.

            PACKET IN --->---PREROUTING---[ routing ]--->----FORWARD---->---POSTROUTING--->--- PACKET OUT
                               - mangle        |              - mangle        - mangle
                               - nat (dst)     |              - filter        - nat (src)
                                               |                                 |
                                               |                                 |
                                             INPUT                            OUTPUT
                                              - mangle                         - mangle
                                              - filter                         - nat (dst)
                                              |                                - filter
                                              |                                 |
                                              `---->----[ application ]---->----'

      The packet enters the firewall via the PREROUTING chain in the mangle table, if any. It is then inspected by the rules in the nat table's PREROUTING chain to see whether the packet requires destination modification (DNAT). It is important to change the destination now, because as soon as it leaves the PREROUTING chain of the nat table, it is routed.

      If the packet is destined for a 'protected' network (Read: another network, whether it is protected is up to your firewall configuration), it is filtered by the rules in the FORWARD chain of the filter table and, if necessary, the packet undergoes SNAT in the POSTROUTING chain before arriving at Network B. When the destination server decides to reply, the packet undergoes the same sequence of steps. Both the FORWARD and POSTROUTING chains may be configured to implement quality of service (QoS) features in their mangle tables, but this is not usually done in SOHO environments.

      If the packet is destined for the firewall itself, it passes through the mangle table of the INPUT chain, if configured, before being filtered by the rules in the INPUT chain of the filter table. If it successfully passes these tests then it is processed by the intended application on the firewall. At some point, the firewall needs to reply. This reply is routed through and inspected by the rules in the OUTPUT chain of the mangle table, if any. Next, the rules in the OUTPUT chain of the nat table determine whether DNAT is required and the rules in the OUTPUT chain of the filter table are then inspected to help restrict unauthorized packets. Finally, before the packet is sent back to the Internet, SNAT and QoS mangling is done by the POSTROUTING chain.

      Packet Inspection

      Now we know how packets traverse the different tables and chains in iptables, it's time to explain how to inspect the packets. There are numerous inspections you can perform on a single packet, practically limited only by the specifications of TCP/IP and your knowledge of TCP/IP. All TCP flags and parameters can be tested; the source IP address, destination IP address, port numbers, connection status, the protocol number, etc., etc.

      About TCP Connections

      One aspect commonly neglected amongst users is the fact that TCP is a triple-handshake protocol. This means, in a more real-life based example, if machine 'workstation' wants to create a TCP connection to machine 'server', 'workstation' first needs to say "Hi, how are you?", at which 'server' needs to reply "Hi, I'm fine, how are you?". 'workstation' then says "I'm fine too", and then, only then, chit-chat is over, and the real conversation can be started.

      In fact, these machines set certain TCP flags. 'workstation' sends a TCP packet with the SYN flag set, at which 'server' replies with a TCP packet with the SYN and ACK flags set. When 'workstation' receives this packet, it sends a TCP packet 'ACK'.

      iptables uses NEW, ESTABLISHED, RELATED and INVALID to represent the connection status.

      When closing the connection, basically the same triple-handshake is performed, but with FIN and ACK flags.

      Why this needs to be secured

      Imagine a 'workstation' just sends thousands of packets to 'server' with the SYN flag set. No, forget that. Let's suppose you have no dial-up Internet connection anymore. Let's suppose 'workstation' sends millions if not billions of packets to 'server' with the SYN flag set. Futuristic, huh?

      All these packets cause 'server' to reply with a TCP packet with the SYN and ACK flags set. 'server' will assume these connections to have a certain status, called SYN-RECEIVED, waiting for the TCP packet with the ACK flag set from 'workstation', after which the connection is ESTABLISHED. This connection status has a default timeout of 60 seconds, meaning it takes 60 seconds before 'server' considers the connection failed and removes it. How many packets can you send in 60 seconds, and how many connections with status SYN-RECEIVED can 'server' handle? If 'workstation' replies with the appropriate ACK, things could get worse. The default timeout for a connection with status ESTABLISHED is 5 days...

      Another situation is a very poorly described feature of iptables. To allow firewall redundancy, iptables allows incoming connections with status NEW, but without the SYN flag set. Remember if you don't filter those packets, they are processed!

      Packet Inspection Options

      option description example
      --protocol
      Match protocol. Options are tcp, udp, icmp, or any other protocol in /etc/protocols
      iptables -A INPUT --protocol tcp
      --source
      Match source IP address. The IP address can be represented in several ways.
      • Single host: host.domain.tld, or using the IP Address: 10.10.10.3
      • Multiple IP Addresses (Subnet): 10.10.10.3/24 or 10.10.10.3/255.255.255.0
      iptables -A INPUT --source 10.10.10.3
      --destination
      Match destination IP address. The IP address can be represented in several ways, see --source
      iptables -A INPUT --destination 192.168.1.0/24
      --source-port
      Match the source port, only available with --protocol tcp, or --protocol udp
      iptables -A INPUT --protocol tcp --source-port 25
      --destination-port
      Match the destination port, only available with --protocol tcp, or --protocol udp
      iptables -A INPUT --protocol udp --destination-port 67
      --state
      Match the state of the connection. Available when module 'state' is loaded with '-m state'. Possible options include:
      NEW
      Matches a packet that creates a new connection.
      ESTABLISHED
      Matches a packet that belongs to an existing connection.
      RELATED
      Matches a packet that does not belong to an existing connection, but is related to an existing connection.
      Think of FTP in Active and Passive mode, which uses separate connections for the actual data transfer. These
      connections are related.
      INVALID
      Matches packets that cannot be identified for some reason. This includes running out of memory, hardware
      failure (your NIC), and ICMP errors which do not correspond with any existing connection.
      iptables -A INPUT -m state --state NEW,ESTABLISHED
      --in-interface
      Matches packets to the interface used for the incoming packet. Usefull in destination NAT and machines with multiple NICs.
      iptables -t nat -A PREROUTING --in-interface eth0 (destination NAT)
      --out-interface
      Matches packets to the interface used for the outgoing packet. Usefull in source NAT and machines with multiple NICs.
      iptables -t nat -A POSTROUTING --in-interface eth1 (source NAT)
      --syn
      Matches packets with '--tcp-flags SYN,RST,ACK SYN' (and is a shorthand). Since this checks TCP flags, use --protocol tcp as well.
      The example matches connections with status NEW, but without the SYN flag set. Generally, these packets should be dropped.
      iptables -A INPUT --protocol tcp ! --syn -m state --state NEW
      --tcp-flags
      Match the TCP flags in the packet. This option takes two parameters: A list of flags to inspect, and a list of flags that should
      be enabled.

      Target Specifications

      Now that you are familiar with the most common packet inspection options, it's time to address how to configure what to do with the packets that match the rules. iptables uses targets. You can (and should!) specify these targets using the 'jump' option: --jump (or shorthand; -j). The list of builtin targets include the list below. These are not all builtin targets, just the most commonly used ones.

       

      ACCEPT
      Accept the packet matching this rule
      DROP
      Silently drop the packet matching this rule
      REJECT
      Reject the packet mathing this rule, (very) verbosively. This target takes an optional parameter '--reject-with'. The type given can be icmp-net-unreachable, icmp-host-unreachable, icmp-port-unreachable (default), icmp-proto-unreachable, icmp-net-prohibitedor icmp-host-prohibited, which return the appropriate ICMP error message (port-unreachable is the default). With ICMP type of connections, the option echo-reply is also allowed. Finally, the option tcp-reset can be used on rules in (or called from) the INPUT chain which only match the TCP protocol: this causes a TCP packet with the RST flag set to be sent back.
      LOG
      Log packets matching this rule. This is usefull in combination with rules you specify to DROP or REJECT packets, for purposes of troubleshooting.
      RETURN
      Processing of packets matching this rule returns to the chain this chain was called from
      SNAT
      Apply source NAT to all packets matching this rule. This target is only valid in the POSTROUTING chain of the nat table, or the OUTPUT chain of the nat table
      DNAT
      Apply destination NAT to all packets matching this rule. This target is only valid in the PREROUTING chain of the nat table
      MASQUERADE
      This target is only valid in the nat table, in the POSTROUTING chain. It should only be used with dynamically assigned IP (dialup) connections: if you have a static IP address, you should use the SNAT target. Masquerading is equivalent to specifying a mapping to the IP address of the interface the packet is going out, but also has the effect that connections are forgotten when the interface goes down. This is the correct behavior when the next dialup is unlikely to have the same interface address (and hence any established connections are lost anyway). This is also the reason why you should use SNAT when you have a static IP address.

      Custom Chains

      iptables also allows you to create custom chains, which can then be specified as a target to jump to. For example, you could create a so-called whitelist for trusted IP address, and a blacklist for evil nodes on the Internet. To create the chains, you would give the following commands:

      iptables -N whitelist
      iptables -N blacklist
      

      To add a rule to these chains (or any other chain), use:

      iptables -A whitelist -s 192.168.0.0/24 -j ACCEPT
      iptables -A blacklist -s 207.46.130.0/24 -j DROP
      iptables -A blacklist -s 207.46.250.0/24 -j DROP
      

      Then, specify these chains as a target in your INPUT, FORWARD and/or OUTPUT chain:

      iptables -A INPUT -j whitelist
      iptables -A INPUT -j blacklist
      iptables -A OUTPUT -j whitelist
      iptables -A OUTPUT -j blacklist
      iptables -A FORWARD -j whitelist
      iptables -A FORWARD -j blacklist

      You have now successfully whitelisted a network 192.168.0.0/24, and blacklisted some Class C address ranges of microsoft.com.

      Accepting or denying connections to your firewall

      Let's suppose you have a mail server directly connected to the Internet (ergo, no modem or router), and you want the machine to be completely secure, at least as far as the firewall is concerned. A mail server where mail is delivered typically uses port 25 (SMTP), and mail servers used by users to read their mail typically use port 110 (POP) and 143 (IMAP). Assuming you have a remote console, the firewall does not necessarily need to allow connections to port 22 (SSH). We also assume no mail has to be send via this mail server. So, connections from anywhere to your mail server's port 25, 110 and 143 should be allowed by the firewall. Basically, a firewall initialization script would look similar to this:

      #!/bin/bash
      # Load the connection tracker kernel module
      modprobe ip_conntrack
      
      # Set the default target to DROP of all chains involved here.
      iptables -P INPUT DROP
      iptables -P FORWARD DROP
      iptables -P OUTPUT DROP
      
      # Always accept things going over the loopback interface
      iptables -A INPUT -i lo -j ACCEPT
      iptables -A OUTPUT -o lo -j ACCEPT
      
      # DROP new connections without the SYN flag set.
      iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
      
      # Get our whitelist and blacklist into place
      iptables -A INPUT -j whitelist
      iptables -A INPUT -j blacklist
      iptables -A OUTPUT -j whitelist
      iptables -A OUTPUT -j blacklist
      
      # Allow new SMTP connections
      iptables -A INPUT -p tcp --dport 25 -m state --state NEW,ESTABLISHED -j ACCEPT
      iptables -A OUTPUT -p tcp --sport 25 -m state --state ESTABLISHED -j ACCEPT
      
      # Allow new POP and IMAP connections
      iptables -A INPUT -p tcp --dport 110 -m state --state NEW,ESTABLISHED -j ACCEPT
      iptables -A OUTPUT -p tcp --sport 110 -m state --state ESTABLISHED -j ACCEPT
      iptables -A INPUT -p tcp --dport 143 -m state --state NEW,ESTABLISHED -j ACCEPT
      iptables -A OUTPUT -p tcp --sport 143 -m state --state ESTABLISHED -j ACCEPT
      
      iptables -N whitelist
      # Suppose your Internet connection has IP address 1.2.3.4
      iptables -A whitelist -s 1.2.3.4 -j ACCEPT
      
      # This statement is a little redundant, at the end of the chain, iptables returns
      # to the previous chain...
      iptables -A whitelist -j RETURN
      
      iptables -N blacklist
      # However very unlickely to ever be incoming traffic, drop traffic coming from
      # the usual private IP address ranges
      iptables -A blacklist -s 10.0.0.0/8 -j DROP
      iptables -A blacklist -s 172.16.0.0/12 -j DROP
      iptables -A blacklist -s 169.254.0.0/16 -j DROP
      iptables -A blacklist -s 192.168.0.0/16 -j DROP
      # And blacklist this known spammer too!
      iptables -A blacklist -s spammer.com -j DROP
      

      Notice that in the first few lines of the above example, we load a kernel module called 'ip_conntrack'. This module enables iptables to 'track connections', meaning that it can examine the status of connections by caching the related information for these connections.

      Also, notice we set the policy for the INPUT, FORWARD and OUTPUT chains.

      Tables, Chains, Rules, Targets...

      You may have thought you're having a hard time getting all this information on tables, chains, rules, targets... What you're read so far in this document is not even half of it. So, get settled in your chair, we're moving to routing, forwarding and network address translation!

      Example Scenarios

      A few scenarios, starting with a relatively simple topology, should clarify a lot on routing as well as NAT, without getting into the real details. These topologies may differ from your situation, so please adapt and verify the commands and parameters used to match your situation. I recommend you apply your policies with logging while setting the INPUT and OUTPUT chain's policies to ACCEPT. Analyze your log before reverting the policies back to DROP or REJECT, because you will eventually make a mistake. The only thing I can guarantee you, is that the complexer your network topology is, the sooner you'll make a mistake. Be sure you have access to the console of the firewall.

      Simple Firewall / Router Combination

      As an example, we place a box between two networks, functioning as a router and a firewall. We'll just add some basic firewall security, further hardening is recommended. To keep it digestable, additional security is a seperate topic.

                  NETWORK A --------------------[ router / firewall ]---------------------- NETWORK B
               192.168.1.0/24             192.168.1.1           192.168.2.1              192.168.2.0/24
      

      Packets from A to B will pass the router, in an appearently transparent LAN. Considering there is no link with the internet, and all clients are 'trusted' desktop PC's, we barely need the firewall functionality and in this topology the router configuration is very simple.

      We use the following command to start routing:

      # echo 1 > /proc/sys/net/ipv4/ip_forward

      Then, one day, we decide to strengthen the security between the two networks. We know Network B has some servers that host some websites that clients in Network A must be able to visit. We decide to implement the following:

      • All packets between Network A and Network B must be dropped by default.
      • Network A is allowed to visit websites hosted on webservers in Network B.

      We implement the following in iptables on the router:

      # iptables --policy FORWARD DROP
      # iptables --append FORWARD --source 192.168.1.0/24 --destination 192.168.2.0/24 --match state --state NEW,ESTABLISHED --protocol tcp \
                 --destination-port 80 -j ACCEPT
      # iptables --append FORWARD --source 192.168.2.0/24 --destination 192.168.1.0/24 --match state --state ESTABLISHED --protocol tcp \
                 --source-port 80 -j ACCEPT

      First, we set the default action for everything that is forwarded by the router, to DROP. This disables all traffic between the two networks that is not explicitly allowed.

      Second, we ACCEPT traffic from Network A to Network B, if the destination port is port 80 (HTTP), and the protocol is tcp. We allow all NEW and ESTABLISHED connections.

      Third, we ACCEPT the responses which of course start at Network B and travel to the client in Network A. This is an already established connection, and we know the source port (the socket which the server uses to respond to the client), is port 80 (HTTP).

      Here's another example, to show you how clients in Network A can also use the mail-, web-, and POP/IMAP- servers in Network B.

      # iptables --policy FORWARD DROP
      # iptables --append FORWARD --source 192.168.1.0/24 --destination 192.168.2.0/24 --match state --state NEW,ESTABLISHED --protocol tcp \
                 --match multiport --destination-ports 25,80,110,143 -j ACCEPT
      # iptables --append FORWARD --source 192.168.2.0/24 --destination 192.168.1.0/24 --match state --state ESTABLISHED \
                 --match multiport --source-ports 25,80,110,143 -j ACCEPT

      You can of course extend these commands to match your requirements. Notice the above examples only limit the network traffic between the two networks, and not traffic to, or from, the firewall itself.

      NAT (Network Address Translation)

      In computer networking, the process of network address translation (NAT, also known as network masquerading or IP-masquerading) involves re-writing the source and/or destination addresses of IP packets as they pass through a router or firewall. Most systems using NAT do so in order to enable multiple hosts on a private network to access the Internet using a single public IP address. According to specifications, routers should not act in this way, but many network administrators find NAT a convenient technique and use it widely. Nonetheless, NAT can introduce complications in communication between hosts.

      Different types of NAT

      • Full cone NAT is NAT where all requests from the same internal IP address and port are mapped to the same external IP address and port. Furthermore, any external host can send a packet to the internal host, by sending a packet to the mapped external address. It is also known as "one-to-one NAT".
      • A restricted cone NAT is one where all requests from the same internal IP address and port are mapped to the same external IP address and port. Unlike a full cone NAT, an external host (with IP address X) can send a packet to the internal host only if the internal host had previously sent a packet to IP address X.
      • A port restricted cone NAT is like a restricted cone NAT, but the restriction includes port numbers. Specifically, an external host can send a packet, with source IP address X and source port P, to the internal host only if the internal host had previously sent a packet to IP address X and port P.
      • A symmetric NAT is a NAT where all requests from the same internal IP address and port to a specific destination IP address and port are mapped to the same external source IP address and port. If the same internal host sends a packet with the same source address and port to a different destination, a different mapping is used. Furthermore, only the external host that receives a packet can send a UDP packet back to the internal host.

      Example Scenario: SOHO

      In a SOHO (Small Office, Home Office) environment, you would typically have a single public IP address. We'll first show you how to setup basic routing, before actually running a secure firewall.

                                               eth1                 eth0
                SOHO Network --------------------[ router / firewall ]---------------------- Internet
               192.168.1.0/24              192.168.1.1           public-ip-address           0.0.0.0/0
      
      

      The above network topology requires the router to use one public IP address for packets from the SOHO Network to the Internet. Also, the router should accept inbound packets that are related to connections initiated from the SOHO Network (responses etc.). Notice that there is no modem and no provider supplied router between our router and the Internet.

      For the very basic router setup using iptables, you would use:

      # iptables --policy INPUT DROP
      # iptables --policy FORWARD DROP
      # iptables --policy OUTPUT DROP
      # iptables --append INPUT --in-interface eth1 --source 192.168.1.0/24 --match state --state NEW,ESTABLISHED --jump ACCEPT
      # iptables --append OUTPUT --out-interface eth1 --destination 192.168.1.0/24 --match state --state NEW,ESTABLISHED --jump ACCEPT
      # iptables --append FORWARD --in-interface eth1 --source 192.168.1.0/24 --destination 0.0.0.0/0 --match state --state NEW,ESTABLISHED --jump ACCEPT
      # iptables --append FORWARD --in-interface eth0 --destination 192.168.1.0/24 --match state --state ESTABLISHED --jump ACCEPT
      # iptables --table nat --append POSTROUTING --out-interface eth0 --jump MASQUERADE

      The router now forwards packets between the two networks, masquerades the outgoing packets from the SOHO Network (so responses at least come back to the router again), and enables management from the SOHO Network as well. Notice that we allow NEW connections from the LAN to the Internet, but not the other way around. Also, because we use MASQUERADE, our router/firewall will only have to FORWARD traffic that comes back from the Internet as a reponse, because, as you may remember from the Packet Processing Overview earlier in this document, as a reply comes back from the Internet, our router will use the nat table to match the existing connection, apply PREROUTING destination NAT as the packet comes in, and hit the FORWARD chain with a new destination IP address.

      A SOHO Network with a Seperate Router and Firewall

      The previous scenario suggests there is one single network device, apart from switches, hubs and modems, between the SOHO Network and the Internet. In most topologies, this is not the case. Many SOHO Networks have a router from the Internet provider to connect to the Internet. If that is the case, the network topology changes:

                                         eth1        eth0
          SOHO Network --------------------[ ROUTER B ]----------------[ ROUTER A ]-------------- Internet
         192.168.2.0/24              192.168.2.1  192.168.1.2     192.168.1.1  public-ip         0.0.0.0/0
      
      Where:
      
      * ROUTER A is the router of the Internet provider.
      * ROUTER B is your router.
      
      

      In this case, configure the following:

      • Configure ROUTER A to have a static route to 192.168.2.0/24 via 192.168.1.2
      • Configure ROUTER A to have 192.168.1.2 as a default (virtual) server, using NAT
      • Configure ROUTER B to have a default route to 0.0.0.0/0 via 192.168.1.1

      ROUTER A will now NAT all incoming packets to 192.168.1.2, and MASQUERADE all outgoing packets with the public IP. The incoming packets will end up with ROUTER B, which is also the firewall.

      Suppose there is a webserver in the SOHO Network, which must be available to the public (the Internet) as well as the clients on the LAN. This means you need to forward all requests to ROUTER B, port 80 to the webserver (suppose this webserver is at 192.168.2.20):

      # iptables -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.2.20

      The same goes for other services that are hosted on the LAN.

      Further Reading and Resources

      Disclaimer

      We test this stuff on our own machines, really we do. But you may run into problems, if you do, come to #fedora on irc.freenode.net

      Document Actions
      Log in


      Forgot your password?
      New user?