I used to rely on ifupdown to
bring up my iptables firewall
automatically using a config like this in /etc/network/interfaces
:
allow-hotplug eno1
iface eno1 inet dhcp
pre-up iptables-restore /etc/network/iptables.up.rules
iface eno1 inet6 dhcp
pre-up ip6tables-restore /etc/network/ip6tables.up.rules
but I wanted to modernize my network configuration and make use of systemd-networkd after upgrading one of my servers to Debian bookworm.
Since I already wrote an iptables
dispatcher script for
NetworkManager,
I decided to follow the same approach for systemd-networkd.
I started by installing networkd-dispatcher
:
apt install networkd-dispatcher moreutils
and then adding a script for the
routable
state in /etc/networkd-dispatcher/routable.d/iptables
:
#!/bin/sh
LOGFILE=/var/log/iptables.log
if [ "$IFACE" = lo ]; then
echo "$0: ignoring $IFACE for \`$STATE'" | ts >> $LOGFILE
exit 0
fi
case "$STATE" in
routable)
echo "$0: restoring iptables rules for $IFACE" | ts >> $LOGFILE
/sbin/iptables-restore /etc/network/iptables.up.rules 2>&1 | ts >> $LOGFILE
/sbin/ip6tables-restore /etc/network/ip6tables.up.rules 2>&1 | ts >> $LOGFILE
;;
*)
echo "$0: nothing to do with $IFACE for \`$STATE'" | ts >> $LOGFILE
;;
esac
before finally making that script executable (otherwise it won't run):
chmod a+x /etc/NetworkManager/dispatcher.d/pre-up.d/iptables
With this in place, I can put my iptables rules in the usual place
(/etc/network/iptables.up.rules
and /etc/network/ip6tables.up.rules
) and
use the handy iptables-apply
and ip6tables-apply
commands to test
any changes to my firewall rules.
Looking at /var/log/iptables.log
confirms that it is being called
correctly for each network interface as they are started.
Finally, create a new /etc/logrotate.d/iptables-local
file to ensure that
the log file does not grow unbounded:
/var/log/iptables.log {
monthly
rotate 1
nocreate
nomail
noolddir
notifempty
missingok
}