Search code examples
networkingcontainerspcaplxdpromiscuous-mode

Is there a way I can make LXD container capture packets while keeping parent interface available in host machine to capture packets from there too?


Hello StackOverflow community,

I have a specific scenario I’m trying to implement, and I haven’t found any solution on this forum. I hope you guys may be able to help me.

I currently have a Lubuntu 22.04 host with 2 Network Cards:

First card (ens33) is acting as a management interface (to manage the Host and have access to the internet) Second card (ens34) is acting as a promiscuous interface (port-mirroring configured on switch to send traffic on that interface). if I run tcpdump -i ens34 on the host machine, I am able to see the captured packets.

Now my first test was to be able to capture packets inside of an LXD container, so I ran this command: lxc config device add centos-worker1 eth1 nic name=eth1 nictype=physical parent=ens34

with this, when I ran tcpdump -i eth1 inside of centos-worker1 container, I was once again able to capture packets.

However, as you already know, using nictype=physical makes ens34 interface from the host vanish, and this interface will only be accessible by centos-worker1 container under the name of eth1.

This is where I’m currently stuck, because my second test consists of using ens34 somewhere else. (A virtualbox VM running on the Host machine in parallel to LXD.)

I tried replacing nictype=physical to nictype=macvlan, but when I run tcpdump -i eth1 in container, I am unable to get captured packets.

I tried creating a bridge on the host ip link add ens35 type bridge and linking it to ens34 using ip link set ens34 master ens35 and then pushing a copy of ens35 in centos-worker1 by replacing nictype to bridged for parent=ens35 but tcpdump still has no traffic on eth1 (even though both ens34 and ens35 have traffic on host)

I tried adding firewall rules like ufw allow in on ens35, ufw route allow in on ens35, ufw route allow out in ens35 in case my firewall was blocking traffic. However I still don't see traffic inside of the container. I saw about 70 packets under 168.254.X.X ip address, when I was actually sending 40 000 packets to that interface. So I don’t think these 70 packets were linked in any sort to my 40 000 packets. I think they were just some intercommunication between the bridge probably. On the host however, I was able to view these 40 000 packets with tcpdump.

Is there a way where I can make my LXD container capture packets while at the same time keep my parent interface in my host machine so that I can also use it to capture traffic in parallel?

Thanks a lot for you help on this topic.


Solution

  • I finally figured it out.

    In netplan I configured a bridge called br0 with parameters:

    • stp to false
    • forward-delay to 0
    • ageing-time to 0

    I then allowed the bridge to forward traffic via ufw:

    • ufw allow in on br0
    • ufw route allow in on br0

    I then configured a device on LXD node, using the bridged nictype with parent=br0.

    And finally I enabled promisc on the bridge and all interfaces connected to the bridge.