Firewall changes during (snap) updates

I’ve installed LXD lxd(8) version 2.21 on ubuntu 16.04.3 via snap(1) on multiple machines. The containers are bundled together using strongswan IPSec tunnels over a wide-area network. This requires the following iptables(8) rules to be inserted in the NAT table POSTROUTING chain:

Chain POSTROUTING (policy ACCEPT)
target                 prot opt source            destination
ACCEPT            all   --   10.45.35.0/24 10.23.11.0/24
ACCEPT            all   --   10.45.35.0/24 10.132.23.0/24
MASQUERADE all   --   10.45.35.0/24 !10.45.35.0/24 /* generated for LXD network lxdbr0 */

During an update, the order of the iptables rules are changed an the LXD generated rule is inserted at the beginning of the POSTROUTING chain blocking all IPSec traffic.

Chain POSTROUTING (policy ACCEPT)
target                 prot opt source            destination
MASQUERADE all   --   10.45.35.0/24 !10.45.35.0/24 /* generated for LXD network lxdbr0 */
ACCEPT            all   --   10.45.35.0/24 10.23.11.0/24
ACCEPT            all   --   10.45.35.0/24 10.132.23.0/24

Is there a way to configure LXD to append the firewall rule at the end or add the additional rules by LXD, when it comes up?

1 Like

There isn’t a way to do this directly in LXD, but one workaround you could use is to turn off NAT on the particular LXD network. This will prevent LXD from generating and removing that particular rule. You can then add a similar rule in your existing firewall script, achieving the wanted result.

Thanks for your answer, unfortunately we don’t run a firewall, yet. Is there any documentation how to combine LXD with ufw or a similar firewall package?

If you don’t run a firewall, where are those ACCEPT rules coming from?

These rules were inserted via a strongswan feature. The script configured via leftupdown created them.

Ah, ok. So yeah, you’d need another script somewhere to add the LXD masquerade entry once the lxd daemon is started.

Are there any hooks to attach a script to start/stop events of lxd (or a snap package)?

ufw may be able to do it, but it may be a bit overkill when you really just need to run:

iptables -t nat -A POSTROUTING -s 10.45.35.0/24 -d ! 10.45.35.0/24 -j MASQUERADE

The hacky way would be to dump that in /etc/rc.local, the less hacky way would be to either put it in its own init script, or attach it to the loopback device in /etc/network/interfaces, changing it from:

auto lo
iface lo inet loopback

to:

auto lo
iface lo inet loopback
    # Setup natting for LXD
    post-up iptables -t nat -A POSTROUTING -s 10.45.35.0/24 -d ! 10.45.35.0/24 -j MASQUERADE

Thanks for your tips, both solutions seem to be a little bit hacky though, because they add additional places, where possibly random generated IP-Subnet addresses from lxd have to be kept aligened with other system configuration files. And both increase the complexity when creating images if you’ll run lxd inside OpenStack for example.

I would like to see an additional configuration option in lxd to ease integration with other software components. Another solution could be to change the ipv4.nat configuration option in a backward compatible way. It could be made tree-state instead of boolean, taking the following options:

  1. true | insert (default) - insert a masquerading firewall rule in the POSTROUTING chain at the beginning
  2. false
  3. append - append a masquerading firewall rule to the POSTROUTING chain
1 Like

Both solutions create the rules, when the interface lo is configured. The rules are moved to the end of the table, when LXD is being reloaded by snap during an update.