Linux: Firewall, iptables Tutorial
This is a tutorial of Linux's iptables
command. You need to have a basic understanding of TCP/IP. If not, see:
TCP/IP Tutorial for Beginner
.
iptables
is a advanced firewall for Linux.
It can {drop, redirect, modify/NAT} packets based on {IP address, port, …}. For a short intro of what it can do, see:
Linux: What's Netfilter, iptables, Their Differences?
you need to be root to use iptables. So, sudo su root
first, or precede all your commands by sudo
.
A Simple Example
first, do this to first see that your network is working:
# check network ping -c 3 google.com
Now, do:
# add a rule to drop ALL incoming packets sudo iptables --table filter --append INPUT --jump DROP
now, all packets coming to your computer are dropped. Now try ping google.com
again. It won't work.
you can look at the packet filtering rules you've added:
# show a list of rules sudo iptables --list
sample output:
Chain INPUT (policy ACCEPT) target prot opt source destination DROP all -- anywhere anywhere Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination
now, clear the rules you've created.
# remove all filtering rules sudo iptables --flush
now, try ping -c 3 google.com
again. It works again.
Basic Concepts and Terminology
man iptables
(2.3k lines of documentation)iptables -h
(command summary)
iptables is a complex software, and the man page is badly written and hard to understand. You need to understand the following basic concepts first, then, you'll be able to read the man page as reference.
firewall works by matching packets with rules. When a rule match, a specified action is done, such as blocking the packet or letting it pass or alter some info in the packet or redirect. The rules can be checking on IP address, port number, protocol, number of packets, a particular network interface the packet is from or to, or connection state, etc.
The iptables
command is used to set the rules and actions.
tables, chain, target
The rules are grouped into “table”, then “chain”. A action to be done on a packet is called “target”.
- table
- A table is a name of a collection of “chain”.
- chain
- A “chain” is a name for a set of rules.
- rule
- A rule is used to match packet. For example, match port number, match protocol, ….
- target
-
Action. A “target” is a name for a action. When a rule matches a packet, the “target” (action) is executed. Example of target: {
ACCEPT
,DROP
,QUEUE
,RETURN
}. - policy
-
The default action when no rules match. Only builtin chains can have policy. And its value must be one of {
ACCEPT
,DROP
}. (todo: can it be RETURN? Or QUEUE?).
Basic Syntax
Example:
# list current rules for filter table sudo iptables --table filter --list
here's a sample output:
# iptables --list Chain INPUT (policy ACCEPT) 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 REJECT all -- anywhere anywhere reject-with icmp-host-prohibited Chain FORWARD (policy ACCEPT) target prot opt source destination REJECT all -- anywhere anywhere reject-with icmp-host-prohibited Chain OUTPUT (policy ACCEPT) target prot opt source destination
On your machine, you'll probably see no rules, because, you haven't set any rules yet.
The general syntax is this:
iptables --table table --append/delete/rename/… CHAIN rule --jump TARGET
It means, work with table named table, then append/delete/rename the rule rule to the chain named CHAIN, when match, do TARGET.
here's one example:
sudo iptables --table filter --append INPUT --match conntrack --ctstate ESTABLISHED,RELATED --jump ACCEPT
here's what it means, broken down in parts:
iptables --table filter …
- Work with the “filter” table.
--append INPUT …
- Append (a rule) to the INPUT chain.
--match conntrack --ctstate ESTABLISHED,RELATED
- Turn on match connection state tracking, and, with condition that the connection is established, or is related to another connection already permitted.
--jump ACCEPT
- Goto the action of target “ACCEPT”.
iptables Tables
The possible table names are:
- filter
- generic table for filtering packets. This is the most commonly used table.
- nat
- for packets that creates a new connection. (this is related to NAT (Network Address Translation))
- mangle
- for specialized packet alteration.
- raw
- mainly for configuring exemptions from connection tracking in combination with the NOTRACK target. It registers at the netfilter hooks with higher priority and is thus called before ip_conntrack, or any other IP tables.
- security
- for Mandatory Access Control (MAC (not MAC address)) networking rules, such as those enabled by the SECMARK and CONNSECMARK targets. Mandatory Access Control is implemented by Linux Security Modules such as SELinux. The security table is called after the filter table, allowing any Discretionary Access Control (DAC) rules in the filter table to take effect before MAC rules.
For example, you can see the list of rules in a table:
sudo iptables -table filter --list sudo iptables -table nat --list
Builtin Chains
Each table has several builtin chains (name for a list of rules) defined by default.
“filter” Table Builtin Chains
INPUT
- for packets destined to local sockets (that is, packets that goes to local host.).
FORWARD
- for packets being routed through the box.
OUTPUT
- for locally-generated packets (that is, packets generated by host).
“nat” Table Builtin Chains
PREROUTING
- for modifying packets as soon as they come in.
OUTPUT
- for modifying locally-generated packets before routing.
POSTROUTING
- for modifying packets as they are about to go out.
“mangle” Table Builtin Chains
PREROUTING
- for altering incoming packets before routing.
INPUT
- for packets coming into the box itself.
OUTPUT
- for altering locally-generated packets before routing.
FORWARD
- for altering packets being routed through the box.
POSTROUTING
- for altering packets as they are about to go out.
“raw” Table Builtin Chains
PREROUTING
- for packets arriving via any network interface.
OUTPUT
- for packets generated by local processes.
“security” Table Builtin Chains
INPUT
- for packets coming into the box itself.
OUTPUT
- for altering locally-generated packets before routing.
FORWARD
- for altering packets being routed through the box.
the “filter” table is the most useful table.
Predefined Actions (buildin targets)
Remember: “target” is a name for a defined action. By default, the following are defined:
ACCEPT
= let the packet through.DROP
= drop the packet.QUEUE
= pass the packet to userspace. (slightly complicated)RETURN
= stop traversing this chain and resume at the next rule in the previous (calling) chain. This is like “break” statement in a loop in programing languages.
The above are the most basic ones. There are many others that comes with iptables but are considered “extension modules”. For example, there's also REJECT
that is like DROP
but also send back a error packet. There's also LOG
, which doesn't do anything to the packet but writes to log.
Print Options
short | command syntax | purpose |
---|---|---|
-L | --list chain rulenum | List the rules in a chain or all chains. Default table is “filter” |
-S | --list-rules chain rulenum | Print the rules in a chain or all chains |
-n | --numeric | numeric output of addresses and ports |
-v | --verbose | print more info |
◇ | --line-numbers | print line numbers when listing rules |
-x | --exact | display exact values for numerical values |
Commands to Edit Chain
Here are the commands to edit “chain”. The “chain” here is a name.
Rule in chain are ordered, and can be identified by their number, starting with 1.
short | command syntax | purpose |
---|---|---|
-A | --append chain rule | Append to chain |
-D | --delete chain rule | Delete matching rule from chain |
-D | --delete chain rulenum | Delete rule rulenum (1 = first) from chain |
-I | --insert chain rulenum | Insert in chain as rulenum (rulenum defaults to 1) |
-R | --replace chain rulenum | Replace rule rulenum (1 = first) in chain |
-X | --delete-chain chain | Delete a user-defined chain, or all user-defined chains. |
-E | --rename-chain old_chain new_chain | Change chain name, (moving any references) |
-N | --new chain | Create a new user-defined chain |
-C | --check chain rule | Check for the existence of a rule |
short | command syntax | purpose |
---|---|---|
-F | --flush chain] | Delete all rules in chain. If not specified, delete all chains |
-Z | --zero chain rulenum | clear packet counters and byte counter in chain or all chains |
short | command syntax | purpose |
---|---|---|
-P | --policy chain target | Change policy on chain to target. (chain must be a builtin one only, and target can only be one of {ACCEPT, DROP, QUEUE}.) |
Syntax for Rules
Some rules can be preceded by !
, meaning boolean inverse. That is, changing “matching” to “not matching”. These are marked by a star ★.
short | option syntax | purpose |
---|---|---|
-p | ★ --proto proto | protocol. proto is protocol number or one of {tcp, udp, udplite, icmp, esp, ah, sctp} or one in “/etc/protocols” or “all”. “all” is default. |
-4 | --ipv4 | Nothing (line is ignored by ip6tables-restore) |
-6 | --ipv6 | Error (line is ignored by iptables-restore) |
-s | ★ --source address/mask | source IP address |
-d | ★ --destination address/mask | destination IP address |
-m | --match match | turn on extended match named match. (may load extension) |
-f | ★ --fragment | match second or further fragmented packets only |
-i | ★ --in-interface name[+] | set rule to match only incoming packets on network interface name ([+] for wildcard) |
-o | ★ --out-interface name[+] | set rule to match only out going packets on network interface name ([+] for wildcard) |
◇ | --set-counters packets bytes | turn on packet counter for --insert, --append, --replace |
Options for Action (target)
short | option syntax | purpose |
---|---|---|
-j | --jump target | goto action named target (may load target extension) |
-g | --goto chain | goto rule set named chain |
General Options
short | option syntax | purpose |
---|---|---|
-t | --table table | use rules in table table (default is “filter”) |
◇ | --modprobe=cmd | try to insert modules using command cmd |
short | option syntax | purpose |
---|---|---|
-V | --version | print version number. |
The above are general options. If you work with iptables a lot, you basically have to memorize all of the above.
There are MANY MORE options, for specifying port, protocol, network adapter, TCP packet detail, …. See man iptables
.
Examples
when --table table
is not specified, the “filter” table is used by default.
# ban a MAC address sudo iptables --table filter --append INPUT --match mac --mac-source 00:0f:b4:ac:a0:58 --jump DROP
# redirect all HTTP traffic to a specific server sudo iptables --table nat --append PREROUTING --protocol tcp --dport 80 --jump REDIRECT --to-port 127.0.0.1:80
# ban a ip address sudo /sbin/iptables --table filter --append INPUT --source $ipAddr --jump DROP
# set default action to drop sudo iptables --policy INPUT DROP
Clean Your Tables, Rules, Chains
When testing, you can use --flush
to clear out the rules. You need to flush every table if you have added rules in them.
You can save the following as iptables-flush.sh
and run them in one shot sudo bash iptables-flush.sh
.
# remove all filtering rules, remove all user created chains iptables -t filter --flush iptables -t filter --delete-chain iptables -t nat --flush iptables -t nat --delete-chain iptables -t mangle --flush iptables -t mangle --delete-chain iptables -t raw --flush iptables -t raw --delete-chain iptables -t security --flush iptables -t security --delete-chain
If you have created a “policy” (default action), the flush won't clean it. You'll need to set policy yourself.
# set policy to accept sudo iptables --policy INPUT ACCEPT # you need to set policy for every table's chain too, if you've changed them. # reset SOME default policies iptables -t filter --policy INPUT ACCEPT iptables -t filter --policy FORWARD ACCEPT iptables -t filter --policy OUTPUT ACCEPT iptables -t nat --policy PREROUTING ACCEPT iptables -t nat --policy POSTROUTING ACCEPT iptables -t nat --policy OUTPUT ACCEPT iptables -t mangle --policy PREROUTING ACCEPT iptables -t mangle --policy OUTPUT ACCEPT # there's also table raw and security. # there's might be other chains too.
More Examples
# accept incoming packet that's bound to tcp and destined for ssh port sudo iptables --append INPUT --protocol tcp --dport ssh --jump ACCEPT
# accept incoming packet that's bound to tcp and destined for port 80 sudo iptables --append INPUT --protocol tcp --dport 80 --jump ACCEPT
# block all traffic sudo iptables --append INPUT --jump DROP
# accept rule to INPUT ruleset in filter table, for traffic bound to loopback address # add rule to filter table, # as 1st rule # in the INPUT set # for traffic bound to loopback address, accept sudo iptables --insert INPUT 1 --in-interface lo --jump ACCEPT
# log dropped packets sudo iptables --insert INPUT 5 --match limit --limit 5/min --jump LOG --log-prefix "dropped: " --log-level 7
# allow max of 2 telnet connections sudo iptables --append INPUT --proto tcp --syn --dport 23 --match connlimit --connlimit-above 2 --jump REJECT
# limit the number of parallel HTTP requests to 16 per class C sized source network (24 bit netmask) sudo iptables --proto tcp --syn --dport 80 --match connlimit --connlimit-above 16 --connlimit-mask 24 --jump REJECT
# the following allows one way traffic # Create chain which blocks new connections, except if coming from inside. sudo iptables --new myblock sudo iptables --append myblock --match state --state ESTABLISHED,RELATED --jump ACCEPT sudo iptables --append myblock --match state --state NEW --in-interface ! ppp0 --jump ACCEPT sudo iptables --append myblock --jump DROP # Jump to that chain from INPUT and FORWARD chains. sudo iptables --append INPUT --jump myblock sudo iptables --append FORWARD --jump myblock
source http://www.netfilter.org/documentation/HOWTO//packet-filtering-HOWTO-5.html
the following is from http://wiki.centos.org/HowTos/Network/IPTables
sudo iptables --policy INPUT ACCEPT sudo iptables --flush sudo iptables --accept INPUT -i lo -j ACCEPT sudo iptables --accept INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT sudo iptables --accept INPUT -p tcp --dport 22 -j ACCEPT sudo iptables --policy INPUT DROP sudo iptables --policy FORWARD DROP sudo iptables --policy OUTPUT ACCEPT
here's the result after above. sudo iptables --list --verbose
Chain INPUT (policy DROP 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 ACCEPT all -- lo any anywhere anywhere 0 0 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 0 packets, 0 bytes) pkts bytes target prot opt in out source destination
ipv6
# Limit the number of connections to a particular host: ip6tables --proto tcp --syn --dport 49152:65535 -d 2001:db8::1 --match connlimit --connlimit-above 100 --jump REJECT
# limit the number of parallel HTTP requests to 16 for the link local network (ipv6) ip6tables --proto tcp --syn --dport 80 --source fe80::/64 --match connlimit --connlimit-above 16 --connlimit-mask 64 --jump REJECT
Saving and Restoring Firewall Config
sudo iptables-save
→ dump iptables rules to stdout
sudo iptables-restore
→ Restore IP Tables
Reference
- short. 〔Ubuntu iptables Howto By Ubuntu Community. At https://help.ubuntu.com/community/IptablesHowTo , accessed on 2013-03-18〕
- huge. verbose. 〔Iptables Tutorial 1.2.2 By Oskar Andreasson. At http://www.frozentux.net/iptables-tutorial/iptables-tutorial.html , accessed on 2013-03-08〕
- authoritative but dated. 〔Linux 2.4 Packet Filtering HOWTO By Rusty Russell. At http://www.netfilter.org/documentation/HOWTO//packet-filtering-HOWTO.html , accessed on 2013-03-08〕
- lots others, but mostly outdated, collected here. http://www.netfilter.org/documentation/index.html
- http://wiki.centos.org/HowTos/Network/IPTables
Related Reference
- Captive portal
- Hotspot (Wi-Fi)
- 〔How to create a homebrew hot-spot with Linux By Juhapekk…@Gmail.Com. At http://code.google.com/p/quickanddirty/wiki/CreatingWirelessHotspotWithLinux , accessed on 2013-03-17〕
StackOverflow ServerFault
- http://serverfault.com/questions/207620/windows-equivalent-of-iptables
- http://serverfault.com/questions/84963/why-not-block-icmp
- http://serverfault.com/questions/268542/hardware-firewall-vs-software-firewall-ip-tables-rhel
- http://serverfault.com/questions/140622/how-can-i-port-forward-with-iptables
- http://serverfault.com/questions/245711/iptables-tips-tricks
- http://serverfault.com/questions/384132/iptables-limit-rate-of-a-specific-incoming-ip