3

Right now I'm using /etc/rc.local to add some iptables rules on my Linux router on boot however some of the rules aren't added. I assume this is because the interface hasn't come up yet.

This is what I have in there:

sudo /sbin/iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE
sudo /sbin/iptables -A FORWARD -i ppp0 -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo /sbin/iptables -A FORWARD -i eth0 -o ppp0 -j ACCEPT

I think the ppp0 interface must take a while to come up on boot and iptables might refuse to add the rule since the ppp0 interface doesn't exist. Is there a way to force iptables to add the rule anyway? I thought I would check this before I introduce a loop into the script to wait for the interface to exist before adding the rules.

I've also observed iptables doesn't remove the rule when the interface disappears and comes back after the rule was already added (which is good behaviour in my case).

1
  • 5
    iptables will happily add rules for interfaces that don't exist yet. iptables -I INPUT -i Eimoexu1 -j ACCEPT works here (that's a random string used as an interface name). iptables -vL INPUT then shows the rule. Commented Jun 5, 2014 at 17:09

2 Answers 2

3

Use post-up in /etc/network/interfaces on any Debian-based distro. That allows you to run the script right after it was brought up by ifup. More in the man page for interfaces.

Side-note: post-down can be used to remove the rules, of course.

And if that doesn't work, because your system brings up ppp0 via some script, you can use the hook scripts in the *.d subfolders of /etc/network corresponding to the aforementioned actions. Several variables will be supplied to you in the script, such as IFACE, ADDRFAM etc. The man pages are really detailed.

On another note, internally up == post-up and down == post-down, so the correct subfolders would be if-down.d and if-up.d respectively.

And if you want to "debug" that process of bringing up an interface that is declared in /etc/network/interfaces (or sourced from there), ifup(8) has the details. In particular you'll want ifup -nvl (and perhaps the interface name). Can also be run unprivileged, because it doesn't do anything, just mimics the process.

Possible caveat

This won't work on Debian-based but Network-Manager-driven setups. But with you mentioning a router, I think it's unlikely to be driven by Network Manager.

1

You actually may add iptables rules with whatever non-existing interfaces you want, and it will work. Just give it a try # iptables -A INPUT -i trollolo -j ACCEPT and see what happens # iptables -nvL. The problem is with the /etc/rc.local approach - it is obsolete and modern Linux's initializer (in most cases it is systemd) won't even read it by default. By default, there isn't even rc-local.service in systemd, so that you need to re-create it manually if you still want to use /etc/rc.local file on your Linux, despite of this being discouraged.

The way I have chosen to persist iptables rules is with custom systemd service which may conveniently depend on other system services so that it may get executed in time.

First, create script file with your iptables rules: touch /usr/local/sbin/init_fw.sh

Put your rules in there:

#!/bin/bash
iptables -F
iptables -P INPUT DROP
................ and so on ......

Make the file executable # chmod +x /usr/local/sbin/init_fw.sh

Create systemd service file # nano /lib/systemd/system/customfw.service and paste this description there

[Unit]
Description=Custom FW

[Service]
ExecStart=/usr/local/sbin/init_fw.sh

[Install]
WantedBy=network-pre.target

Then do # systemctl start customfw. Check for errors in your rules with # systemctl status customfw. And if everything is fine, make it autorun # systemctl enable customfw.

Notice - this script is no daemon, so inactive (dead) state is fine - the job has been done. You may check it on next boot iptables -nvL

Also notice the WantedBy= part - it makes these rules to be applied before any network connection could be established in the OS.

2
  • Original question was asked in 2014, systemd wasn't as common back then Commented Jan 7, 2023 at 4:18
  • 1
    @nazar-pc this is true. And the question is formulated the way people are still inquiring today and likely to be inquiring for years ahead. "Adding an iptables rule for an interface before it comes up", you know. It seems to always be needed, as far as iptables and interfaces exist in Linux. This is why, when I saw this question and answers to it, I decided that this answer needs a little update. To keep the page helpful, because google shows it to people like me Commented Feb 28, 2023 at 14:08

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.