iptables

Linux iptables command examples

iptables


Iptables is a name given to a configuration utility that is used to configure tables provided by the Linux kernel Firewall. Netfilter is a kernel module that is responsible for the actual filtering of packets. The application is normally run by the "root" user of a system. Iptables is used to create, maintain, and inspect the tables of IPv4 packet filter rules in the Linux kernel. Each table contains a number of built in chains and may also contain user defined chains.

Each chain is a list of rules which can match a set of packets. Each rule specifies what to do with a packet that matches. This is called a 'target', which may be a jump to a user defined chain in the same table.

A firewall rule specifies criteria for a packet and a target. If the packet does not match, the next rule in the chain is then examined; if there is no match, then the next rule is specified by the value of the target, this can be the name of a user defined chain or one of the special values "ACCEPT", "DROP", "QUEUE" or "RETURN".

The basic function of iptables is to place rules into predefined chains. These chains are "INPUT", "OUTPUT" and "FORWARD". These chains are checked against network traffic, and a decision is made to what action should be taken based on the rule. Either the packets are accepted or dropped. These actions are known as targets. The main targets are "ACCEPT" and "DROP" (accept a packet or drop a packet)



The three main chains used within iptables


INPUT: All packets are destined for the host computer.

OUTPUT: All packets that originate from the host computer.

FORWARD: These are packets that are not destined to or originating from the host computer. These packets literally are passed through.

Rules are then added into each of these chains. Packets are then checked against each of these rules in turn. The rules are processed from the top. If a match is made then the appropriate action is taken. This can be "ACCEPT" or "DROP". Once a match has been made against a rule and an action taken, then there is no further processing to be carried out in that chain. If a packet passes down through all the rules without making a match, then the default policy is used to process this packet. This policy will be either "ACCEPT" or "DROP".


Verify iptables has been installed


Most distributions will offer to install or install a firewall by default. RPM based distributions such as CentOS, Fedora and openSUSE generally install iptables by default. Debian based systems generally use "ufw" an alternative firewall. We will be covering this product in a separate section.

To verify you have iptables installed on your system, you can issue the following rpm query command: rpm -q iptables



[root@rhel01 root]# rpm -q iptables
iptables-1.2.5-3

[root@rhel01 root]# lsmod | grep iptab
iptable_filter          2752   0  (autoclean) (unused)
ip_tables              13984   1  [iptable_filter]

You can also issue the command: iptables -L to display your currently loaded rules:



[root@rhel01 root]# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

The above shows that we currently have no rules assigned to our chains (INPUT, FORWARD and OUTPUT).


Defining Rules


In the example below, we are going to assign some basic rules. Be very careful when you assign rules, if you are logged into your server remotely, you can loose connectivity! To combat this from happening, we are going to initially set the default policy on the INPUT chain to ACCEPT.


Set Default Policy on INPUT chain to ACCEPT



[root@rhel01 root]# iptables -P INPUT ACCEPT

Flush out any existing rules



[root@rhel01 root]# iptables -F

Append a rule to INPUT chain



[root@rhel01 root]# iptables -A INPUT -i lo -j ACCEPT

The "-A" flag is used to append a rule, the "-i" flag specifies interface. In this example, we are specifying the localhost. Once issued, we can see that we now have an entry:



Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere

Add the state module to the INPUT chain



[root@rhel01 root]# iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

The state module is used to examine the state of a packet and determine whether it is "NEW", "ESTABLISHED" or "RELATED"

We can now see our two new rules so far:



Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere           state RELATED,ESTABLISHED

NEW: Incoming packets that are new and were not initiated by the host system.

RELATED/ESTABLISHED: These are incoming packets that have an already established connection or are already related to an established connection.


Accept ssh connections over port 22



[root@rhel01 root]# iptables -A INPUT -p tcp --dport 22 -j ACCEPT

The above instruction adds a rule that allows connections over tcp port 22

Our rules so far now look like:



Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere           state RELATED,ESTABLISHED
ACCEPT     tcp  --  anywhere             anywhere           tcp dpt:ssh


Modify Default policy on the INPUT chain


The following rule will set the default policy to DROP. This means any packets that did not match the rules above will be dropped. It is important to have the ssh rule in place first otherwise you could have locked your self out of your system if you were connected remotely.



