Difference between revisions of "Iptables: Explanations, options & examples"
| (19 intermediate revisions by 2 users not shown) | |||
| Line 54: | Line 54: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
| − | * <code>-A INPUT</code> = '''Append''' the rule | + | * <code>-A INPUT</code> = '''Append''' the rule to the '''INPUT''' ''chain'' |
* <code>-i virbr0</code> = '''Interface''' = '''virbr0''' | * <code>-i virbr0</code> = '''Interface''' = '''virbr0''' | ||
* <code>-p udp</code> = '''Protocol''' = '''UDP''' | * <code>-p udp</code> = '''Protocol''' = '''UDP''' | ||
* <code>-m udp</code> = '''match''' = '''UDP''' - ''not sure what this means!'' | * <code>-m udp</code> = '''match''' = '''UDP''' - ''not sure what this means!'' | ||
* <code>--dport 53</code> = '''desintation port''' = '''53''' | * <code>--dport 53</code> = '''desintation port''' = '''53''' | ||
| − | * <code>-j ACCEPT</code> = '''Jump''' to the target of '''ACCEPT'''. Basically, what to do if the packet matches the rule criteria. Option could be to ACCEPT, DENY | + | * <code>-j ACCEPT</code> = '''Jump''' to the target of '''ACCEPT'''. Basically, what to do if the packet matches the rule criteria. Option could be to ACCEPT, DENY, jump to another chain or a number of different possibilities. |
| − | This rule will basically '''accept''' '''UDP''' traffic on '''port 53''' across '''virbr0'''. In practice, this rule will exist in the <code>*filter</code> '' | + | This rule will basically '''accept''' '''UDP''' traffic on '''port 53''' across '''virbr0'''. In practice, this rule will exist in the <code>*filter</code> ''table'' and will allow DNS operations over the KVM virtual network interface known as <code>virbr0</code>. |
== Example operations with iptables == | == Example operations with iptables == | ||
| Line 68: | Line 68: | ||
[root@srv1 ~]# iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT | [root@srv1 ~]# iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT | ||
</syntaxhighlight> | </syntaxhighlight> | ||
| − | This rule needs to be in the <code>*filter</code> '' | + | This rule needs to be in the <code>*filter</code> ''table''. |
It will allow TCP traffic over port 80. | It will allow TCP traffic over port 80. | ||
<br> | <br> | ||
<br> | <br> | ||
NB - The '''--state NEW''' signifies the packet is establishing a new connection. '''ESTABLISHSED''' would mean the packet is associated with an existing connected which has seen packet transfer in both directions. '''RELATED''' would mean a packet is establishing a new connection but is associated with an existing connections (useful for FTP). | NB - The '''--state NEW''' signifies the packet is establishing a new connection. '''ESTABLISHSED''' would mean the packet is associated with an existing connected which has seen packet transfer in both directions. '''RELATED''' would mean a packet is establishing a new connection but is associated with an existing connections (useful for FTP). | ||
| + | |||
| + | === Traffic forwarding over bridged interface === | ||
| + | <syntaxhighlight> | ||
| + | [root@srv1 ~]# iptables -I FORWARD -m physdev --physdev-is-bridged -j ACCEPT | ||
| + | </syntaxhighlight> | ||
| + | This rule will be inserted into the <code>FORWARD</code> ''chain'' and will all packed to be forward across the bridged network adapter | ||
| + | <br> | ||
| + | <br> | ||
| + | NB - The '''-I FORWARD''' signified that this rule should be inserted into the specified chain, rather than appended. | ||
| + | |||
| + | === Port forwarding (to a different IP address) === | ||
| + | This can be used to forward incoming traffic (e.g. web traffic) to a different host or vm. For example, a host system could be running a web server as a virtual machine and incoming web traffic on TCP port 80 should be forwarded to that vm. | ||
| + | <syntaxhighlight> | ||
| + | [root@srv1 ~]# iptables -A PREROUTING -i eth1 -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.0.16:80 | ||
| + | </syntaxhighlight> | ||
| + | This rule will be appended to the <code>PREROUTING</code> ''chain'' within the <code>*nat</code> ''table''. | ||
| + | <br>As TCP traffic on port 80 data arrives across interface eth1, it is transferred to a host with IP address of 192.168.0.16 on port 80. | ||
| + | <br> | ||
| + | <br> | ||
| + | NB - '''DNAT''' is a virtual state, whereby the original destination differs from the reply source, which will be the case where NAT has or will take place. | ||
| + | |||
| + | == Common rules for *filter table == | ||
| + | === Allow ICMP traffic === | ||
| + | <syntaxhighlight> | ||
| + | [root@srv1 ~]# iptables -A INPUT -p icmp -j ACCEPT | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | === Allow any traffic from a given interface === | ||
| + | <syntaxhighlight> | ||
| + | [root@srv1 ~]# iptables -A INPUT -i lo -j ACCEPT | ||
| + | [root@srv1 ~]# iptables -A INPUT -i eth0 -j ACCEPT | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | === Allow related and established traffic between two interfaces === | ||
| + | <syntaxhighlight> | ||
| + | [root@srv1 ~]# iptables -A FORWARD -i eth1 -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | == Common rules for *nat table == | ||
| + | === Enable NAT for a specified interface === | ||
| + | <syntaxhighlight> | ||
| + | [root@srv1 ~]# iptables -A POSTROUTING -o eth1 -j MASQUERADE | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | === Enable NAT for specific ports for a given IP subnet === | ||
| + | <syntaxhighlight> | ||
| + | [root@srv1 ~]# iptables -A POSTROUTING -s 192.168.122.0/24 ! -d 192.168.122.0/24 -p tcp -j MASQUERADE --to-ports 1024-65535 | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | == Practical examples == | ||
| + | === Enable NAT/Masquerading on a new system === | ||
| + | * Useful for setting up a node as a gateway within centos or RHEL | ||
| + | * Firstly, the Linux kernel needs to be told to entertain IP forwarding; | ||
| + | <syntaxhighlight> | ||
| + | [root@srv1 ~]# echo 1 > /proc/sys/net/ipv4/ip_forward | ||
| + | </syntaxhighlight> | ||
| + | Or for a permanent solution, edit '''<code>/etc/sysctl.conf</code>''' and change the line that says '''<code>net.ipv4.ip_forward = 0</code>''' to '''<code>net.ipv4.ip_forward = 1</code>'''. | ||
| + | <br>Then: | ||
| + | <syntaxhighlight> | ||
| + | [root@srv1 ~]# iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE | ||
| + | [root@srv1 ~]# iptables -A FORWARD -i eth1 -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT | ||
| + | [root@srv1 ~]# iptables -A FORWARD -i eth0 -o eth1 -j ACCEPT | ||
| + | </syntaxhighlight> | ||
| + | Note: The above didnt work if there was already some icmp reject statements in the firewall rules (This will be evident when ping returns: From 192.168.0.1: icmp_seq=1 Destination Host Prohibited) | ||
| + | |||
| + | To address this saved the iptables rules <tt>service iptables save</tt> then move the ICMP reject rules to the end of the rules list. e.g. below (for accepting traffic from a private network on eth2 and forwarding out on eth0 | ||
| + | <syntaxhighlight> | ||
| + | [root@piston_gateway ~]# cat /etc/sysconfig/iptables | ||
| + | # Generated by iptables-save v1.4.7 on Wed Jan 21 15:13:23 2015 | ||
| + | *nat | ||
| + | :PREROUTING ACCEPT [159:33580] | ||
| + | :POSTROUTING ACCEPT [28:1720] | ||
| + | :OUTPUT ACCEPT [28:1720] | ||
| + | -A POSTROUTING -o eth0 -j MASQUERADE | ||
| + | COMMIT | ||
| + | # Completed on Wed Jan 21 15:13:23 2015 | ||
| + | # Generated by iptables-save v1.4.7 on Wed Jan 21 15:13:23 2015 | ||
| + | *filter | ||
| + | :INPUT ACCEPT [0:0] | ||
| + | :FORWARD ACCEPT [0:0] | ||
| + | :OUTPUT ACCEPT [5508:662782] | ||
| + | -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 | ||
| + | -A FORWARD -i eth0 -o eth2 -m state --state RELATED,ESTABLISHED -j ACCEPT | ||
| + | -A FORWARD -i eth2 -o eth0 -j ACCEPT | ||
| + | -A INPUT -j REJECT --reject-with icmp-host-prohibited # <- this line moved to bottom | ||
| + | -A FORWARD -j REJECT --reject-with icmp-host-prohibited # <- this line moved to bottom | ||
| + | COMMIT | ||
| + | # Completed on Wed Jan 21 15:13:23 2015 | ||
| + | </syntaxhighlight> | ||
| + | To commit these new rules to the '''<code>/etc/sysconfig/iptables</code>''' configuration file, type: | ||
| + | <syntaxhighlight> | ||
| + | [root@srv1 ~]# service iptables save | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | == Saving and restoring an iptables config in ubuntu == | ||
| + | Unlike RedHat based distros, ubuntu does not, by default, save the iptables config to a text file and the <code>service iptables save</code> option is not available so any changes will, without further action, be lost in the event of a system reboot. | ||
| + | <br><br> | ||
| + | Settings can be saved and restored by using the '''<code>iptables-save</code>''' and '''<code>iptables-restore</code>''' commands. | ||
| + | |||
| + | === Save iptables config to a file === | ||
| + | <syntaxhighlight> | ||
| + | sudo sh -c "iptables-save > /etc/iptables.rules" | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | === Manually restore settings from config file === | ||
| + | <syntaxhighlight> | ||
| + | iptables-restore < /etc/iptables.rules | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | === Automatically restore when an interface come up === | ||
| + | Edit the '''<code>/etc/network/interfaces</code>''' file to include the following for an interface: | ||
| + | <syntaxhighlight> | ||
| + | pre-up iptables-restore < /etc/iptables.rules | ||
| + | </syntaxhighlight> | ||
| + | For example: | ||
| + | <syntaxhighlight> | ||
| + | # This file describes the network interfaces available on your system | ||
| + | # and how to activate them. For more information, see interfaces(5). | ||
| + | |||
| + | # The loopback network interface | ||
| + | auto lo | ||
| + | iface lo inet loopback | ||
| + | |||
| + | # The primary network interface | ||
| + | auto em1 | ||
| + | auto em2 | ||
| + | iface em1 inet static | ||
| + | pre-up iptables-restore < /etc/iptables.rules | ||
| + | address 10.17.1.1 | ||
| + | netmask 255.0.0.0 | ||
| + | gateway 10.0.0.3 | ||
| + | iface em2 inet static | ||
| + | address 172.28.0.2 | ||
| + | netmask 255.255.0.0 | ||
| + | broadcast 172.28.255.255 | ||
| + | gateway 172.28.0.2 | ||
| + | dns-nameservers 172.28.0.2 | ||
| + | dns-search pxe.boston.co.uk | ||
| + | </syntaxhighlight> | ||
Latest revision as of 15:17, 21 January 2015
Configuration file location and command commands
Configuration file
The iptables configuration file is located at: /etc/sysconfig/iptables. The contains all the tables, chains and rules. Additional configurations can be added directly to this file or via command line tools, for example:
[root@srv1 ~]# iptables -A INPUT -i eth0 -j ACCEPTCommon Commands
# start iptables
[root@srv1 ~]# service iptables start
# get current status
[root@srv1 ~]# service iptables status
# stop iptables
[root@srv1 ~]# service iptables stop
# restart iptables
[root@srv1 ~]# service iptables restart
# save any newly added rules
[root@srv1 ~]# service iptables saveStructure of /etc/sysconfig/iptables
Tables
iptables includes 3 default tables:
*filter- Default table for filtering packets*nat- Default table for Network Address Translation*mangle- Default table used for specific type of packet alteration
Chains
Each table has a group of built-in chains, corresponding to the actions to be performed on the packets. The chains for each section are as follows:
- The built-in chains for the filter table:
INPUT- Applies to packets targeted at the host (incoming traffic)OUTPUT- Applies to locally-generated packets heading out of the system (outgoing traffic)FORWARD- Applies to packets routed through the host (forwarded/routed traffic)
- The built-in chains for the nat table:
PREROUTING- Alters packets when they arriveOUTPUT- Alters locally-general packets before they leavePOSTROUTING- Alters packets before they leave
- The built-in chains for the mangle table:
INPUT- Alters packets targeted for the hostOUTPUT- Alters locally-generated packets before they leaveFORWARD- Alters to packets routed through the hostPREROUTING- Alters incoming packets before they are routedPOSTROUTING- Alters packets before they leave
Explanation of an example iptables rule
[root@srv1 ~]# iptables -A INPUT -i virbr0 -p udp -m udp --dport 53 -j ACCEPT-A INPUT= Append the rule to the INPUT chain-i virbr0= Interface = virbr0-p udp= Protocol = UDP-m udp= match = UDP - not sure what this means!--dport 53= desintation port = 53-j ACCEPT= Jump to the target of ACCEPT. Basically, what to do if the packet matches the rule criteria. Option could be to ACCEPT, DENY, jump to another chain or a number of different possibilities.
This rule will basically accept UDP traffic on port 53 across virbr0. In practice, this rule will exist in the *filter table and will allow DNS operations over the KVM virtual network interface known as virbr0.
Example operations with iptables
Open up specific ports (port 80 in this example)
[root@srv1 ~]# iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPTThis rule needs to be in the *filter table.
It will allow TCP traffic over port 80.
NB - The --state NEW signifies the packet is establishing a new connection. ESTABLISHSED would mean the packet is associated with an existing connected which has seen packet transfer in both directions. RELATED would mean a packet is establishing a new connection but is associated with an existing connections (useful for FTP).
Traffic forwarding over bridged interface
[root@srv1 ~]# iptables -I FORWARD -m physdev --physdev-is-bridged -j ACCEPTThis rule will be inserted into the FORWARD chain and will all packed to be forward across the bridged network adapter
NB - The -I FORWARD signified that this rule should be inserted into the specified chain, rather than appended.
Port forwarding (to a different IP address)
This can be used to forward incoming traffic (e.g. web traffic) to a different host or vm. For example, a host system could be running a web server as a virtual machine and incoming web traffic on TCP port 80 should be forwarded to that vm.
[root@srv1 ~]# iptables -A PREROUTING -i eth1 -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.0.16:80This rule will be appended to the PREROUTING chain within the *nat table.
As TCP traffic on port 80 data arrives across interface eth1, it is transferred to a host with IP address of 192.168.0.16 on port 80.
NB - DNAT is a virtual state, whereby the original destination differs from the reply source, which will be the case where NAT has or will take place.
Common rules for *filter table
Allow ICMP traffic
[root@srv1 ~]# iptables -A INPUT -p icmp -j ACCEPTAllow any traffic from a given interface
[root@srv1 ~]# iptables -A INPUT -i lo -j ACCEPT
[root@srv1 ~]# iptables -A INPUT -i eth0 -j ACCEPT[root@srv1 ~]# iptables -A FORWARD -i eth1 -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPTCommon rules for *nat table
Enable NAT for a specified interface
[root@srv1 ~]# iptables -A POSTROUTING -o eth1 -j MASQUERADEEnable NAT for specific ports for a given IP subnet
[root@srv1 ~]# iptables -A POSTROUTING -s 192.168.122.0/24 ! -d 192.168.122.0/24 -p tcp -j MASQUERADE --to-ports 1024-65535Practical examples
Enable NAT/Masquerading on a new system
- Useful for setting up a node as a gateway within centos or RHEL
- Firstly, the Linux kernel needs to be told to entertain IP forwarding;
[root@srv1 ~]# echo 1 > /proc/sys/net/ipv4/ip_forwardOr for a permanent solution, edit /etc/sysctl.conf and change the line that says net.ipv4.ip_forward = 0 to net.ipv4.ip_forward = 1.
Then:
[root@srv1 ~]# iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE
[root@srv1 ~]# iptables -A FORWARD -i eth1 -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
[root@srv1 ~]# iptables -A FORWARD -i eth0 -o eth1 -j ACCEPTNote: The above didnt work if there was already some icmp reject statements in the firewall rules (This will be evident when ping returns: From 192.168.0.1: icmp_seq=1 Destination Host Prohibited)
To address this saved the iptables rules service iptables save then move the ICMP reject rules to the end of the rules list. e.g. below (for accepting traffic from a private network on eth2 and forwarding out on eth0
[root@piston_gateway ~]# cat /etc/sysconfig/iptables
# Generated by iptables-save v1.4.7 on Wed Jan 21 15:13:23 2015
*nat
:PREROUTING ACCEPT [159:33580]
:POSTROUTING ACCEPT [28:1720]
:OUTPUT ACCEPT [28:1720]
-A POSTROUTING -o eth0 -j MASQUERADE
COMMIT
# Completed on Wed Jan 21 15:13:23 2015
# Generated by iptables-save v1.4.7 on Wed Jan 21 15:13:23 2015
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [5508:662782]
-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
-A FORWARD -i eth0 -o eth2 -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i eth2 -o eth0 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited # <- this line moved to bottom
-A FORWARD -j REJECT --reject-with icmp-host-prohibited # <- this line moved to bottom
COMMIT
# Completed on Wed Jan 21 15:13:23 2015To commit these new rules to the /etc/sysconfig/iptables configuration file, type:
[root@srv1 ~]# service iptables saveSaving and restoring an iptables config in ubuntu
Unlike RedHat based distros, ubuntu does not, by default, save the iptables config to a text file and the service iptables save option is not available so any changes will, without further action, be lost in the event of a system reboot.
Settings can be saved and restored by using the iptables-save and iptables-restore commands.
Save iptables config to a file
sudo sh -c "iptables-save > /etc/iptables.rules"Manually restore settings from config file
iptables-restore < /etc/iptables.rulesAutomatically restore when an interface come up
Edit the /etc/network/interfaces file to include the following for an interface:
pre-up iptables-restore < /etc/iptables.rulesFor example:
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).
# The loopback network interface
auto lo
iface lo inet loopback
# The primary network interface
auto em1
auto em2
iface em1 inet static
pre-up iptables-restore < /etc/iptables.rules
address 10.17.1.1
netmask 255.0.0.0
gateway 10.0.0.3
iface em2 inet static
address 172.28.0.2
netmask 255.255.0.0
broadcast 172.28.255.255
gateway 172.28.0.2
dns-nameservers 172.28.0.2
dns-search pxe.boston.co.uk