This is about how to make sense of the chains found in the iptables
default configuration on a typical home router running OpenWrt (a stripped down Linux for router devices), but which ultimately may not be specific to that particular system.
Let's focus on the INPUT
main chain here, and disregard FORWARD
and OUTPUT
from the same table, as well as PREROUTING
and POSTROUTING
from the nat
table.
Doing an iptables -L -t filter
shows a large number of rules. I have rearranged the output below to make it less intimidating, and in an attempt to pinpoint the parts that hamper my understanding.
There are three built-in chains in the filter
table, which appear at the top of the output. (I specified -v
because I find it less confusing.)
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
1260 133K ACCEPT all -- any any anywhere anywhere ctstate RELATED,ESTABLISHED
8 544 ACCEPT all -- lo any anywhere anywhere
787 41632 syn_flood tcp -- any any anywhere anywhere tcp flags:FIN,SYN,RST,ACK/SYN
13012 1249K input_rule all -- any any anywhere anywhere
13012 1249K input all -- any any anywhere anywhere
Chain FORWARD … # not considering this chain here
Chain OUTPUT … # not considering either
As you can see, I snipped the chains referenced from FORWARD
and OUTPUT
in order to focus on INPUT
. (I could have chosen any of the other two as they are built up in a similiar manner.)
INPUT
has a policy of ACCEPT
, and it specifies five rules. The first three ones are clear to me. First, accept stuff that is "established" or "related". (For example, accept the response from an HTTP or DNS request I made.) Seconds, accept everything going to the loopback device (127.0.0.1
). (This may only come from localhost itself, and I do want that to work. Wouldn't make sense otherwise.) Third, have a synflood protection. (Which protects against a certain kind of attack.)
Chain syn_flood (1 references)
pkts bytes target prot opt in out source destination
787 41632 RETURN tcp -- any any anywhere anywhere tcp flags:FIN,SYN,RST,ACK/SYN limit: avg 25/sec burst 50
0 0 DROP all -- any any anywhere anywhere
But then, there are two rules branching into two chains called input
and input_rule
, and the question is, why are there two of them, and which one are you supposed to use for what?
Let's drill down the jump stack of those rules.
Chain input_rule (1 references)
pkts bytes target prot opt in out source destination
There's nothing in here yet. It is meant for me to add rules. But what kind of rules?
Chain input (1 references)
pkts bytes target prot opt in out source destination
6315 482K zone_lan all -- br-lan any anywhere anywhere
6697 767K zone_wan all -- pppoe-wan any anywhere anywhere
Okay, this one does have stuff, jumping further down into LAN and WAN, which makes sense for a home router.
Chain zone_lan (1 references)
pkts bytes target prot opt in out source destination
6315 482K input_lan all -- any any anywhere anywhere
6315 482K zone_lan_ACCEPT all -- any any anywhere anywhere
Chain zone_wan (1 references)
pkts bytes target prot opt in out source destination
0 0 ACCEPT udp -- any any anywhere anywhere udp dpt:bootpc
0 0 ACCEPT icmp -- any any anywhere anywhere icmp echo-request
6697 767K input_wan all -- any any anywhere anywhere
6697 767K zone_wan_REJECT all -- any any anywhere anywhere
As you can see, each one of those rules jumps further down the stack to more user-defined rules.
Chain input_lan (1 references)
pkts bytes target prot opt in out source destination
Chain zone_lan_ACCEPT (2 references)
pkts bytes target prot opt in out source destination
4 1322 ACCEPT all -- any br-lan anywhere anywhere
6315 482K ACCEPT all -- br-lan any anywhere anywhere
What is the purpose of input_lan
? The other one is probably to accept packets, but it makes me wonder … the policy for INPUT
is ACCEPT
, so why repeat ACCEPT
here?
Now, input from WAN. If you scroll up you can see that some UDP and ICMP stuff is accepted. This is for DHCP and, basically, ping
. That much is clear. What is less clear, again, is the partially empty stuff following those rules:
Chain input_wan (1 references)
pkts bytes target prot opt in out source destination
Same question as for input_lan
.
Chain zone_wan_REJECT (2 references)
pkts bytes target prot opt in out source destination
0 0 reject all -- any pppoe-wan anywhere anywhere
6697 767K reject all -- pppoe-wan any anywhere anywhere
Okay, that is input from WAN (not established or related), and yes, we probably want to reject it, and now there are two kinds of rejection here, one closing the socket (tcp-reset
) for TCP connection attempts, and another one via ICMP reply (icmp-port-unreachable
) for ICMP messages (think ping
).
Chain reject (5 references)
pkts bytes target prot opt in out source destination
595 31817 REJECT tcp -- any any anywhere anywhere reject-with tcp-reset
4858 582K REJECT all -- any any anywhere anywhere reject-with icmp-port-unreachable
This last one is a catch-all. So nothing will get accepted here.
Finally, here's a list of other chains found in the filter
table that aren't referenced from the built-in INPUT
chain in the net
table. Just for completeness, and to see that they seem to have analogous constructs.
# other chains, not reached from the INPUT chain, so truncated and moved here
Chain forward (1 references)
Chain forwarding_lan (1 references)
Chain forwarding_rule (1 references)
Chain forwarding_wan (1 references)
Chain nat_reflection_fwd (1 references)
Chain output (1 references)
Chain output_rule (1 references)
Chain reject (5 references)
Chain zone_lan_DROP (0 references)
Chain zone_lan_REJECT (1 references)
Chain zone_lan_forward (1 references)
Chain zone_wan_ACCEPT (2 references)
Chain zone_wan_DROP (0 references)
Chain zone_wan_forward (1 references)
So, well. Sorry for this long post. There were a couple questions along the way. I don't know how to put this in an easier or shorter way. This iptables
configuration is not exactly easy to grasp because there are unclear details spread about here and there. Hope you can clarify this and explain the underlying rationale. Thanks for your attention.