LXD containers are not fully protected by NAT?

I found the following issues: despite the enabled NAT on the LXD hosts, all VMs and containers are still accessible from local network. Let’s imagine the following network topology:

               Switch
               +-----------------+
               |                 |
               | O O O O O O O O |
               |                 |
               +----+-------+----+
                    |       |
                    |       |
192.168.1.2         |       |    192.168.1.3
+--------------+    |       |    +-------------------------------------+
|              |    |       |    |                                     |
| Hacker       +----+       |    | LXD Host                            |
|              |            |    |                                     |
+--------------+            |    |                                     |
                            |    |  192.168.130.2      192.168.130.3   |
                            +----+  +------------+     +------------+  |
                                 |  |            |     |            |  |
                                 |  | VM1        |     | VM2        |  |
                                 |  |            |     |            |  |
                                 |  +------------+     +------------+  |
                                 |                                     |
                                 |                                     |
                                 +-------------------------------------+

While there is a NAT enabled on the LXD host, the hacker can add a route using the following
command:

$ ip route add 192.168.130.0/24 via 192.168.1.3
$ ping 192.168.130.2
PING 192.168.130.2 (192.168.130.2) 56(84) bytes of data.
64 bytes from 192.168.130.2: icmp_seq=1 ttl=63 time=3.14 ms
64 bytes from 192.168.130.2: icmp_seq=2 ttl=63 time=3.66 ms
64 bytes from 192.168.130.2: icmp_seq=3 ttl=63 time=3.62 ms
64 bytes from 192.168.130.2: icmp_seq=4 ttl=63 time=3.80 ms

and will have full access to all VMs and containers running on LXD host. This issue is reproduced both on LXD and regular LXC containers with lxc-net. Meanwhile, there no such issue for libvirt VMs and Docker containers. Looks like LXD is missing some kind of iptables filter rule.

NAT isn’t firewalling. If you want firewalling, create an ACL and apply it to the bridge.

But why doesn’t LXD apply such firewall rules while other hypervisors do?

If I’m not wrong, it is just one rule

iptables -A FORWARD -o lxdbr0 -m state --state NEW,INVALID -j DROP

Because we have quite a few users that want this behavior and for whom this would cause a regression. It’s not uncommon for someone to have a machine with containers on their LAN and then put a static route to that container subnet on another machine in order to reach them directly.

2 Likes