Ubuntu 18.04 Chronicles: Applying firewall rules on startup, Pre-network

Another installment in this series. If you are used to dropping scripts in /etc/network/if-pre-up.d/ and seeing them get executed just before the network subsystem is up that’s another thing that doesn’t work in ubuntu Bionic, and you get no feedback that it doesnt.

Don’t panic though, because here I show you how to accomplish partially similar results. I say partially because my proposal here executes only on system boot, but that should suffice, because the firewall rules don’t disappear and need to be reapplied due to network status changes, and you will probably have other mechanisms in pace to deal with events that are related to network anyway.

The straightforward answer is that you now need to create a systemd service, which executes the script you would normally place in /etc/network/if-pre-up.d/. As a digression, despite the fact that systemd renders much of my previously acquired know-how useless, I actually like the logic of it’s design and so I hope that the new knowledge I’m acquiring and sharing here will be useful for long into the future.

Here’s my firewall rules script that I shamelessly adapted from Ars Technica: (the rules continue to be relevant to ubuntu Bionic, but the methods aren’t).

root@sol:/home/nucc1# cat /etc/network/iptables 
#!/bin/sh
echo "Loading Firewall Rules..."

WAN="enp3s0"
LAN="enp4s0"

logger "ROUTER: WAN: $WAN, LAN: $LAN"

logger "setting up base iptables rules"

/sbin/iptables-restore <<-EOF
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]

-A POSTROUTING -o $WAN -j MASQUERADE

COMMIT

*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]

#---------
#SERVICE RULES
#--------------------

#global accept rules
-A INPUT -s 127.0.0.0/8 -d 127.0.0.0/8 -i lo -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -m state --state ESTABLISHED -j ACCEPT

#enable traceroute rejections to be sent.

You need to create a systemd unit file in /etc/systemd/system/ with the contents below (give it any name of your choice dot service, I call mine ‘router-rules.service‘):

[Unit]
Description = Apply base firewall rules for router functionality

[Service]
Type=oneshot
ExecStart=/etc/network/iptables

[Install]
WantedBy=network-pre.target

It’s pretty easy to understand I think. Type=oneshot means, execute the script and don’t try to daemonise it or something. WantedBy=network-pre.target is the systemd way of saying to execute something just before the network is configured, which is Pre-Network.

Once this systemd service has been created, you need to enable it (otherwise, it won’t run at startup).

sudo systemctl enable router-rules.service

Et voilà! Next time your system reboots, the script will be executed, and your firewall will contain the rules it set. Notice that I designed my script to write messages to /var/log/syslog so that there is some record of it’s activity in syslog for me to review on this headless machine.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.