iptables contains 5 tables which in turn contain a number of built-in chains and may also contain user defined chains. Each chain is a list of rules that can match a set of packets. Each rule specifies what to do with a packet that matches. The action to take on matched packets are known as a 'target' and are specified via the --jump flag. The target can either be a chain, a target from an iptables-extension or one of the special built-in targets:
- ACCEPT: Let the packet through
- DROP: Throw away this packet and stop processing subsequent rules
- RETURN: Stop processing the packet in this chain and jump back to the previous chain
The way that a packet 'flows' through iptables can be complicated. See the below flowchart if you want to understand the details. Processing Flowchart
- INPUT: Packets destined for local sockets
- OUTPUT: Packets generated locally on the host
- FORWARD: Packets being routed through the localhost
- INPUT: Altering packets destined for local sockets
- OUTPUT: Altering packets generated locally before routing
- PREROUTING: Altering packets as soon as they arrive at the host
- POSTROUTING: Altering packets as they are about to leave the host
- OUTPUT: Altering packets generated locally before routing
- PREROUTING: Altering packets as soon as they arrive at the host
- OUTPUT Packets generated by local processes
- PREROUTING Packets arriving via any network interface
- INPUT: Packets coming into the localhost
- OUTPUT: Altering locally generated packets before routing
- FORWARD: Packets being routed through the localhost
I want to do..
- source/destination NAT: NAT
- basic firewall filtering (allow/drop): INPUT
- excempt traffic from connection tracking: RAW
- specific alterations to packet headers: MANGLE
- MAC networking rules (not to be confused with L2 MAC addresses): SECURITY
I want to..
- perform source translation (SNAT): POSTROUTING [NAT]
- perform destination translation (DNAT): PREROUTING [NAT]
- allow or drop traffic destined TO the localhost: INPUT [FILTER]
- allow or drop traffic originating FROM the localhost: OUTPUT [FILTER]
- allow or drop traffic being routed THROUGH the localhost: FORWARD [FILTER]
Q: Do rules in the OUTPUT chain in the filter table affect packets being SNAT by the localhost?
A: No. The OUTPUT chain in the filter table is only consulted when packets are generated locally by the localhost.
Q: Isn't it more performant to drop traffic in the PREROUTING chain in the raw table?
A: Yes, it's about 280% more performant (according to this article).
But it makes organizing the firewall policy much harder by spreading rules between the tables.
Look into configuring connection tracking excemptions before configuring drop rules here.
Q: When should I put drop rules in the PREROUTING chain in the raw table?
A: When performance is absolutely key, such as dropping traffic to prevent DDOS.
Q: Can I set the default policy for a user-defined chain?
A: No, default policy can only be set on built-in chains.
Q: What happens if a packet reaches the end of a chain without having matched any rules?
A: The packet will continue to traverse down the parent chain.
iptables -P INPUT DROP
iptables --append INPUT --protocol tcp --dport 22 --jump ACCEPT
iptables --append INPUT --protocol tcp --dport 22 --jump DROP
iptables --append FORWARD --source 10.0.0.0/24 --out-interface eth0 --jump ACCEPT
iptables --table nat --append POSTROUTING --source 10.0.0.0/24 --out-interface eth0 --jump MASQUERADE
iptables --table nat --append POSTROUTING --source 10.0.0.0/24 --to-source 1.2.3.4 --jump SNAT
iptables --append INPUT --match conntrack --cstate RELATED,ESTABLISED --jump ACCEPT