I'd like to load iptables rules on boot or interface going up on Ubuntu. Made a search on StackExchange and other places and looks like the most commonly agreed approach is either use iptables-save
/iptables-restore
or iptables-persistent
package. I'd prefer (may be due to my not yet matured Linux nature) to keep iptables rules in "explicit" form (e.g. iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT
) instead of having all different rules dumped into the same persistent file where, without comments and some structure, could be tricky to find a particular rule and change it.
What I did so far - I've added following line to the /etc/network/interfaces
post-up sh -c "/etc/iptables/eth0.post-up.sh"
where eth0.post-up.sh
is a file where iptables are explicitly set (e.g. iptables -A FORWARD -i eth0 -o eth1 -m state --state ESTABLISHED,RELATED -j ACCEPT
). All would be good, rules are applied, but the reason I'm writing here is that if I try to run iptables -L FORWARD
then I don't see the loaded rules, though I'm sure they are applied (it's a subnet forwarding rules and I see that ping goes through when the rule has run and that it doesn't when the rule hasn't run. Here is the output:
# iptables -L FORWARD
Chain FORWARD (policy DROP)
target prot opt source destination
ufw-before-logging-forward all -- anywhere anywhere
ufw-before-forward all -- anywhere anywhere
ufw-after-forward all -- anywhere anywhere
ufw-after-logging-forward all -- anywhere anywhere
ufw-reject-forward all -- anywhere anywhere
ufw-track-forward all -- anywhere anywhere
If I comment out the above post-up ... in the /etc/network/interfaces
file (making sure the rules are not applied) and then run the rules manually I get the output:
# iptables -L FORWARD
Chain FORWARD (policy DROP)
target prot opt source destination
ufw-before-logging-forward all -- anywhere anywhere
ufw-before-forward all -- anywhere anywhere
ufw-after-forward all -- anywhere anywhere
ufw-after-logging-forward all -- anywhere anywhere
ufw-reject-forward all -- anywhere anywhere
ufw-track-forward all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
So, the rules are applied in both cases, but in the former case then iptables -L
doesn't show the rules, and in later ase it does.
Ultimately it works but I'd like to understand what's the caveat here, why it looks like I'm the only one around who is trying to use this approach, and why iptables -L
doesn't give me expected output.
UPDATE: have to correct myself, not all iptables rules in eth0.post-up.sh
file are executed, out of 3 commands below:
/sbin/iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT
/sbin/iptables -A FORWARD -i eth0 -o eth1 -m state --state ESTABLISHED,RELATED -j ACCEPT
/sbin/iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
only the last one (wiht POSTROUTING) is executed which is required for ping to go through, where as the first two neither have any traces in the iptables -Lnv FORWARD
nor result in connection getting established (e.g. wget google.com
) from another computer which uses this box as a router. But if I run this file manually after boot - then all is executed correctly, both ping and wget from remote computer work as expected.
sh "/etc/iptables/eth0.post-up.sh"
?