Systemd in Ubuntu 16.04 / core snap doesn't support iptables

Hey everyone

Today I spent some time debugging a weird network issue that affected my router running Ubuntu classic (17.04) to another box running Ubuntu classic (16.04). I chose to “downgrade” to 16.04 to take advantage of the live kernel patches (via canonical-livepatch snap).

My setup was pretty simple, USB 3G modem was NATed into the local network. I used systemd-networkd for that, specifically relying on the IPForward=yes and IPMasquerade=yes. I moved and compared my network config files around and noticed that while the box was now properly online and routing tables looked fine I could not get any connectivity from other machines on the network. Some debugging made it evident that NAT was just not applied at all. Interestingly I noticed that syslog had this message systemd-networkd[486]: eth0: Could not enable IP masquerading: Operation not supported.

Digging deeper I found that the copy of systemd in Ubuntu 16.04 (and thus ubuntu core) is built without support for iptables. This was done in Debian to save about 3.5MB in dependencies. The details are available in the following Debian bug: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=787480

In the end I ended up building systemd with a small patch (I’ll attach it here after some testing) that restored this functionality. I think it could be interesting iff we try to build simple IOT routers using systemd-networkd features and APIs.

I suspect that most people developing routers will opt to not use systemd-networkd for the foreseeable future since it isn’t widely used (AIUI), and simply use the lowlevel tools afforded by the network-control and firewall-control interfaces.