I recently wanted to run a VPN service on my router and needed to open the port to the outside world. After adding the rule, it didn’t work. After searching the Internet, it turns out that the problem is caused by the priority of iptbles rules. Today to give you an analysis.

Suppose we want to open port 80 of tcp to the public, we can add rules like this.

1
iptables -A INPUT -p tcp --dport 80 -j ACCEPT

where -A means append; INPUT is a chain of iptables for inbound data; -p specifies the protocol; -dport specifies the target port; and -j ACCEPT means allow through the firewall.

In theory, adding this rule is enough. But after adding it, we still can’t access port 80.

In this case, let’s look at the firewall rules.

1
2
3
4
5
6
7
8
9
iptables -L INPUT -n

Chain INPUT (policy ACCEPT)
target  prot opt source     destination
ACCEPT  all  --  0.0.0.0/0  0.0.0.0/0  state RELATED,ESTABLISHED
DROP    all  --  0.0.0.0/0  0.0.0.0/0  state INVALID
ACCEPT  all  --  0.0.0.0/0  0.0.0.0/0  state NEW
DROP    all  --  0.0.0.0/0  0.0.0.0/0
ACCEPT  tcp  --  0.0.0.0/0  0.0.0.0/0  tcp dpt:80

-L means list the current rule; -n means show the port number directly.

We see that the last line is the rule we added. It makes sense that port 80 has been released, why is it still not accessible? Do you see the problem? At that time I did not see it. A google found this article, the original iptables rules are priority of.

Look at the last two rules before.

1
2
DROP    all  --  0.0.0.0/0  0.0.0.0/0
ACCEPT  tcp  --  0.0.0.0/0  0.0.0.0/0  tcp dpt:80

The DROP above takes precedence over ACCEPT, which naturally drops all packets.

The problem here is the -A option at the beginning. -A means to append after the existing rule. To fix the problem, you need to insert the new rule in front of the existing rule . This requires the -I option. So, it should look like this.

1
iptables -I INPUT -p tcp --dport 80 -j ACCEPT

The rule, when implemented, looks like this.

1
2
3
4
5
6
7
8
9
iptables -L INPUT -n

Chain INPUT (policy ACCEPT)
target  prot opt source     destination
ACCEPT  tcp  --  0.0.0.0/0  0.0.0.0/0  tcp dpt:80
ACCEPT  all  --  0.0.0.0/0  0.0.0.0/0  state RELATED,ESTABLISHED
DROP    all  --  0.0.0.0/0  0.0.0.0/0  state INVALID
ACCEPT  all  --  0.0.0.0/0  0.0.0.0/0  state NEW
DROP    all  --  0.0.0.0/0  0.0.0.0/0

Perfect solution.