Firewall Explanation Using iptables

Tags:

This document explains each section of the firewall script. The script is broken down into three parts. I found an example of the firewall script at http://www.iptablesrocks.org/ and modified it to fit our environment. This is not the only way to create a firewall script.

I'll use one of the firewall script examples which I modified for our machine (full firewall script is at the end of this document). Some of the descriptions come directly from the man pages of iptables. Iptables information will be written to kern.log file located in /var/log.

1. Nat (network address translation) is consulted when a packet that creates a new connection is encountered. This section of the firewall is not really needed for servers acting as a webserver. The author states that it is included just in case. Each item beginning with a colon has this convention:

  • :<chain-name> <chain-policy> [<packet-counter>:<byte-counter>]
    • <chain-name> is either PREROUTING, POSTROUTING, or OUTPUT
    • <chain-policy> is either ACCEPT or DROP
    • <packet-counter> can be anything; it gets incremented whenever this chain is hit
    • <byte-counter> can be anything; it gets incremented whenever this chain is hit
  • By performing this command (iptables-save -c -t nat), the following result appears. By continuously running this command, the packet-counter and byte-counter should increment.

       *nat
       :PREROUTING ACCEPT [127173:7033011]
       :POSTROUTING ACCEPT [31583:2332178]
       :OUTPUT ACCEPT [32021:2375633]
       COMMIT

    • PREROUTING – This chain is used to alter packets as soon as they get in to the firewall.
    • POSTROUTING – This chain is used to alter packets just as they are about to leave the firewall.
    • OUTPUT – This chain is used for altering locally generated packets (i.e., on the firewall) before they get to the routing decision.

2. Mangle is used to block or confuse most port scans. It literally mangles packets. Simple nmap scans will fail, but nmap's sophistication can go around these, and for that matter, can go around almost any kind of firewall.

       *mangle
       :PREROUTING ACCEPT [444:43563]
       :INPUT ACCEPT [444:43563]
       :FORWARD ACCEPT [0:0]
       :OUTPUT ACCEPT [402:144198]
       :POSTROUTING ACCEPT [402:144198]
       

  • INPUT – Used to alter packets after they have been routed to the local computer itself, but before the user space application actually sees the data.
  • FORWARD – Used to mangle packets after they have hit the first routing decision, but before they actually hit the last routing decision.
  • OUTPUT – Used for altering locally generated packets after they enter the routing decision.
  • PREROUTING – Used for altering packets just as they enter the firewall and before they hit the routing decision.
  • POSTROUTING – Used to mangle packets just after all routing decisions have been made.

    Each PREROUTING chain below tries to detect the different combinations of TCP control bits and effectively drops them. This helps prevent attacks such as SYN Floods and the like.

            -A PREROUTING -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,PSH,URG -j DROP
            -A PREROUTING -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP
            -A PREROUTING -p tcp -m tcp --tcp-flags SYN,RST SYN,RST -j DROP
            -A PREROUTING -p tcp -m tcp --tcp-flags FIN,SYN FIN,SYN -j DROP
            -A PREROUTING -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,PSH,URG -j DROP
            -A PREROUTING -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP
            -A PREROUTING -p tcp -m tcp --tcp-flags SYN,RST SYN,RST -j DROP
            -A PREROUTING -p tcp -m tcp --tcp-flags FIN,SYN FIN,SYN -j DROP
            -A PREROUTING -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,PSH,URG -j DROP
            -A PREROUTING -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP
            -A PREROUTING -p tcp -m tcp --tcp-flags SYN,RST SYN,RST -j DROP
            -A PREROUTING -p tcp -m tcp --tcp-flags FIN,SYN FIN,SYN -j DROP
            -A PREROUTING -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,PSH,URG -j DROP
            -A PREROUTING -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP
            -A PREROUTING -p tcp -m tcp --tcp-flags SYN,RST SYN,RST -j DROP
            -A PREROUTING -p tcp -m tcp --tcp-flags FIN,SYN FIN,SYN -j DROP
            COMMIT
         

