Commands / Firewall and NAT

Firewall and NAT

iptables

Also ip6tables, netfilter, firewall rules, nat table, nft

Lists and changes the kernel's firewall and NAT rules, with a counter on each rule of what it matched.

Rules sit in chains: INPUT (to this device), OUTPUT (from it), FORWARD (through it, when it routes). A packet runs down the chain until a rule matches; if none does, the chain's policy decides. The nat table rewrites addresses: POSTROUTING … MASQUERADE (share one outside address) and PREROUTING … DNAT (port forwarding). -L -n -v shows counters: send the failing traffic again, and the rule whose counter grew is the one acting on it. ip6tables is the same for IPv6.

iptables command usage

iptables [-t nat] -L [CHAIN] -n -v [--line-numbers]
iptables -S
iptables -I|-A|-D CHAIN RULE
iptables -P CHAIN ACCEPT|DROP

Options

-L -n -v
list rules with numeric addresses and counters
-S
list rules as the commands that create them
-t nat
the NAT table instead of filter
--line-numbers
number each rule, to delete by number
-I CHAIN
insert a rule at the top
-A CHAIN
append a rule at the bottom
-D CHAIN RULE / N
delete a rule, by its text or number
-P CHAIN DROP
set the chain's policy
-j DROP / REJECT / ACCEPT
what a matching rule does
-Z
zero the counters

iptables examples

iptables -L -n -v
Lists every filter rule with how many packets and bytes each matched.
iptables -S FORWARD
Prints the FORWARD chain as the commands that would recreate it.
iptables -A FORWARD -i officeNetwork -s 10.0.1.40 -j DROP
A standard access list line: drops whatever 10.0.1.40 sends in on the office card (a card named after its network).
iptables -R FORWARD 2 -o serverNetwork -s 10.0.1.40 -j DROP
Replaces line 2 with the same deny, checked out on the server card instead.
iptables -t nat -L -n -v --line-numbers
Lists the NAT rules, numbered, with their counters.
iptables -I INPUT -p tcp --dport 22 -j DROP
Drops every SSH connection to this device, silently.
iptables -I FORWARD -d 10.0.2.10 -p tcp --dport 80 -j REJECT --reject-with tcp-reset
Refuses forwarded web connections to 10.0.2.10 with a TCP reset.
iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
Lets replies to connections already allowed through: the heart of a stateful firewall.
iptables -t nat -A PREROUTING -p tcp --dport 2222 -j DNAT --to-destination 10.0.1.10:22
Forwards port 2222 on this router to SSH on 10.0.1.10.
iptables -D INPUT 1
Deletes the first rule of INPUT.
iptables -A INPUT -i lo -j ACCEPT
Allows the device to talk to itself, the first rule before a default drop.
iptables -A INPUT -p tcp -s 10.0.9.0/24 --dport 22 -j ACCEPT
Allows SSH only from the management network.
iptables -A INPUT -p tcp -m multiport --dports 80,443 -j ACCEPT
Allows both web ports in one rule.
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
Answers pings.
iptables -R FORWARD 2 -p tcp --dport 80 -j REJECT --reject-with tcp-reset
Replaces line 2 of FORWARD with a reject that answers port 80 with a TCP reset, as a host with no web server would.
iptables -P INPUT DROP
Makes DROP the policy for anything no rule accepted; add the accept rules first or you lock yourself out.
iptables -A INPUT -j LOG --log-prefix 'INPUT drop: '
Logs what reaches the end of the chain to the kernel log, before the policy drops it.
iptables -t nat -A POSTROUTING -s 10.0.1.0/24 -o eth1 -j MASQUERADE
Shares the router's eth1 address with the whole 10.0.1.0/24 network: the NAT of a home router.
iptables -C INPUT -p tcp --dport 22 -j ACCEPT
Checks whether that exact rule exists: exit 0 if it does, so a script adds it only once.
iptables-save > /etc/iptables/rules.v4
Saves every table's rules to a file; iptables-restore < /etc/iptables/rules.v4 loads them back.

Reading the output

$ iptables -L FORWARD -n -v
Chain FORWARD (policy ACCEPT 63 packets, 6066 bytes)
 pkts bytes target     prot opt in     out     source               destination
   14  1136 ACCEPT     0    --  *      *       0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
    1    60 ACCEPT     6    --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:80
    1    84 ACCEPT     1    --  *      *       0.0.0.0/0            0.0.0.0/0
    1    60 DROP       6    --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:22
  • policy ACCEPT: what happens to a packet no rule matched. On a locked-down router this is DROP.
  • pkts / bytes: how much each rule matched so far. Try again and watch which one grows.
  • prot 6 is TCP, 1 ICMP, 17 UDP, 0 any. tcp dpt:22: destination port 22.
  • Order matters: the first match wins, so an early ACCEPT makes a later DROP dead.

Pitfalls

  • DROP makes the sender wait and retry; REJECT answers at once. They look different from outside: a hang or an instant refusal.
  • Forgetting the ESTABLISHED rule lets requests out and blocks every reply: "requests leave, replies never arrive".
  • Rules on a router's INPUT do not filter traffic passing through it: that is FORWARD.

Run it on real machines

Learn it on real machines.

Every lab is a small network of real Linux machines in your browser. Start with a free account: Google or email, no card.

Start this lab, free