Difference between revisions of "Iptables"

From Christoph's Personal Wiki
Jump to: navigation, search
 
(29 intermediate revisions by the same user not shown)
Line 1: Line 1:
 +
'''iptables''' is a user-space utility program that allows a system administrator to configure the tables provided by the Linux kernel firewall (implemented as different Netfilter modules) and the chains and rules it stores. Different kernel modules and programs are currently used for different protocols; iptables applies to IPv4, ip6tables to IPv6, arptables to ARP, and ebtables to Ethernet frames.
 +
 +
iptables requires elevated privileges to operate and must be executed by user root, otherwise it fails to function. On most Linux systems, iptables is installed as <tt>/usr/sbin/iptables</tt> and documented in its man pages, which can be opened using <code>man iptables</code> when installed. It may also be found in <tt>/sbin/iptables</tt>, but since iptables is more like a service rather than an "essential binary", the preferred location remains <tt>/usr/sbin</tt>.
 +
 +
The term ''iptables'' is also commonly used to inclusively refer to the kernel-level components. ''x_tables'' is the name of the kernel module carrying the shared code portion used by all four modules that also provides the API used for extensions; subsequently, ''Xtables'' is more or less used to refer to the entire firewall (v4, v6, arp, and eb) architecture.
 +
 +
The successor of iptables is nftables, which was merged into the Linux kernel mainline in kernel version 3.13, which was released on 19 January 2014.
 +
 +
==Stateful filtering==
 +
*TCP states: NEW, RELATED, ESTABLISHED, INVALID
 +
*Connection states (to match in the conntrack module): INVALID, NEW, ESTABLISHED, RELATED, UNTRACKED, SNAT, DNAT
 +
*Chain types (this option can either be the name of a user defined chain or any of the builtin chains): INPUT, FORWARD, OUTPUT, PREROUTING, POSTROUTING, SECMARK, CONNSECMARK
 +
*Jump types: ACCEPT, DROP, REJECT
 +
 +
*Basic ruleset:
 +
<pre>
 +
*filter
 +
:INPUT ACCEPT [0:0]
 +
:FORWARD ACCEPT [0:0]
 +
:OUTPUT ACCEPT [241:19144]
 +
-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 INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
 +
-A INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT
 +
-A INPUT -p tcp -m state --state NEW -m tcp --dport 53 -j ACCEPT
 +
-A INPUT -p udp -m state --state NEW -m udp --dport 53 -j ACCEPT
 +
-A INPUT -j REJECT --reject-with icmp-host-prohibited
 +
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
 +
COMMIT
 +
</pre>
 +
 +
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 --sport 63636 -s 10.0.0.2 -j ACCEPT
 +
 +
* Get a list of ICMP type names:
 +
$ iptables -p icmp -h
 +
 +
* The REJECT target rejects the packet. If you do not specify which ICMP message to reject with, by default, the server will send back "ICMP port unreachable" (type 3, code 3).
 +
;<code>REJECT</code>: This is used to send back an error packet in response to the matched packet: otherwise it is equivalent to DROP so it is a terminating TARGET, ending rule traversal. This target is only valid in the INPUT, FORWARD, and OUTPUT chains, and user-defined chains which are only called from those chains. The following option controls the nature of the error packet returned:
 +
--reject-with type
 +
: The type given can be:
 +
::<code>icmp-net-unreachable</code>
 +
::<code>icmp-host-unreachable</code>
 +
::<code>icmp-port-unreachable</code>
 +
::<code>icmp-proto-unreachable</code>
 +
::<code>icmp-net-prohibited</code>
 +
::<code>icmp-host-prohibited</code>
 +
::<code>icmp-admin-prohibited</code> (*)
 +
:which return the appropriate ICMP error message (port-unreachable is the default). The option tcp-reset can be used on rules which only match the TCP protocol: this causes a TCP RST packet to be sent back. This is mainly useful for blocking ident (113/tcp) probes, which frequently occur when sending mail to broken mail hosts (which will not accept your mail otherwise).
 +
:(*) Using icmp-admin-prohibited with kernels that do not support it will result in a plain DROP instead of REJECT
 +
 +
==Examples==
 +
* Sample <code>`iptables`</code> ruleset:
 +
<pre>
 +
*filter
 +
 +
# Dropping incoming connections that don't have explecit rules bellow
 +
:INPUT DROP [68:4456]
 +
:FORWARD ACCEPT [0:0]
 +
:OUTPUT ACCEPT [1628:151823]
 +
 +
