Linux Netfilter IPtables Configuration
Firewall, NAT and packet mangling in Linux
Linux subsystems to filter/classify packets/datagrams/frames …netfilter 1 configured with {ip,ip6,arp,eb}tables
commands …stateless/stateful packet filtering (firewall) …network address and port translation (NAT), masquerading, transparent proxies …QoS and policy routes with iproute2
packet manipulation (mangling)
nftables intended to replace Netfilter ..configured with nft
command …re-uses existing Netfilter subsystems …backward compatibility layer supports {ip,ip6}tables
commands.
iptables
Kernel hooks in network stack for all incoming/outgoing traffic:
Hook | Description |
---|---|
NF_IP_PRE_ROUTING | Before any routing decision |
NF_IP_LOCAL_IN | After routing, package destined for the local system |
NF_IP_FORWARD | After routing, package forwarded to another host |
NF_IP_LOCAL_OUT | Locally created outbound traffic |
NF_IP_POST_ROUTING | Outgoing/forwarded traffic after routing |
Multiple modules connect to each hook in deterministic order (using a priority number). Modules process a package and return a decision indicating package destination.
Rules & Targets
Packet filtering organized in rules …rules classify according to the type of decisions they are used to make …further organized within separate chains (representing the netfilter hooks) …rules are placed within a specific chain of a specific table. Basic syntax like…
iptables <options> <chain> <matches> <target>
Property | Description |
---|---|
chain |
Rules are placed within a specific chain of a specific table |
matches |
Criteria that a packet must meet for the associated action |
target |
Action triggered if a packet metss matching criteria of a rule |
Targets divided into multiple categories…
Target | Description |
---|---|
terminating | Terminates evaluation within the chain |
non-terminating | Continue evaluation within the chain |
jumping | Move to a different chain for additional processing |
Examine tables, chains and rules:
iptables -L -n # view current rules
iptables -t filter --line-numbers -n --exact -v -L # ^ in more details
iptables -L INPUT -n -v # show specific chain i.e. INPUT
iptables -t nat -L -v -n # show chain in the NAT table
Chains & Tables
Chains are collections of rules …basically determine when rules will be evaluated …if no rule matches the default is applied …either built-in (i.e. INPUT) or user defined. List of built-in chains…
Chain | Comment |
---|---|
PREROUTING | packets traverse this chain before routing |
INPUT | incoming packets terminating at localhost |
OUTPUT | outgoing packets originating from localhost |
FORWARD | packets not terminating or originating at/from localhost |
POSTROUTING | packets traverse this chain after routing |
Tables are collections of multiple chains…
Table | Comment |
---|---|
filter | (default) actual packet filtering |
nat | rewrite packet source/destination |
mangle | alter packet headers/contents |
raw | avoid connection tracking |
security | SELinux internal |
# list tables
iptables -vL -t filter
iptables -vL -t nat
iptables -vL -t mangle
iptables -vL -t raw
iptables -vL -t security
Chains implemented in each table…
Table↓/Chains→ | PREROUTING | INPUT | FORWARD | OUTPUT | POSTROUTING |
---|---|---|---|---|---|
(routing decision) | ✓ | ||||
raw | ✓ | ✓ | |||
(connection tracking) | ✓ | ✓ | |||
mangle | ✓ | ✓ | ✓ | ✓ | ✓ |
nat (DNAT) | ✓ | ✓ | |||
(routing decision) | ✓ | ✓ | |||
filter | ✓ | ✓ | ✓ | ||
security | ✓ | ✓ | ✓ | ||
nat (SNAT) | ✓ | ✓ |
DNAT
operations alter the destination address of a packet,SNAT
operations alter the source address- Chains process from top-to-bottom (i.e.
PREROUTING
from all tables top-to-bottom, beforeINPUT
) - chain traversal order
Source/Destination | Chains |
---|---|
Incoming to localhost | PREROUTING → INPUT |
Forwarding to another host | PREROUTING → FORWARD → POSTROUTING |
Localhost outgoing | OUTPUT → POSTROUTING |
Usage
Store and/or restore a rule-set from a file:
iptables-save > /etc/iptables/iptables.rules
iptables-restore < /etc/iptables/iptables.rules
Flush everything…
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
iptables -t raw -F
iptables -t raw -X
iptables -A INPUT -p tcp -syn -j DROP # drop incoming packets
## previously initiated and accepted exchanges to bypass rule checking
iptables -A INPUT -m state —state ESTABLISHED,RELATED -j ACCEPT
## drop ICMP traffic
iptables -A OUTPUT -p icmp -j DROP
Enable IP forwarding in the kernel
# persistant configuration
grep ^net.ipv4.ip_forward /etc/sysctl.conf && sysctl -p
net.ipv4.ip_forward=1
# enable with sysctl
sysctl -w net.ipv4.ip_forward=1
# or enable in /proc
echo 1 > /proc/sys/net/ipv4/ip_forward
# add a NAT with forwarding rules
iptables -t nat -A POSTROUTING -o <ext-iface> -j MASQUERADE
iptables -A FORWARD -i <int-iface> -j ACCEPT
Open ports for services
## Accept outgoing traffic for DNS
iptables -A OUTPUT -p udp -o eth0 --dport 53 -j ACCEPT
iptables -A INPUT -p udp -i eth0 --sport 53 -j ACCEPT
# outgoing SSH
iptables -A OUTPUT -o eth0 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
# incoming SSH
iptables -A INPUT -i eth0 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
# block logins after 3 failed attempts
iptables -I INPUT -p tcp --dport 22 -i eth0 -m state --state NEW -m recent --set
iptables -I INPUT -p tcp --dport 22 -i eth0 -m state --state NEW -m recent --update --seconds 60 --hitcount 4 -j DROP
# HTTP
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
# better
iptables -A INPUT -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT
# redirect 80 to 8080
iptables -t nat -A OUTPUT -o lo -p tcp --dport 80 -j REDIRECT --to-port 8080
# Accept SMTP/POP3 traffic
iptables -A INPUT -p tcp --dport 25 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --sport 25 -m state --state ESTABLISHED -j ACCEPT
iptables -A INPUT -p tcp --dport 110 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --sport 110 -m state --state ESTABLISHED -j ACCEPT
## disable outing mails
iptables -A OUTPUT -p tcp --dports 25,465,587 -j REJECT
Specific sources & destinations
# accept incoming packets from a specific IP
iptables -A INPUT -s 1.2.3.4 -j ACCEPT
# drop incoming packets from a given IP
iptables -A INPUT -s 1.2.3.4 -j DROP
iptables -D INPUT -s 1.2.3.4 -j DROP # unblock
iptables -A INPUT -p tcp -s 1.2.3.4 -j DROP # specific protocol
iptables -A INPUT -s 1.2.3.4/24 -j DROP # for an IP range
# reject outgoing connection for a specific ip/port
iptables -A OUTPUT -p tcp --dport 1234 -s 1.2.3.4 -j REJECT
# drop traffic from a MAC address
iptables -A INPUT -m mac --mac-source 00:00:00:00:00:00 -j DROP
# control traffic to a given port
iptables -A INPUT -p tcp --dport 1234 -j ACCEPT # allow incoming connections
iptables -A OUTPUT -p tcp --dport 1234 -j DROP # block outgoing connections
iptables -A INPUT -p tcp -i eth0 -p tcp -dport 1234 -j DROP # ^on selected interface
iptables -A INPUT -p tcp -s ! 1.2.3.4/24 -dport 1234 -j DROP # ^except a specific IP range
# drop traffic from a given site
iptables -A OUTPUT -p tcp -d www.google.com -j DROP
iptables -A OUTPUT -p tcp -d goolge.com -j DROP
Footnotes
Linux Netfilter
https://netfilter.org↩︎