Linux - iptables
- Linux firewall
- Works via packet filtering
- More aptly called iptables/netfilter
- iptables is the userspace module
- netfilter is the kernel module
TABLES, CHAINS, RULES
- iptables breaks down into tables (which are all predefined)
- Each table has chains
- There are built-in chains (pre-defined and cannot be deleted). You can also create your own user-defined chains
- Each chain has a rule set (an ordered set of rules)
- In other words, TABLES -> CHAINS -> RULES
- The type of traffic determines which tables and built-in chains (and therefore rules) are consulted.
- iptables/netfilter also provides NAT (Network Address Translation) -- which allows you to modify the source or destination addresses of packets
TABLES
1. filter
- The default table (i.e. if the -t option is omitted)
- Unless otherwise noted, the notes on this page refer to this table
- Has 3 built-in chains
- INPUT (for packets destined for this machine)
- OUTPUT (for packets originating from this machine)
- FORWARD (for packets being routed through this machine -- i.e. when this machine is being used as a router)
filter Table
FORWARD Chain
(packets being routed thru this machine - i.e. the machine is a router)
|
+--------|----------+
| | |
INPUT Chain -----> | -----> OUTPUT Chain
(packets destined for this machine) | (packets originating from this machine)
| | |
| | |
| | |
+--------|----------+
|
\ /
2. nat
- For NAT (network address translation -- see below).
- NAT alters the source or destination address of packets
- It is consulted when a packet that creates a new connection is encountered.
- Has 3 built-in chains
- PREROUTING (for altering packets as soon as they come in)
- POSTROUTING (for altering packets as they are about to go out)
- OUTPUT (for altering packets sent from app on local machine) - app > OUTPUT > POSTROUTING > interface
- INPUT (for altering packets destined for the local machine) - interface > PREROUTING > INPUT > app
nat Table
+-------------------+
| |
PREROUTING Chain -----> OUTPUT Chain
(altering packets as soon as they arrive) ----->
| |
POSTROUTING Chain <----- |
(altering packets as they're about to depart) |
| |
+-------------------+
3. mangle
- Used for specialized packet alteration.
- It has five built-in chains
- PREROUTING (for altering incoming packets before routing)
- OUTPUT (for altering locally-generated packets before routing)
- INPUT (for packets coming into the box itself), FORWARD (for altering packets being routed through the box)
- POSTROUTING (for altering packets as they are about to go out)
4. raw
- Used 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.
- It provides the following built-in chains
- PREROUTING (for packets arriving via any network interface)
- OUTPUT (for packets generated by local processes)
CHAINS
- There are two types of chains - built-in chains (cannot be deleted) and user-defined chains
- Based on the type of traffic, the rules of the appropriate built-in chain are consulted in order
- Each rule has criteria and an action (target)
- If the criteria of a rule is matched, the action of the rule is followed
- Rule actions can be: ACCEPT (accept the packet), DROP (drop the packet) or jump to a user-defined chain.
- User-defined chains are traversed similar to built-in chains. However, if no rule of the chain matches the packet, traversal resumes at the next rule of the calling chain
- If all the rules of the built-in chain are traversed, the default action for the chain is taken -- which must be either ACCEPT or DROP
- User-defined chains names must be <= 31 characters and by convention are usually lowercase
- User-defined chains allow you to group related rules together
iptables COMMAND USAGE
Options to Manage an Entire Chain
iptables [-t table] -L [chain] -nv --line-numbers -Z
- list the rules for a chain (or all chains)
- -n to avoid dns lookups and display ip addresses
- -v for verbose - will display byte and packet counts
- -Z will atomically display and zero out byte counts
iptables [-t table] -S [chain] -v
- print all rules in the selected chain in iptables-save format.
- -v for verbose - will display byte counts
iptables [-t table] -N <chain>
- create a new chain
iptables [-t table] -X <chain>
- delete an empty chain
iptables [-t table] -E <old-chain> <new-chain>
- rename chain
iptables [-t table] -P <chain> <target>
- set default policy for given chain. Only pre-defined chains can have default policy and default policies cannot be another chain -- i.e. must be ACCEPT, DROP
iptables [-t table] -F [chain]
- remove (flush) all rules in the specified chain
Options to Manage Rules of a Chain
iptables [-t table] -A <chain> <rule-specification>
- append rule to the end of the selected chain
iptables [-t table] -I <chain> [rule#] <rule-specification>
- insert rule at specified rule number. 1 is the default rule number. i.e. 1st rule in the list (highest priority)
iptables [-t table] -D <chain> <rule#>
- delete rule
iptables [-t table] -R <chain> <rule#> <rule-specification>
- replace rule
Options to Manage a Rule - Selectors & Actions
-i [!] in interface
- lo (loopback), eth0, ... .
- An interface name ending with '+' will match all interfaces which begin with that string (e.g. eth+) .
- ! negates
-o [!] out interface
- see comments for
-i
-p [!] protocol
- ICMP, TCP, UDP.
- Case insensitive
- ! negates
-s [!] source IP address[/mask]
- source IP address.
- do not use a name which needs to be looked up via remote call (e.g DNS).
- masks specify which part of the IP address is significant
- mask can either be a network mask (e.g. 255.255.255.0) or a plain number (e.g. 24), where the plain number is the number of 1's in the left side of the network mask.
- ! negates
-d [!] destination address[/mask]
- destination address.
- see comments under source IP address.
--sport port
- source port
--dport port
- destination port
-f
- the rule only applies to the 2nd or later fragments. See section on fragments below.
-j action
- action to take -- ACCEPT, DROP, another chain name
iptable MODULES
- Both netfilter and iptables can be extended via modules
- Kernel modules usually live in /lib/modules/2.XXX/kernel/net/ipv4/netfilter
- iptable modules are shared libraries (.so) which usually live in /usr/local/lib/iptables. However, distributions usually put them in /lib/iptables or /usr/lib/iptables
- Modules come in two flavors: new targets (other than ACCEPT, DROP) and new matches (for example state matching)
- Use the -m option to load an extension
- State matching. See example above. The following states are supported: NEW (a packet which creates a new connection), ESTABISHED (a packet which belongs to an existing connection), RELATED (a packet which is related to, but not a part of, an existing connection -- for instance a packet establishing a ftp data connection), INVALID (a packet which could not be identified)
- Examples of target modules are LOG -- which provides kernel logging of matching packets, and REJECT which is similar to DROP except that the sender receives a ICMP port unreachable error message.
A BASIC FIREWALL
iptables -P INPUT ACCEPT # input chain -- temporarily allow all connections so we do not lose connection (if necesary)
iptables -F # flush rule set -- clear all rules (other than default rules)
iptables -A INPUT -i lo -j ACCEPT # input chain -- append rule (-A) accept all on loopback interface (127.0.0.1)
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # input chain -- append rule (-A) accept all packets on previously established connections
iptables -A INPUT -p tcp --dport 22 -j ACCEPT # input chain -- append rule (-A) allow ssh
iptables -A INPUT -s 192.168.0.0/255.255.255.0 -j ACCEPT # input chain -- append rule (-A) allow connections from known ip addresses
iptables -P INPUT DROP # input chain -- default policy -- DROP
iptables -P FORWARD DROP # forward chain -- default policy -- DROP
iptables -P OUTPUT ACCEPT # output chain -- default policy -- ACCEPT
iptables -L -v # list the rules
iptables-save >/etc/iptables/rules.v4 # save the rule set such that it's reloaded upon reboot (requires iptables-persistent)
NAT - Network Address Translation
What is NAT?
- NAT alters the source or destination address of packets
- The NAT table has two main chains. The
PREROUTING
chain allows altering of packets before they reach the INPUT
chain. The POSTROUTING
chain allows you to alter packets after they exit the OUTPUT
chain
- NAT comes in two flavors: Source NAT (SNAT) and Destination NAT (DNAT).
- Source NAT (SNAT) is when you alter the source address before it leaves the system (i.e. on the way to internet). It is always done post-routing. The destination will return the packet to the NAT device. Therefore the NAT enabled device must keep track of all packets in which it changed such that it can deliver any related packets the proper source.
# SNAT Example
iptables -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j SNAT --to-source <public-address>
- Masquerading is a special case of SNAT in which the source address is taken from the interface
# MASQUERADE Example
iptables -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j MASQUERADE
- Destination NAT (DNAT) is when you alter the destination address. It's typically used to allow packets from the internet to be redirected to an internal server in your DMZ. DNAT is always done pre-routing -- when the packet first comes off the wire. Port forwarding and proxying are examples of DNAT.
# DNAT Example
iptables -t nat -A PREROUTING -p tcp --dport <incoming-port> -j DNAT --to-destination <destination-ip>:<destination-port>
NAT - Main Uses
- Share your internet connection with other machines that do not have a public IP address. In order to accompish this, you must alter the source address of the packets leaving the local network and the destination address of the packets destinated for the local network. This is commonly known as IP masquerading.
- Sometimes you have one public internet address, but would like different hosts to handle the traffic destinated for different ports. This is commonly known as port forwarding
- Proxying. Routing packets which are being routed through the current host are instead routed to a program running on the local host
DNAT Quick Start
# all incoming tcp connections to port 80 should be sent to 192.168.1.2:8080
iptables -A PREROUTING -t nat -i <in-interface> -p tcp --dport 80 -j DNAT --to-destination 192.168.1.2:8080
# allow forwarding to 192.168.1.2:8080
iptables -A FORWARD -p tcp -d 192.168.1.2 --dport 8080 -j ACCEPT
Masquerading Quick Start
- Masquerading is actually a specialized case of source NAT (SNAT).
# temporarily turn on IP forwarding
echo 1 >/proc/sys/net/ipv4/ip_forward
# edit /etc/sysctl.conf and uncomment the following line to make it permanent
net.ipv4.ip_forward=1
# NAT table (-t NAT), append rule to chain POSTROUTING (-A) with action masquerade (-j MASQUERADE)
# output interface (-o) eth0 -- the interface which speaks to the outside world
# POSTROUTING alters packets as they're about to depart
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
# allow all forwarding communication from eth1 (internal network) to eth0 (outside world)
iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT
# allow all established forwarding communication from eth0 (outside world) to eth1 (internal network)
iptables -A FORWARD -i eth0 -o eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT
# verify firewall settings
# -S = iptables-save format
iptables -t nat -S
iptables -S
# save firewall settings so they'll be restored upon reboot (via iptables-persistent)
iptables-save >/etc/iptables/rules.v4
NAT Options to Manage a Rule
- You can specify the source (-s) or destination (-d) IP addresses
- You can the input (-i) or output (-o) interface to match. However, on the PREROUTING chain, you can only specify the input interface. Similarly, on the POSTROUTING chain, you can only specify the ouptut interface
FRAGMENTS
- Sometimes, a packet is too large and it gets split into fragments
- When this happens, only the initial fragment has the complete header
- If you are doing NAT or are working with the INPUT chain, then all fragments will be merged into the origial packet before reaching the packet filtering engine
iptables MODULE
lsmod | grep ip_tables
- check if iptables module is loaded
ismod ip_tables
- if your kernel has iptables support as a module and you need to load it
Auto-start
Netfilter Packet Traversal
Incoming Packets: Internet to Local Machine
conntrack > mangle.prerouting > nat.prerouting (dnat) > mangle.input > ?nat.input? > filter.input > local_app
Incoming Packets: Internet to Machine on LAN
conntrack > mangle.prerouting > nat.prerouting (dnat) > mangle.forward > filter.forward > LAN
Outgoing Packets: Local Machine to Internet
conntrack > mangle.output > nat.output > filter.output > mangle.postrouting > nat.postrouting (snat/masquerading)
Outgoing Packets: Machine on LAN to Internet
mangle.forward > filter.forward > mangle.postrouting > nat.postrouting (snat/masquerading)
See
Netfilter Packet Traversal Diagram
Acknowledgements
- iptables howto
- NAT howto
- iptables man page