# Allow established connections for both public and private connections
 +
-A INPUT -i eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
 +
-A INPUT -i eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT
 +
 +
# Opening ports wide open
 +
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
 +
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
 +
-A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
 +
-A INPUT -p tcp -m tcp --dport 21 -j ACCEPT
 +
-A INPUT -p tcp -m tcp --dport 3306 -j ACCEPT
 +
-A INPUT -p tcp -m tcp --dport 53 -j ACCEPT
 +
-A INPUT -p udp -m udp --dport 53 -j ACCEPT
 +
 +
# Opening a port to a specific IP
 +
-A INPUT -p tcp -m tcp --dport 10000 -s 192.168.1.1 -j ACCEPT
 +
 +
# Opening a port to a range of IPs
 +
-A INPUT -p tcp -m tcp --dport 20000 -s 192.168.0.0/24 -j ACCEPT
 +
 +
# Commmiting the rules to the firewall
 +
COMMIT
 +
</pre>
 +
 +
*Simple [[Bash]] script:
 +
<pre>
 +
#!/bin/bash
 +
# Set INPUT chain default policy to DROP
 +
iptables -P INPUT DROP
 +
# Flushes all rule in the filter table
 +
iptables -F
 +
# ACCEPT all packets from loopback interface
 +
iptables -A INPUT -i lo -j ACCEPT
 +
# ACCEPT all ESTABLISHED,RELATED packets
 +
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
 +
# ACCEPT all NEW connections to tcp port 22
 +
iptables -A INPUT -m state --state NEW -p tcp --dport 22 -j ACCEPT
 +
# REJECT all packets from 192.168.1.0/24 network
 +
iptables -A INPUT -s 192.168.1.0/24 -j REJECT
 +
# ACCEPT all icmp traffic from 192.168.0.0/24
 +
iptables -A INPUT -p icmp -s 192.168.0.0/24 -j ACCEPT
 +
# save rules
 +
iptables-save > /etc/sysconfig/iptables
 +
# print out saved rules
 +
iptables-save
 +
iptables -nvL
 +
</pre>
 +
 +
===Network Address Translation (NAT)===
 +
* The chains available in the <code>filter</code> table are: <code>INPUT, FORWARD, OUTPUT</code>
 +
* The chains available in the <code>nat</code> table are: <code>PREROUTING, POSTROUTING, OUTPUT</code>
 +
* Example:
 +
$ iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
 +
$ iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 192.168.0.1
 +
$ iptables -t nat -A PREROUTING -i eth0 -m tcp -p tcp --dport 80 -j DNAT --to-destination 192.168.0.100:8080
 +
* The <code>DNAT</code> target can only be used in the <code>PREROUTING</code> chain and the <code>OUTPUT</code> chain of the <code>nat</code> table.
 +
* To enable forwarding persistently across reboots, add <code>net.ipv4.ip_forward=1</code> to <code>/etc/sysctl.conf</code> then run <code>sysctl -p</code>, or:
 +
sysctl -w net.ipv4.ip_forward=1
 +
 
==Basic command options==
 
==Basic command options==
 
Chain manipulation (three default chains, INPUT, FORWARD, OUTPUT, are always present):
 
Chain manipulation (three default chains, INPUT, FORWARD, OUTPUT, are always present):
Line 13: Line 133:
 
*Append a new rule to a chain (<code>-A, --append chain rule-specification</code>)
 
*Append a new rule to a chain (<code>-A, --append chain rule-specification</code>)
 
*Delete a rule at some position in a chain (<code>-D, --delete chain rule-specification</code>)
 
*Delete a rule at some position in a chain (<code>-D, --delete chain rule-specification</code>)
 +
 +
;NEW : packet starts a new communication, adds a rule to the state tracking table
 +
;ESTABLISHED : any packet that matches a rule in the state tracking table
 +
;RELATED : traffic "related" in some way to ESTABLISHED traffic; protocols like SSH, FTP, etc.
 +
;INVALID : packet cannot be identified; normally these should be rejected or dropped
 +
 +
NOTE: Running the <code>`iptables`</code> command changes the netfilter kernel module rules in memory, but will not persist across a reboot.
 +
 +
Running <code>`service iptables save`</code> will take the current rules in memory and write them to <code>/etc/sysconfig/iptables</code> which is read during system boot. Run instead:
 +
service iptables restart
  
 
==Help (-h)==
 
==Help (-h)==
Line 63: Line 193:
 