3. Filter incoming traffic destined for this host. The filter example below initially blocks all incoming, outgoing, and forwarded ports. Then, the INPUT/OUTPUT/icmp_packets chains are entered to open up the necessary ports for acceptance.

   *filter
   :INPUT DROP [1:242]
   :FORWARD DROP [0:0]
   :OUTPUT DROP [0:0]
   :LOG_DROP - [0:0]
   :LOG_ACCEPT - [0:0]
   :icmp_packets – [0:0]

  • INPUT – Used on all packets that are destined for our local host (the firewall) and drops them.
  • OUTPUT – Used for all locally generated packets and drops them.
  • FORWARD – Used on all non-locally generated packets that are not destined for our local host (the firewall) and drops them.
  • LOG_DROP – This is a user defined target which is part of a logging rule to log the packet and then drop it.
  • LOG_ACCEPT – This is a user defined target which is part of a logging rule to log the packet and then accept it.
  • icmp_packets – This is a user defined target which defines rules for icmp packets.

    The items below are for packets coming into the machine. The INPUT state is first established. Then, each port that we want to ACCEPT for INPUT is opened up. The rest are dropped.

      -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT -A INPUT -p tcp -m tcp --dport 22 -j LOG_ACCEPT -A INPUT -p tcp -m tcp --dport 25 -j LOG_ACCEPT . . . . . . . . . -A INPUT -p tcp -m tcp --dport 8009 -j ACCEPT -A INPUT -p tcp -m tcp --dport 8080 -j ACCEPT -A INPUT -s 127.0.0.1 -j ACCEPT -A INPUT -p icmp -j icmp_packets -A INPUT -j LOG_DROP

    The items below are for packets exiting the machine. The OUTPUT state is first established. Then, each port that we want to ACCEPT for OUTPUT is opened up. The rest are dropped.

      -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT -A OUTPUT -p tcp -m tcp --dport 20 -j ACCEPT -A OUTPUT -p tcp -m tcp --dport 21 -j ACCEPT . . . . . . . . . -A OUTPUT -p tcp -m tcp --dport 8009 -j ACCEPT -A OUTPUT -p tcp -m tcp --dport 8080 -j ACCEPT -A OUTPUT -d 127.0.0.1 -j ACCEPT -A OUTPUT -p icmp -j icmp_packets -A OUTPUT -j LOG_DROP

    The following four lines define the custom log captions that will be displayed in the log file whenever a user-defined DROP or ACCEPT is encountered.

      -A LOG_DROP -j LOG --log-prefix "[IPTABLES DROP] : " --log-tcp-options --log-ip-options -A LOG_DROP -j DROP -A LOG_ACCEPT -j LOG --log-prefix "[IPTABLES ACCEPT] : " --log-tcp-options --log-ip-options -A LOG_ACCEPT -j ACCEPT

    Lastly, these rules drop all ping requests, except requests coming from the server itself. The purpose is make potential hackers think the machine is off the net. ICMP type = 0 is echo reply, 8 is echo request, 3 is destination unreachable, and 11 is time exceeded.

      -A icmp_packets -p icmp -m icmp --icmp-type 0 -j ACCEPT -A icmp_packets -s histone.cti.depaul.edu -p icmp -m icmp --icmp-type 8 -j ACCEPT -A icmp_packets -p icmp -m icmp --icmp-type 8 -j DROP -A icmp_packets -p icmp -m icmp --icmp-type 3 -j ACCEPT -A icmp_packets -p icmp -m icmp --icmp-type 11 -j ACCEPT COMMIT

    If we wanted to add a new INPUT chain, say port 1234, we would just add the following:

      -A INPUT -p tcp -m tcp --dport 1234 -j ACCEPT

    If we want to block a specific IP from accessing the server, we would do the following:

      -A INPUT -s 123.111.123.10 -j DROP

Glossary of Terms

    nat – Network Address Translation – The best example is when a home has one incoming IP. The user has more than one computer and all of the computers access the internet. In order to distinguish which computer should receive the reply, some NATing software/hardware is needed to identify the source computer. Examples of software/hardware NATing: router, DHCP server.
    packet – A message sent over the network that contains a header and a data portion.
    FIN – (Finish) – The sender of the segment is requesting that the connection be closed.
    SYN – (Synchronize) – Packet used by TCP when initiating a new connection to synchronize the sequence numbers on two connecting computers.
    RST – (Reset) – The sender has encountered a problem and wants to reset the connection.
    PSH – (Push) – Tells the sending TCP to immediately “push” all the data it has to the recipient's TCP as soon as it is able to do so, without waiting for more data.
    ACK – (Acknowledge) – Acknowledge receipt of a packet.
    URG – (Urgent) – Urgent pointer field is significant (URG control bit is set to 1) – Prioritizes the sending of data.
    ICMP – Internet Control Message Protocol – Used primarily for echo requests to determine if a host is up or not. ICMP has many other control messages, but for our purposes, it's used for ping requests.
    chain – A chain contains a ruleset of rules that are applied on packets that traverses the chain. Each chain has a specific purpose (e.g., which table it is connected to which specifies what this chain is able to do), as well as a specific application area (e.g., only forwarded packets or only packets destined for this host).
    TCP – Transmission Control Protocal – From Wikipedia, “...applications on networked hosts can create connections to one another, over which they can exchange data in packets....TCP is the intermediate layer between the Internet Protocol (IP) below it, and an application above it.” Below represents some of the common TCP/IP ports:

      20 – FTP data port
      21 – FTP control port
      22 – SSH
      23 – Telnet
      43 – Whois protocol
      53 – DNS
      80 – HTTP
      110 – POP3 (used for sending/retreiving email)
      111 – SUNRPC
      143 – IMAP4 (used for retreiving email)
      443 – HTTPS (HTTP over SSL)
      8080 – HTTP alternate (used by tomcat and others)

Complete Sample Firewall Script

