From Fedora Project Wiki

Revision as of 19:38, 7 December 2011 by Rforlot (talk | contribs) (file way to edit iptables rules)

How to edit IPtables rules.

In this how to we will learn three differents way to edit IPtables rules :

  • CLI : iptables command and his config file /etc/sysconfig/iptables.
  • ncurse interface : setup or system-config-firewall-tui
  • GUI : system-config-firewall

It is not an how to about making elaborates rules with iptables, we only use iptables on a basic way.

Let's go.

my CLI way

Hot changes in iptables rules content

This method allow you to change behaviour of your iptables firewall when is running.

Stop (medium size).png
Caution
You can break up your connection with mistakes in rules.

I invite you to read the man pages about iptables for further explanation and more sophisticated rules. You must have superuser rights to launch these commands, please use sudo or su as your convenience. Example of iptables rules which allow any connections established or related, icmp requests, all local traffic and finally ssh communication :

[root@server ~]# iptables -L
Chain INPUT (policy DROP)
target     prot opt source               destination         
ACCEPT     all  --  anywhere             anywhere             state RELATED,ESTABLISHED
ACCEPT     icmp --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     tcp  --  anywhere             anywhere             state NEW tcp dpt:ssh

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination 

First thing to know, the rules apply in order of appearance and exit if there is a match. So, if we have a rule that reject ssh connections then after another rules allowing ssh then once the reject rule is reached, the packets exit and apply the reject rule but never reached the accept rule. So with that in mind, we can edit iptables's rules.

Append a rule

This is add a rule at the end of the specified chain of iptables :

[root@server ~]# iptables -A INPUT -p tcp --dport 80 -j ACCEPT
[root@server ~]# iptables -L
Chain INPUT (policy DROP)
target     prot opt source               destination         
ACCEPT     all  --  anywhere             anywhere             state RELATED,ESTABLISHED
ACCEPT     icmp --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     tcp  --  anywhere             anywhere             state NEW tcp dpt:ssh
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:http

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination 

Notice the last line in chain INPUT. There are now 5 rules in that chain. Let's delete the last one for recreate on the top of the same chain.

[root@server ~]# iptables -D INPUT 5
[root@server ~]# iptables -L
Chain INPUT (policy DROP)
target     prot opt source               destination         
ACCEPT     all  --  anywhere             anywhere             state RELATED,ESTABLISHED
ACCEPT     icmp --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     tcp  --  anywhere             anywhere             state NEW tcp dpt:ssh

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination 

Now, recreate it on the top :

[root@server ~]# iptables -I INPUT 1 -p tcp --dport 80 -j ACCEPT
[root@server ~]# iptables -L
Chain INPUT (policy DROP)
target     prot opt source               destination         
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:http
ACCEPT     all  --  anywhere             anywhere             state RELATED,ESTABLISHED
ACCEPT     icmp --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     tcp  --  anywhere             anywhere             state NEW tcp dpt:ssh

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination 

Notice the number append after the name of the chain. As we say that we insert the rule at the top, we must insert it before the first. So, you want to insert this rules before the third rule you as to change this number to 3. Simple isn't it!

For the next, we replace a rules already existing. The rules about the http server is pretty wide for acceptance. Restrict a little more this rule by only allow a specific network 192.168.0.0/24 :

[root@server ~]# iptables -R INPUT 1 -p tcp -s 192.168.0.0/24 --dport 80 -j ACCEPT
[root@server ~]# iptables -L
Chain INPUT (policy DROP)
target     prot opt source               destination         
ACCEPT     tcp  --  192.168.0.0/24       anywhere             tcp dpt:http
ACCEPT     all  --  anywhere             anywhere             state RELATED,ESTABLISHED
ACCEPT     icmp --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     tcp  --  anywhere             anywhere             state NEW tcp dpt:ssh

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination 

So, summarize, we now know how to :

  • append
iptables -A <chain>
  • insert
iptables -I <chain> <rule_position>
  • replace
iptables -R <chain> <rule_position>
  • delete
iptables -D <chain> <rule_position>

Make changes persistant

Ok, when editing iptables rules with iptables command, if we reboot the pc then we loose rules that we make. So we have to save them!

Happily, iptables comes with two useful utility : iptables-save and iptables-restore.

  • iptables-save : print a reusable dump of current iptables rules. You have to redirect to a file like that :
[root@server ~]# iptables-save > iptables.dump 
[root@server ~]# cat iptables.dump 
# Generated by iptables-save v1.4.12 on Wed Dec  7 20:10:49 2011
*filter
:INPUT DROP [45:2307]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [1571:4260654]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
COMMIT
# Completed on Wed Dec  7 20:10:49 2011
  • iptables-restore : restore a dump of rules made by iptables-save.
[root@server ~]# iptables-restore < iptables.dump 
[root@server ~]# iptables -L
Chain INPUT (policy DROP)
target     prot opt source               destination         
ACCEPT     all  --  anywhere             anywhere             state RELATED,ESTABLISHED
ACCEPT     icmp --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     tcp  --  anywhere             anywhere             state NEW tcp dpt:ssh

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Now, we can imagine to automatize startup and stop of iptables based on a dump file restored and saved. This mechanism already exists, this what is going on when you start and stop the iptables service. At each stop of service, it saves the current state of iptables rules set on a file and each stop it restores this file. And this file is :

  • /etc/sysconfig/iptables
    for IPv4
  • /etc/sysconfig/ip6tables
    for IPv6

So, if you prefer, you can edit this file and restart the iptables service to commit the changes. The format is pretty the same than iptables command :

# Generated by iptables-save v1.4.12 on Wed Dec  7 20:22:39 2011
*filter <--------------------------------------------------------- Specify the table of the next rules
:INPUT DROP [157:36334] <----------------------------------------- This is the three chain belong to filter table, then the policy of the chain
:FORWARD ACCEPT [0:0] <------------------------------------------- and between brackets [<packet-counter>:<byte-counter>] numbers is for
:OUTPUT ACCEPT [48876:76493439] <--------------------------------- debug/informations purpose only. Leave them at their current value.
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT <--------- A rule.
-A INPUT -p icmp -j ACCEPT <-------------------------------------- You just have to take all arguments
-A INPUT -i lo -j ACCEPT <---------------------------------------- of an iptables command.
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
COMMIT <---------------------------------------------------------- Needed at each end of table definition. Commit rules in that table.
# Completed on Wed Dec  7 20:22:39 2011

TUI/semi graphical

GUI