{| align="center" style="border: 1px solid #999; background-color:#FFFFFF"
 
{| align="center" style="border: 1px solid #999; background-color:#FFFFFF"
 
|-
 
|-
! colspan="4" bgcolor="#EFEFEF" | '''Common Netmask Bit Values'''
+
! colspan="5" bgcolor="#EFEFEF" | '''Netmask Bit Values'''
 
|-align="center" bgcolor="#1188ee" color="#fff"
 
|-align="center" bgcolor="#1188ee" color="#fff"
!Netmask
+
!Addrs
 
!Bits
 
!Bits
|- align="left"
+
!Pref
|255.0.0.0 || 8
+
!Class
|--bgcolor="#eeeeee" align="left"
+
!Mask
|255.255.0.0 || 16
+
|--align="right"
|-
+
|      ||  0 || /32 ||      || 255.255.255.255
|255.255.255.0 || 24
+
|--bgcolor="#eeeeee" align="right"
|--bgcolor="#eeeeee" align="left"
+
|     2 ||  1 || /31 ||      || 255.255.255.254
|255.255.255.128 || 25
+
|--align="right"
|-
+
|    4 ||  2 || /30 ||      || 255.255.255.252
|255.255.255.192 || 26
+
|--bgcolor="#eeeeee" align="right"
|--bgcolor="#eeeeee" align="left"
+
|    8 ||  3 || /29 ||      || 255.255.255.248
|255.255.255.224 || 27
+
|--align="right"
|-
+
|   16 ||  4 || /28 ||      || 255.255.255.240
|255.255.255.240 || 28
+
|--bgcolor="#eeeeee" align="right"
|--bgcolor="#eeeeee" align="left"
+
|    32 ||  5 || /27 ||      || 255.255.255.224
|255.255.255.248 || 29
+
|--align="right"
|-
+
|   64 ||  6 || /26 ||      || 255.255.255.192
|255.255.255.252 || 30
+
|--bgcolor="#eeeeee" align="right"
 +
|  128 ||  7 || /25 ||      || 255.255.255.128
 +
|--align="right"
 +
|   256 ||  8 || /24 ||  1C || 255.255.255.0
 +
|--bgcolor="#eeeeee" align="right"
 +
|  512 ||  9 || /23 ||  2C || 255.255.254.0
 +
|--align="right"
 +
|   1K || 10 || /22 ||  4C || 255.255.252.0
 +
|--bgcolor="#eeeeee" align="right"
 +
|    2K || 11 || /21 ||  8C || 255.255.248.0
 +
|--align="right"
 +
|    4K || 12 || /20 ||  16C || 255.255.240.0
 +
|--bgcolor="#eeeeee" align="right"
 +
|   8K || 13 || /19 ||  32C || 255.255.224.0
 +
|--align="right"
 +
|  16K || 14 || /18 ||  64C || 255.255.192.0
 +
|--bgcolor="#eeeeee" align="right"
 +
|  32K || 15 || /17 || 128C || 255.255.128.0
 +
|--align="right"
 +
|   64K || 16 || /16 ||  1B || 255.255.0.0
 +
|--bgcolor="#eeeeee" align="right"
 +
|  128K || 17 || /15 ||  2B || 255.254.0.0
 +
|--align="right"
 +
|  256K || 18 || /14 ||  4B || 255.252.0.0
 +
|--bgcolor="#eeeeee" align="right"
 +
|  512K || 19 || /13 ||  8B || 255.248.0.0
 +
|--align="right"
 +
|   1M || 20 || /12 ||  16B || 255.240.0.0
 +
|--bgcolor="#eeeeee" align="right"
 +
|    2M || 21 || /11 ||  32B || 255.224.0.0
 +
|--align="right"
 +
|    4M || 22 || /10 ||  64B || 255.192.0.0
 +
|--bgcolor="#eeeeee" align="right"
 +
|    8M || 23 || /9  || 128B || 255.128.0.0
 +
|--align="right"
 +
|  16M || 24 || /8  ||  1A || 255.0.0.0
 +
|--bgcolor="#eeeeee" align="right"
 +
|  32M || 25 || /7  ||  2A || 254.0.0.0
 +
|--align="right"
 +
|  64M || 26 || /6  ||  4A || 252.0.0.0
 +
|--bgcolor="#eeeeee" align="right"
 +
|  128M || 27 || /5  ||  8A || 248.0.0.0
 +
|--align="right"
 +
|  256M || 28 || /4  ||  16A || 240.0.0.0
 +
|--bgcolor="#eeeeee" align="right"
 +
|  512M || 29 || /3  ||  32A || 224.0.0.0
 +
|--align="right"
 +
| 1024M || 30 || /2  ||  64A || 192.0.0.0
 +
|--bgcolor="#eeeeee" align="right"
 +
| 2048M || 31 || /1  || 128A || 128.0.0.0
 +
|--align="right"
 +
| 4096M || 32 || /0  || 256A || 0.0.0.0
 
|}
 
|}
 
