Linux - iptables

TABLES, CHAINS, RULES

TABLES

1. filter

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

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

4. raw

CHAINS

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

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 - Main Uses

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

# 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

FRAGMENTS

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