Setting up Shorewall for LXC container network bridging and routing

Host instructions for LXC

Ensure that the LXC bridge is enabled:

root@host:~# cat /etc/default/lxc-net
USE_LXC_BRIDGE="true"

Ensure that the virtual networking kernel module is running:

root@host:~# lsmod | grep veth
veth                   20480  0

If it is not running, load the module and check again:

modprobe veth

Configure the bridge:

root@host:~# cat /etc/lxc/default.conf
lxc.net.0.type = veth
lxc.net.0.link = lxcbr0
lxc.net.0.flags = up
lxc.net.0.hwaddr = 00:16:3e:09:ef:0f
lxc.apparmor.profile = generated
lxc.apparmor.allow_nesting = 1

Restart the daemons:

systemctl restart lxc-net lxc

Container instructions

Set the correct gateway for each container:

ip route add default via 10.0.3.1

Host instructions for Shorewall

Shorewall needs additional zone and interface configuration to allow traffic to pass from the host to the containers and back.

root@crest2:/etc/shorewall# cat zones
#ZONE   TYPE
fw      firewall
net     ipv4
lxc     ipv4

The zone name is used elsewhere in the rules and policy to refer to the interface, which is in turn defined in the interfaces file (this blog may wrap the lines, the option flags should be on the same line as each zone):

#ZONE   INTERFACE   BROADCAST   OPTIONS
net     eth0            detect          dhcp,tcpflags,logmartians,nosmurfs
lxc     lxcbr0          detect          routefilter,dhcp,tcpflags,logmartians,nosmurfs

Here the interface lxcbr0 is assigned to the lxc zone we created above. And now in the policy configuration we can allow the traffic to pass through:


#SOURCE         DEST            POLICY          LOG LEVEL       LIMIT:BURST
$FW             net             ACCEPT
$FW             lxc             ACCEPT
lxc             $FW             ACCEPT
net             all             DROP            info
# The FOLLOWING POLICY MUST BE LAST
all             all             REJECT          info

The following configuration has been applied to enable SNAT masquerading from the lxc network via the eth0 interface:

root@host:/etc/shorewall# cat snat
#ACTION    SOURCE              DEST
MASQUERADE 10.0.3.0/24         eth0

This is sufficient to allow the guests to communicate via the host.