</div>
 
</div>
 +
<br clear="all"/>
  
 
==ICMP datagram types==
 
==ICMP datagram types==
Line 127: Line 309:
 
|}
 
|}
 
</div>
 
</div>
 
+
<br clear="all"/>
 
==Type Of Service (TOS)==
 
==Type Of Service (TOS)==
 
<div style="float:left; margin:0px 20px 20px 0px;">
 
<div style="float:left; margin:0px 20px 20px 0px;">
Line 148: Line 330:
 
|}
 
|}
 
</div>
 
</div>
 
+
<br clear="all"/>
 
==Example script==
 
==Example script==
 
<pre>
 
<pre>
Line 209: Line 391:
 
iptables -A INPUT -s $CLASS_A -p udp --destination-port 445 -j ACCEPT
 
iptables -A INPUT -s $CLASS_A -p udp --destination-port 445 -j ACCEPT
 
</pre>
 
</pre>
 +
 +
==Map external IP address onto an internal one==
 +
Let's say your external IP address is <code>128.65.225.10</code> and your internal IP address is <code>10.0.17.10</code>, then:
 +
-A PREROUTING -d 128.65.225.10 -j DNAT --to-destination 10.0.17.10
 +
-A POSTROUTING -s 10.0.17.10 -j SNAT --to-source 128.65.225.10
 +
 +
You can then view the results with
 +
iptables --list -n -t nat -v
 +
 +
==Scripts==
 +
*[[Iptables/scripts/flush|rc.flush-iptables]] &mdash; resets iptables to default values
 +
*[[fail2ban]]
 +
 +
==Tips==
 +
*Find your external interface:
 +
$ ip route ls
 +
10.0.213.56 via 10.0.27.5e dev eth0  metric 10
 +
192.168.27.0/24 dev eth0  proto kernel  scope link  src 192.168.27.63  metric 10
 +
10.0.27.0/24 dev eth0  proto kernel  scope link  src 10.0.27.63  metric 10
 +
169.254.0.0/16 dev eth0  scope link  metric 10
 +
127.0.0.0/8 dev lo  scope link
 +
default via 10.0.27.153 dev eth0  metric 10
 +
The last line shows <code>eth0</code> to be your external interface.
 +
 +
*Determine the IP address of your external interface:
 +
$ ip addr ls dev eth0
 +
2: eth0: <BROADCAST,MULTICAST,UP,10000> mtu 1500 qdisc pfifo_fast qlen 100
 +
    link/ether 00:19:d1:4f:22:60 brd ff:ff:ff:ff:ff:ff
 +
    inet '''128.95.27.63'''/24 brd 10.0.27.255 scope global eth0
 +
    inet 192.168.27.63/24 brd 192.168.27.255 scope global eth0:0
 +
    inet6 fe80::219:d1ff:fe4f:2260/64 scope link
 +
      valid_lft forever preferred_lft forever
 +
*So, the IP address of the external interface is <code>128.95.27.63</code>.
 +
 +
==See also==
 +