# Firewall setup for histone.

#The NAT portion of the ruleset. Used for Network Address Transalation.
#Usually not needed on a typical web server, but it's there if you need it.
*nat
:PREROUTING ACCEPT [127173:7033011]
:POSTROUTING ACCEPT [31583:2332178]
:OUTPUT ACCEPT [32021:2375633]
COMMIT

#The Mangle portion of the ruleset. Here is where unwanted packet types get dropped.
#This helps in making port scans against your server a bit more time consuming and
#difficult, but not impossible.
*mangle
:PREROUTING ACCEPT [444:43563]
:INPUT ACCEPT [444:43563]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [402:144198]
:POSTROUTING ACCEPT [402:144198]
-A PREROUTING -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,PSH,URG -j DROP
-A PREROUTING -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP
-A PREROUTING -p tcp -m tcp --tcp-flags SYN,RST SYN,RST -j DROP
-A PREROUTING -p tcp -m tcp --tcp-flags FIN,SYN FIN,SYN -j DROP
-A PREROUTING -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,PSH,URG -j DROP
-A PREROUTING -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP
-A PREROUTING -p tcp -m tcp --tcp-flags SYN,RST SYN,RST -j DROP
-A PREROUTING -p tcp -m tcp --tcp-flags FIN,SYN FIN,SYN -j DROP
-A PREROUTING -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,PSH,URG -j DROP
-A PREROUTING -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP
-A PREROUTING -p tcp -m tcp --tcp-flags SYN,RST SYN,RST -j DROP
-A PREROUTING -p tcp -m tcp --tcp-flags FIN,SYN FIN,SYN -j DROP
-A PREROUTING -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,PSH,URG -j DROP
-A PREROUTING -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP
-A PREROUTING -p tcp -m tcp --tcp-flags SYN,RST SYN,RST -j DROP
-A PREROUTING -p tcp -m tcp --tcp-flags FIN,SYN FIN,SYN -j DROP
COMMIT

#The FILTER section of the ruleset is where we initially drop all packets and then 
#selectively open certain ports. We will also enable logging of all dropped requests.
*filter
:INPUT DROP [1:242]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]
:LOG_DROP - [0:0]
:LOG_ACCEPT - [0:0]
:icmp_packets - [0:0]

#First, we cover the INPUT rules, or the rules for incoming requests.
#Note how at the end we log any incoming packets that are not accepted.
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j LOG_ACCEPT
-A INPUT -p tcp -m tcp --dport 25 -j LOG_ACCEPT
-A INPUT -p tcp -m tcp --dport 43 -j ACCEPT
-A INPUT -p udp -m udp --dport 53 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 110 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 111 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 143 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 8009 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 8080 -j ACCEPT
-A INPUT -s 127.0.0.1 -j ACCEPT
-A INPUT -p icmp -j icmp_packets
-A INPUT -j LOG_DROP

#Next, we cover the OUTPUT rules, or the rules for all outgoing traffic.
#Note how at the end we log any outbound packets that are not accepted.
-A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 20 -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 21 -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 23 -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 25 -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 43 -j ACCEPT
-A OUTPUT -p udp -m udp --dport 53 -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 110 -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 111 -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 143 -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 443 -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 8009 -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 8080 -j ACCEPT
-A OUTPUT -d 127.0.0.1 -j ACCEPT
-A OUTPUT -p icmp -j icmp_packets
-A OUTPUT -j LOG_DROP

#Here we have 2 sets of logging rules. One for dropped packets to log all dropped 
# requests and one for accepted packets, should we wish to log any accepted requesets.
-A LOG_DROP -j LOG --log-prefix "[IPTABLES DROP] : " --log-tcp-options --log-ip-options
-A LOG_DROP -j DROP

-A LOG_ACCEPT -j LOG --log-prefix "[IPTABLES ACCEPT] : " --log-tcp-options --log-ip-options
-A LOG_ACCEPT -j ACCEPT

#And finally, a rule to deal with ICMP requests. We drop all ping requests except from our own server.
-A icmp_packets -p icmp -m icmp --icmp-type 0 -j ACCEPT
-A icmp_packets -s histone.cti.depaul.edu -p icmp -m icmp --icmp-type 8 -j ACCEPT
-A icmp_packets -p icmp -m icmp --icmp-type 8 -j DROP
-A icmp_packets -p icmp -m icmp --icmp-type 3 -j ACCEPT
-A icmp_packets -p icmp -m icmp --icmp-type 11 -j ACCEPT
COMMIT

References

  1. http://en.wikipedia.org/wiki/Transmission_Control_Protocol
  2. http://www.iptablesrocks.org/
  3. http://iptables-tutorial.frozentux.net/iptables-tutorial.html
  4. http://www.linuxguruz.com/iptables/howto/iptables-HOWTO.html
  5. http://logi.cc/linux/netfilter-log-format.php3
  6. http://tcpipguide.com/free/t_TCPMessageSegmentFormat-3.htm