[root@rhel01 root]# iptables -P INPUT DROP

Now our are rules are defined as follows. (Notice the default policy has changed to DROP):



Chain INPUT (policy DROP)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere           state RELATED,ESTABLISHED
ACCEPT     tcp  --  anywhere             anywhere           tcp dpt:ssh

Define default policy for FORWARD chain



[root@rhel01 root]# iptables -P FORWARD DROP

This policy will stop any packets passing through our system.


Our FORWARD policy now looks like:


Chain FORWARD (policy DROP)

Define policy for the OUTPUT chain to ACCEPT


This will allow all outgoing traffic



[root@rhel01 root]# iptables -P OUTPUT ACCEPT

View current rules


To view our rules are in place and working, we can issue the "iptables -L -v" command. "-L" will list the rules, "-v" specifies verbose mode:



[root@rhel01 root]# iptables -L -v
Chain INPUT (policy DROP 1716 packets, 141K bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 ACCEPT     all  --  lo     any     anywhere             anywhere
  889 79108 ACCEPT     all  --  any    any     anywhere             anywhere           state RELATED,ESTABLISHED
    0     0 ACCEPT     tcp  --  any    any     anywhere             anywhere           tcp dpt:ssh

Chain FORWARD (policy DROP 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 352 packets, 26164 bytes)
 pkts bytes target     prot opt in     out     source               destination

Saving iptables Rules


Once you are happy that your rules meet your requirements, these rules will then need to be saved. This will ensure that they are in place after a reboot. To accomplish this we use the "save" option in conjunction with the "iptables" command:



[root@rhel01 root]# service iptables save
Saving current rules to /etc/sysconfig/iptables:           [  OK  ]

Our rules have now been saved and will be applied at next reboot. We can verify our rules again by looking at the file:

/etc/sysconfig/iptables



[root@rhel01 sysconfig]# pwd
/etc/sysconfig
[root@rhel01 sysconfig]# cat iptables
# Generated by iptables-save v1.2.5 on Wed May  8 13:31:38 2013
*filter
:INPUT DROP [2199:181749]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [660:49656]
[0:0] -A INPUT -i lo -j ACCEPT
[1141:101408] -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
[0:0] -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
COMMIT
# Completed on Wed May  8 13:31:38 2013

Filter by IP Address


Often you may wish to filter traffic from its originating IP address. To do this we can create a rule to allow a specific IP addresses:



[root@rhel01 root]# iptables -A INPUT -s 192.168.0.27 -j ACCEPT

Here we are appending a rule to the INPUT chain to ACCEPT packets from the source "192.168.0.27"

If we wanted to open the network to all connections on our local network for IP addresses 192.168.9.x, we could add a rule:



[root@rhel01 root]# iptables -A INPUT -s 192.168.0.0/24 -j ACCEPT

We can also use a similar rule to DROP a packet:



[root@rhel01 root]# iptables -A INPUT -s 10.52.231.84 -j DROP

The above rule will drop all inbound traffic from IP address 10.52.231.84



[root@rhel01 root]# iptables -A INPUT -s 192.168.0.0/24 -j DROP

The above rule will block all traffic from the 192.168.0.0/24 network.


Filter by mac address

If you require added security for access, you can specify a mac address as well as an IP address. This would then allow only traffic from the specified IP address with the matching mac address access:



[root@rhel01 root]# iptables -A INPUT -s 192.168.0.32 -m mac --mac-source 00:50:56:AF:1F:74 -j ACCEPT

The above will now add a rule to the INPUT chain allowing traffic from the IP address 192.168.0.32 with a mac address of 00:50:56:AF:1F:74. The option "-m mac" is used to load the module "mac" and the "--mac-source" is used to allow us to specify the mac address.


Open a range of ports



iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 7000:7010 -j ACCEPT

The above command opens port 7000 through to port 7010 for use by inbound traffic.


iptables options


To display your rules with a numerical line number:



[root@rhel01 root]# iptables -n -L -v --line-numbers
Chain INPUT (policy DROP 7871 packets, 646K bytes)
num   pkts bytes target     prot opt in     out     source               destination
1        0     0 ACCEPT     all  --  lo     *       0.0.0.0/0            0.0.0.0/0
2     2144  191K ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0          state RELATED,ESTABLISHED
3        0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0          tcp dpt:22
4        0     0 ACCEPT     all  --  *      *       192.168.0.27         0.0.0.0/0
5        0     0 ACCEPT     all  --  *      *       192.168.0.0/24       0.0.0.0/0
6        0     0 ACCEPT     all  --  *      *       192.168.0.32         0.0.0.0/0          MAC 00:50:56:AF:1F:74

Chain FORWARD (policy DROP 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 1907 packets, 137K bytes)
num   pkts bytes target     prot opt in     out     source               destination

To display a specific chain rule



[root@rhel01 root]# iptables -L INPUT -n -v

The above command displays rules within the "INPUT" chain.



[root@rhel01 root]# iptables -L OUTPUT -n -v

The above command displays rules within the "OUTPUT" chain.


How to Delete a Rule


The easiest way to delete a rule is find out its associated line number by using the command:

iptables -n -L -v --line-numbers



[root@rhel01 root]# iptables -n -L -v --line-numbers

[root@rhel01 root]# iptables -n -L -v --line-numbers
Chain INPUT (policy DROP 7871 packets, 646K bytes)
num   pkts bytes target     prot opt in     out     source               destination
1        0     0 ACCEPT     all  --  lo     *       0.0.0.0/0            0.0.0.0/0
2     2144  191K ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0          state RELATED,ESTABLISHED
3        0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0          tcp dpt:22
4        0     0 ACCEPT     all  --  *      *       192.168.0.27         0.0.0.0/0
5        0     0 ACCEPT     all  --  *      *       192.168.0.0/24       0.0.0.0/0
6        0     0 ACCEPT     all  --  *      *       192.168.0.32         0.0.0.0/0          MAC 00:50:56:AF:1F:74

Once we have identified the rule to delete, we can specify its line number as follows (in our example we remove line 6 from the INPUT chain):



[root@rhel01 root]# iptables -D INPUT 6

[root@rhel01 root]# iptables -n -L -v --line-numbers
Chain INPUT (policy DROP 8860 packets, 727K bytes)
num   pkts bytes target     prot opt in     out     source               destination
1        0     0 ACCEPT     all  --  lo     *       0.0.0.0/0            0.0.0.0/0
2     2419  216K ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0          state RELATED,ESTABLISHED
3        0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0          tcp dpt:22
4        0     0 ACCEPT     all  --  *      *       192.168.0.27         0.0.0.0/0
5        0     0 ACCEPT     all  --  *      *       192.168.0.0/24       0.0.0.0/0

Further Help


For further information on "iptables" you can issue the command: iptables --help or man iptables to view the man pages.



Iptables Basic Options


For a full list of options available consult the man pages: man iptables



OPTIONS
       The options that are recognized by iptables can be divided into several different groups.

   COMMANDS
       These options specify the specific action to perform.  Only one of them can  be  specified  on  the
       command line unless otherwise specified below.  For all the long versions of the command and option
       names, you need to use only enough letters to ensure that iptables can differentiate  it  from  all
       other options.

       -A, --append
              Append  one or more rules to the end of the selected chain.  When the source and/or destina-
              tion names resolve to more than one address, a rule will be added for each possible  address
              combination.

       -D, --delete
              Delete  one  or more rules from the selected chain.  There are two versions of this command:
              the rule can be specified as a number in the chain (starting at 1 for the first rule)  or  a
              rule to match.

       -R, --replace
              Replace  a  rule  in  the selected chain.  If the source and/or destination names resolve to
              multiple addresses, the command will fail.  Rules are numbered starting at 1.

       -I, --insert
              Insert one or more rules in the selected chain as the given rule number.  So,  if  the  rule
              number  is  1,  the  rule  or rules are inserted at the head of the chain.  This is also the
              default if no rule number is specified.

       -L, --list
              List all rules in the selected chain.  If no chain is selected, all chains are  listed.   It
              is  legal to specify the -Z (zero) option as well, in which case the chain(s) will be atomi-
              cally listed and zeroed.  The exact output is affected by the other arguments given.

       -F, --flush
              Flush the selected chain.  This is equivalent to deleting all the rules one by one.

       -Z, --zero
              Zero the packet and byte counters in all chains.  It is legal  to  specify  the  -L,  --list
              (list) option as well, to see the counters immediately before they are cleared. (See above.)
	
       -N, --new-chain
              Create a new user-defined chain by the given name.  There must be no  target  of  that  name
              already.

       -X, --delete-chain
              Delete  the  specified  user-defined  chain.   There must be no references to the chain.  If
              there are, you must delete or replace the referring rules before the chain can  be  deleted.
              If no argument is given, it will attempt to delete every non-builtin chain in the table.

       -P, --policy
              Set  the  policy  for  the chain to the given target.  See the section TARGETS for the legal
              targets.  Only non-user-defined chains can have policies, and  neither  built-in  nor  user-
              defined chains can be policy targets.

       -E, --rename-chain
              Rename  the  user  specified  chain to the user supplied name.  This is cosmetic, and has no
              effect on the structure of the table.

       -h     Help.  Give a (currently very brief) description of the command syntax.

 PARAMETERS
       The following parameters make up a rule specification (as used in the add, delete, insert,  replace
       and append commands).

       -p, --protocol [!] protocol
              The  protocol  of  the rule or of the packet to check.  The specified protocol can be one of
              tcp, udp, icmp, or all, or it can be a numeric value, representing one of these protocols or
              a  different  one.   A  protocol  name  from /etc/protocols is also allowed.  A "!" argument
              before the protocol inverts the test.  The number zero is equivalent to all.   Protocol  all
              will match with all protocols and is taken as default when this option is omitted.

       -s, --source [!] address[/mask]
              Source  specification.   Address  can  be  either  a hostname, a network name, or a plain IP
              address.  The mask can be either a network mask or a plain number, specifying the number  of
              1's  at  the  left  side  of  the  network  mask.   Thus,  a  mask  of  24  is equivalent to
              255.255.255.0.  A "!" argument before the address specification inverts  the  sense  of  the
              address. The flag --src is a convenient alias for this option.

       -d, --destination [!] address[/mask]
              Destination  specification.   See  the  description  of  the -s (source) flag for a detailed
              description of the syntax.  The flag --dst is an alias for this option.

       -j, --jump target
              This specifies the target of the rule; i.e., what to do if the packet matches it.  The  tar-
              get  can  be  a  user-defined chain (other than the one this rule is in), one of the special
              builtin targets which decide the fate of the packet immediately, or an extension (see EXTEN-
              SIONS  below).   If  this  option  is omitted in a rule, then matching the rule will have no
              effect on the packet's fate, but the counters on the rule will be incremented.

       -i, --in-interface [!] [name]
              Optional name of an interface via which a packet  is  received  (for  packets  entering  the
              INPUT,  FORWARD  and PREROUTING chains).  When the "!" argument is used before the interface
              name, the sense is inverted.  If the interface name ends in a "+", then any interface  which
              begins  with  this  name  will match.  If this option is omitted, the string "+" is assumed,
              which will match with any interface name.

       -o, --out-interface [!] [name]
              Optional name of an interface via which a packet is going to be sent (for  packets  entering
              the  FORWARD,  OUTPUT  and  POSTROUTING  chains).   When the "!" argument is used before the
              interface name, the sense is inverted.  If the interface name ends in a "+", then any inter-
              face  which  begins with this name will match.  If this option is omitted, the string "+" is
              assumed, which will match with any interface name.


       [!]  -f, --fragment
              This means that the rule only refers to second and further fragments of fragmented  packets.
              Since  there  is  no  way  to tell the source or destination ports of such a packet (or ICMP
              type), such a packet will not match any rules which specify them.   When  the  "!"  argument
              precedes the "-f" flag, the rule will only match head fragments, or unfragmented packets.

       -c, --set-counters  PKTS BYTES
              This  enables the administrator to initialize the packet and byte counters of a rule (during
              INSERT, APPEND, REPLACE operations)

        --line-numbers
              When listing rules, add line numbers to the beginning of each rule,  corresponding  to  that
              rule's position in the chain.