*[[CentOS#How to switch from FirewallD to Iptables on CentOS 7|How to switch from FirewallD to Iptables on CentOS 7]]
 +
*[http://ettercap.sourceforge.net/ Ettercap] &mdash; a suite for man in the middle attacks on LAN. It features sniffing of live connections, content filtering on the fly and many other interesting tricks.
 +
*[http://n2h.telles.org/ netfilter2html] &mdash; a script wrote using [[awk|GAWK]] to process netfilter logs and generate a nice HTML output.
 +
*[http://www.wallfire.org/wflogs/ Wflogs] &mdash; a firewall log analysis tool. It can be used to produce a log summary report in plain text, HTML and XML, or to monitor firewalling logs in real-time.
 +
*[[Samba]] &mdash; contains extra iptables rules
 +
*[http://www.saout.de/misc/dm-crypt/ dm-crypt: a device-mapper crypto target]
 +
*[http://loop-aes.sourceforge.net/ loop-AES]
 +
*[http://sourceforge.net/projects/tripwire/ tripwire]
 +
*[[wikipedia:Port_address_translation]] (PAT)
  
 
==External links==
 
==External links==
 
*[http://www.netfilter.org/ netfilter.org]
 
*[http://www.netfilter.org/ netfilter.org]
 +
===Free firewall software===
 +
*[http://directory.fsf.org/security/firewall/ GNU Firewall Free Software Directory]
 +
*[http://www.shorewall.net/ Shorewall]
 +
===Tutorials / Howtos / Examples / etc.===
 
*[http://iptables-tutorial.frozentux.net/iptables-tutorial.html Iptables Tutorial 1.2.2] &mdash; by Oskar Andreasson
 
*[http://iptables-tutorial.frozentux.net/iptables-tutorial.html Iptables Tutorial 1.2.2] &mdash; by Oskar Andreasson
 
*[http://www.netfilter.org/documentation/HOWTO//networking-concepts-HOWTO.html Linux Networking-concepts HOWTO]
 
*[http://www.netfilter.org/documentation/HOWTO//networking-concepts-HOWTO.html Linux Networking-concepts HOWTO]
Line 219: Line 449:
 
*[http://myy.helia.fi/~karte/iptables_firewall.html Firewall for Single Host with Iptables]
 
*[http://myy.helia.fi/~karte/iptables_firewall.html Firewall for Single Host with Iptables]
 
*[http://logi.cc/linux/netfilter-log-format.php3 Netfilter Log Format]
 
*[http://logi.cc/linux/netfilter-log-format.php3 Netfilter Log Format]
 +
*[http://www.oreilly.com/catalog/linag2/book/ch09.html Linux Network Administrator's Guide, 2nd Edition - Chapter 9: TCP/IP Firewall]
 +
*[http://www.oreilly.com/catalog/tcp3/chapter/ch09.html TCP/IP Network Administration, 3rd Edition - Chapter 9: Local Network Services]
 +
*[http://www.howtoforge.com/nat_iptables Step-By-Step Configuration of NAT with iptables]
 +
*[http://easyfwgen.morizot.net/gen/index.php Easy Firewall Generator for IPTables]
 +
*[http://www.linux.ie/articles/tutorials/firewall/ Firewalling with netfilter/iptables] &mdash; on linux.ie
 +
*[http://redhatcat.blogspot.com/2007/09/beating-sandvine-with-linux-iptables.html Beating Sandvine with Linux iptables] &mdash; for legal downloads only.
 +
*[http://snafu.priv.at/mystuff/recent-plus-pam.html pam_recent: an add-on to make iptables' recent match more useful]
 +
*[http://www.learn-networking.com/tcp-ip/introduction-to-tcp-ip-protocol-suite.php An Introduction to TCP/IP]
 +
*[http://www.debian-administration.org/articles/390 Speedup DNS requests with a local cache]
  
 
[[Category:Linux Command Line Tools]]
 
[[Category:Linux Command Line Tools]]

Latest revision as of 21:16, 19 December 2018

iptables is a user-space utility program that allows a system administrator to configure the tables provided by the Linux kernel firewall (implemented as different Netfilter modules) and the chains and rules it stores. Different kernel modules and programs are currently used for different protocols; iptables applies to IPv4, ip6tables to IPv6, arptables to ARP, and ebtables to Ethernet frames.

iptables requires elevated privileges to operate and must be executed by user root, otherwise it fails to function. On most Linux systems, iptables is installed as /usr/sbin/iptables and documented in its man pages, which can be opened using man iptables when installed. It may also be found in /sbin/iptables, but since iptables is more like a service rather than an "essential binary", the preferred location remains /usr/sbin.

The term iptables is also commonly used to inclusively refer to the kernel-level components. x_tables is the name of the kernel module carrying the shared code portion used by all four modules that also provides the API used for extensions; subsequently, Xtables is more or less used to refer to the entire firewall (v4, v6, arp, and eb) architecture.

The successor of iptables is nftables, which was merged into the Linux kernel mainline in kernel version 3.13, which was released on 19 January 2014.

Stateful filtering

  • TCP states: NEW, RELATED, ESTABLISHED, INVALID
  • Connection states (to match in the conntrack module): INVALID, NEW, ESTABLISHED, RELATED, UNTRACKED, SNAT, DNAT
  • Chain types (this option can either be the name of a user defined chain or any of the builtin chains): INPUT, FORWARD, OUTPUT, PREROUTING, POSTROUTING, SECMARK, CONNSECMARK
  • Jump types: ACCEPT, DROP, REJECT
  • Basic ruleset:
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [241:19144]
-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 INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 53 -j ACCEPT
-A INPUT -p udp -m state --state NEW -m udp --dport 53 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited 
-A FORWARD -j REJECT --reject-with icmp-host-prohibited 
COMMIT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 --sport 63636 -s 10.0.0.2 -j ACCEPT
  • Get a list of ICMP type names:
$ iptables -p icmp -h
  • The REJECT target rejects the packet. If you do not specify which ICMP message to reject with, by default, the server will send back "ICMP port unreachable" (type 3, code 3).
REJECT
This is used to send back an error packet in response to the matched packet: otherwise it is equivalent to DROP so it is a terminating TARGET, ending rule traversal. This target is only valid in the INPUT, FORWARD, and OUTPUT chains, and user-defined chains which are only called from those chains. The following option controls the nature of the error packet returned:
--reject-with type
The type given can be:
icmp-net-unreachable
icmp-host-unreachable
icmp-port-unreachable
icmp-proto-unreachable
icmp-net-prohibited
icmp-host-prohibited
icmp-admin-prohibited (*)
which return the appropriate ICMP error message (port-unreachable is the default). The option tcp-reset can be used on rules which only match the TCP protocol: this causes a TCP RST packet to be sent back. This is mainly useful for blocking ident (113/tcp) probes, which frequently occur when sending mail to broken mail hosts (which will not accept your mail otherwise).
(*) Using icmp-admin-prohibited with kernels that do not support it will result in a plain DROP instead of REJECT

Examples

  • Sample `iptables` ruleset:
*filter

# Dropping incoming connections that don't have explecit rules bellow
:INPUT DROP [68:4456]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [1628:151823]

# Allow established connections for both public and private connections
-A INPUT -i eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT

# Opening ports wide open
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 21 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 3306 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 53 -j ACCEPT
-A INPUT -p udp -m udp --dport 53 -j ACCEPT

# Opening a port to a specific IP
-A INPUT -p tcp -m tcp --dport 10000 -s 192.168.1.1 -j ACCEPT

# Opening a port to a range of IPs
-A INPUT -p tcp -m tcp --dport 20000 -s 192.168.0.0/24 -j ACCEPT

# Commmiting the rules to the firewall
COMMIT
#!/bin/bash
# Set INPUT chain default policy to DROP
iptables -P INPUT DROP
# Flushes all rule in the filter table
iptables -F
# ACCEPT all packets from loopback interface
iptables -A INPUT -i lo -j ACCEPT
# ACCEPT all ESTABLISHED,RELATED packets
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# ACCEPT all NEW connections to tcp port 22
iptables -A INPUT -m state --state NEW -p tcp --dport 22 -j ACCEPT
# REJECT all packets from 192.168.1.0/24 network
iptables -A INPUT -s 192.168.1.0/24 -j REJECT
# ACCEPT all icmp traffic from 192.168.0.0/24
iptables -A INPUT -p icmp -s 192.168.0.0/24 -j ACCEPT
# save rules
iptables-save > /etc/sysconfig/iptables
# print out saved rules
iptables-save
iptables -nvL

Network Address Translation (NAT)

  • The chains available in the filter table are: INPUT, FORWARD, OUTPUT
  • The chains available in the nat table are: PREROUTING, POSTROUTING, OUTPUT
  • Example:
$ iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
$ iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 192.168.0.1
$ iptables -t nat -A PREROUTING -i eth0 -m tcp -p tcp --dport 80 -j DNAT --to-destination 192.168.0.100:8080
  • The DNAT target can only be used in the PREROUTING chain and the OUTPUT chain of the nat table.
  • To enable forwarding persistently across reboots, add net.ipv4.ip_forward=1 to /etc/sysctl.conf then run sysctl -p, or:
sysctl -w net.ipv4.ip_forward=1

Basic command options

Chain manipulation (three default chains, INPUT, FORWARD, OUTPUT, are always present):

  • Create a new chain (-N, --new-chain chain)
  • Delete an empty chain (-X, --delete-chain [chain])
  • Change the policy for a built-in chain (-P, --policy chain target)
  • List the rules in a chain (-L, --list [chain])
  • Flush the rules out of a chain (-F, --flush [chain])
  • Zero the packet and byte counters in all chains (-Z, --zero) (note: It is legal to specify the -L, --list (list) option as well, to see the counters immediately before they are cleared.)

Rule manipulation:

  • Append a new rule to a chain (-A, --append chain rule-specification)
  • Delete a rule at some position in a chain (-D, --delete chain rule-specification)
NEW 
packet starts a new communication, adds a rule to the state tracking table
ESTABLISHED 
any packet that matches a rule in the state tracking table
RELATED 
traffic "related" in some way to ESTABLISHED traffic; protocols like SSH, FTP, etc.
INVALID 
packet cannot be identified; normally these should be rejected or dropped

NOTE: Running the `iptables` command changes the netfilter kernel module rules in memory, but will not persist across a reboot.

Running `service iptables save` will take the current rules in memory and write them to /etc/sysconfig/iptables which is read during system boot. Run instead:

service iptables restart

Help (-h)

Usage

iptables -[AD] chain rule-specification [options]
iptables -[RI] chain rulenum rule-specification [options]
iptables -D chain rulenum [options]
iptables -[LFZ] [chain] [options]
iptables -[NX] chain
iptables -E old-chain-name new-chain-name
iptables -P chain target [options]
iptables -h (print this help information)

Commands

Either long or short options are allowed.

--append -A chain 
append to chain
--delete -D chain 
delete matching rule from chain
--delete -D chain rulenum 
delete rule rulenum (1 = first) from chain
--insert -I chain [rulenum] 
insert in chain as rulenum (default 1=first)
--replace -R chain rulenum 
replace rule rulenum (1 = first) in chain
--list -L [chain] 
list the rules in a chain or all chains
--flush -F [chain] 
delete all rules in chain or all chains
--zero -Z [chain] 
zero counters in chain or all chains
--new -N chain 
create a new user-defined chain
--delete-chain -X [chain] 
delete a user-defined chain
--policy -P chain target 
change policy on chain to target
--rename-chain -E old-chain new-chain 
change chain name, (moving any references)

Options

--proto -p [!] proto 
protocol: by number or name, eg. 'tcp'
--source -s [!] address[/mask] 
source specification
--destination -d [!] address[/mask] 
destination specification
--in-interface -i [!] input name[+] 
network interface name ([+] for wildcard)
--jump -j target 
target for rule (may load target extension)
--goto -g chain 
jump to chain with no return
--match -m match 
extended match (may load extension)
--numeric -n 
numeric output of addresses and ports
--out-interface -o [!] output name[+] 
network interface name ([+] for wildcard)
--table -t table 
table to manipulate (default: 'filter')
--verbose -v 
verbose mode
--line-numbers 
print line numbers when listing
--exact -x 
expand numbers (display exact values)
[!] --fragment -f 
match second or further fragments only
--modprobe=<command> 
try to insert modules using this command
--set-counters PKTS BYTES 
set the counter during insert/append
[!] --version -V 
print package version.

Netmask

Netmask Bit Values
Addrs Bits Pref Class Mask
0 /32 255.255.255.255
2 1 /31 255.255.255.254
4 2 /30 255.255.255.252
8 3 /29 255.255.255.248
16 4 /28 255.255.255.240
32 5 /27 255.255.255.224
64 6 /26 255.255.255.192
128 7 /25 255.255.255.128
256 8 /24 1C 255.255.255.0
512 9 /23 2C 255.255.254.0
1K 10 /22 4C 255.255.252.0
2K 11 /21 8C 255.255.248.0
4K 12 /20 16C 255.255.240.0
8K 13 /19 32C 255.255.224.0
16K 14 /18 64C 255.255.192.0
32K 15 /17 128C 255.255.128.0
64K 16 /16 1B 255.255.0.0
128K 17 /15 2B 255.254.0.0
256K 18 /14 4B 255.252.0.0
512K 19 /13 8B 255.248.0.0
1M 20 /12 16B 255.240.0.0
2M 21 /11 32B 255.224.0.0
4M 22 /10 64B 255.192.0.0
8M 23 /9 128B 255.128.0.0
16M 24 /8 1A 255.0.0.0
32M 25 /7 2A 254.0.0.0
64M 26 /6 4A 252.0.0.0
128M 27 /5 8A 248.0.0.0
256M 28 /4 16A 240.0.0.0
512M 29 /3 32A 224.0.0.0
1024M 30 /2 64A 192.0.0.0
2048M 31 /1 128A 128.0.0.0
4096M 32 /0 256A 0.0.0.0


ICMP datagram types

see: RFC 1700 (Assigned Numbers)
/usr/include/netinet/ip_icmp.h
ICMP Datagram Types
Type number iptables mnemonic Type description
0 echo-reply Echo Reply
3 destination-unreachable Destination Unreachable
4 source-quench Source Quench
5 redirect Redirect
8 echo-request Echo Request
11 time-exceeded Time Exceeded
12 parameter-problem Parameter Problem
13 timestamp-request Timestamp Request
14 timestamp-reply Timestamp Reply
15 none Information Request
16 none Information Reply
17 address-mask-request Address Mask Request
18 address-mask-reply Address Mask Reply


Type Of Service (TOS)

Suggested Uses for TOS Bitmasks
TOS ANDmask XORmask Suggested Use
Minimum Delay 0x01 0x10 ftp, telnet, ssh
Maximum Throughput 0x01 0x08 ftp-data, www
Maximum Reliability 0x01 0x04 snmp, dns
Minimum Cost 0x01 0x02 nntp, smtp


Example script

#!/bin/bash

LOOPBACK="127.0.0.0/8"
CLASS_A="10.0.0.0/8"
CLASS_B="172.16.0.0/12"
CLASS_C="192.168.0.0/16"
CLASS_D="224.0.0.0/4"
CLASS_E="240.0.0.0/5"
BROADCAST_SRC="0.0.0.0"
BROADCAST_DEST="255.255.255.255"

########
# flush iptables
iptables -F
iptables -t nat -F
iptables -t mangle -F

########
# loopback
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

########
# policies
iptables -P INPUT DROP
iptables -P OUTPUT ACCEPT
iptables -P FORWARD DROP

iptables -t nat -P PREROUTING ACCEPT
iptables -t nat -P OUTPUT ACCEPT
iptables -t nat -P POSTROUTING ACCEPT

iptables -t mangle -P PREROUTING ACCEPT
iptables -t mangle -P OUTPUT ACCEPT

########
# allow related incoming
iptables -I INPUT 1 -m state --state ESTABLISHED,RELATED -j ACCEPT

########
# programs and stuff (add a line for each service you want to allow)

# SSH on local network
iptables -A INPUT -s $CLASS_A -p tcp --destination-port 22 -j ACCEPT

# apache server (on all interfaces/networks)
iptables -A INPUT -p tcp --destination-port 80 -j ACCEPT

# samba + network share
iptables -A INPUT -s $CLASS_A -p tcp --destination-port 137 -j ACCEPT
iptables -A INPUT -s $CLASS_A -p udp --destination-port 137 -j ACCEPT
iptables -A INPUT -s $CLASS_A -p tcp --destination-port 138 -j ACCEPT
iptables -A INPUT -s $CLASS_A -p udp --destination-port 138 -j ACCEPT
iptables -A INPUT -s $CLASS_A -p tcp --destination-port 139 -j ACCEPT
iptables -A INPUT -s $CLASS_A -p udp --destination-port 139 -j ACCEPT
iptables -A INPUT -s $CLASS_A -p tcp --destination-port 445 -j ACCEPT
iptables -A INPUT -s $CLASS_A -p udp --destination-port 445 -j ACCEPT

Map external IP address onto an internal one

Let's say your external IP address is 128.65.225.10 and your internal IP address is 10.0.17.10, then:

-A PREROUTING -d 128.65.225.10 -j DNAT --to-destination 10.0.17.10
-A POSTROUTING -s 10.0.17.10 -j SNAT --to-source 128.65.225.10

You can then view the results with

iptables --list -n -t nat -v

Scripts

Tips

  • Find your external interface:
$ ip route ls
10.0.213.56 via 10.0.27.5e dev eth0  metric 10
192.168.27.0/24 dev eth0  proto kernel  scope link  src 192.168.27.63  metric 10
10.0.27.0/24 dev eth0  proto kernel  scope link  src 10.0.27.63  metric 10
169.254.0.0/16 dev eth0  scope link  metric 10
127.0.0.0/8 dev lo  scope link
default via 10.0.27.153 dev eth0  metric 10

The last line shows eth0 to be your external interface.

  • Determine the IP address of your external interface:
$ ip addr ls dev eth0
2: eth0: <BROADCAST,MULTICAST,UP,10000> mtu 1500 qdisc pfifo_fast qlen 100
   link/ether 00:19:d1:4f:22:60 brd ff:ff:ff:ff:ff:ff
   inet 128.95.27.63/24 brd 10.0.27.255 scope global eth0
   inet 192.168.27.63/24 brd 192.168.27.255 scope global eth0:0
   inet6 fe80::219:d1ff:fe4f:2260/64 scope link
      valid_lft forever preferred_lft forever
  • So, the IP address of the external interface is 128.95.27.63.

See also

External links

Free firewall software

Tutorials / Howtos / Examples / etc.