Search code examples
networkingmininetsdnopenvswitchlinux-namespaces

Can't capture packets from namespace interface


My goal

Hi everyone! So my goal is to run a python listener on an interface inside a namespace to catch EAP messages.

To be more specific: I'm running a Faucet SDN controller and a topology created in mininet. In faucet SDN controller there is a module called Chewie which is responsible for handling 802.1X messages (acts as an authenticator). It works by listening on a port that is specified in a config (NFV port). Than it checks values against RADIUS server and sends a response.

A problem

My problem is that I can't get Chewie to actually capture packets that are sent to the interface. What I think is happening is that Chewie is listening on an interface that are visible from host side (e.g. veths interfaces, in my case s1-eth3)

root@ubuntu2004:~# ip link show
[...]
33: s1-eth3@if2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master ovs-system state UP mode DEFAULT group default qlen 1000
    link/ether d2:90:29:3a:15:f7 brd ff:ff:ff:ff:ff:ff link-netnsid 1

but what it should actually listen on is an interface seen from inside a namespace - in my case listener-eth0 (I'm really sorry if I'm speaking nonsens here, I'm in the process of learning about all of this stuff)

mininet> listener ifconfig
listener-eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.0.0.2  netmask 255.0.0.0  broadcast 10.255.255.255
        inet6 fe80::2095:66ff:feab:8918  prefixlen 64  scopeid 0x20<link>
        ether 22:95:66:ab:89:18  txqueuelen 1000  (Ethernet)
        RX packets 31  bytes 3536 (3.5 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 13  bytes 1006 (1.0 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
[...]

And I don't know how can I provide access to this port, because just giving a name isn't enough (I get error that this device could not be found)

I know that Chewie is working because when I sent a EAP packet directly to the lo interface and set Faucet/Chewie to listen on it it reacted correctly and started authentication process: Wireshark capture of EAP protocol working

Also I checked whether packet are routed by the switch correctly but it's also true because:

  • wireshark sees EAP start packets Wireshark capture of EAP start packet visible on the interface

  • there is a flow installed that corresponds to this traffic - here I'm not sure why MAC address is being modified:

cookie=0x5adc15c0, duration=906.988s, table=0, n_packets=0, n_bytes=0, priority=20481,in_port="s1-eth1",dl_type=0x888e actions=mod_dl_dst:00:00:00:00:00:01,output:"s1-eth3"

What I tried

  • to set listening on lo (in Faucet config) and running wpa_supplicant on lo from host - it worked, Chewie got a packet
  • to set listening on a standard interface (in my case enp0s3) and added it to the openvswitch. Chewie didn't got a packet
  • to set listening on a created interface by mininet (s1-eth3) - Chewie didn't get a packet

Additional info

There is not a lot of information out there about this configuration. Bits and pieces that I was able to find:

Minimum setup needed to recreate it

  • installed mininet with this topology:
from mininet.topo import Topo  
  
  
class MyTopo(Topo):  
    "Simple topology example."  
  
    def build(self):  
        "Create custom topo."  
  
        # Add hosts and switches  
        client = self.addHost('client')  
        server = self.addHost('server')  
        listener = self.addHost('listener')  
        switch = self.addSwitch('s1')  
  
        # Add links  
        self.addLink(client, switch)  
        self.addLink(server, switch)  
        self.addLink(listener, switch)  
  
  
topos = {'mytopo': (lambda: MyTopo())}
  • installed faucet (service with root privileges because chewie has to be able to open a socket), with this configuration:
vlans:
    office:
        vid: 100
        description: "office network"
    radius:
        vid: 200
        description: "radius network"

dps:
    sw1:
        dp_id: 0x1
        dot1x:
            nfv_intf: s1-eth3
            nfv_sw_port: 3
            radius_ip: 127.0.0.1
            radius_port: 18120
            radius_secret: SECRET
        hardware: "Open vSwitch"
        interfaces:
            1:
                name: "RADIUS for host 1"
                dot1x: true
                dot1x_dyn_acl: true
                native_vlan: office
            2:
                name: "host2"
                description: "host2 network namespace"
                native_vlan: office
            3:
                name: "eap listening port"
                output_only: true
acls:
    block-ping:
        - rule:
            dl_type: 0x800      # IPv4
            ip_proto: 1         # ICMP
            actions:
                allow: False
        - rule:
            dl_type: 0x86dd     # IPv6
            ip_proto: 58        # ICMPv6
            actions:
                allow: False
  • wpa supplicant with this example configuration:
ctrl_interface=/tmp/wpa_supplicant
ctrl_interface_group=0
ap_scan=0

network={
 key_mgmt=IEEE8021X
 eap=MD5
 identity="admin"
 password="test123"
 eapol_flags=0
}

Then run faucet

systemctl start faucet

And run mininet with configured topology

sudo mn --custom mytopo.py --topo mytopo --controller=remote

Then try to run wpa_supplicant from the client and see if chewie is receiving EAP packet (logs can be found in /var/log/faucet/faucet.log). There should be info about received packet.

NOTE: To complete login RADIUS server is needed but for now I just want Chewie to receive a EAP packet.

If anyone can help me with this I would be very grateful!


Solution

  • So I figured it out. The interface which Chewie listen on shouldn't be in namespace. In mininet configuration I had to add "inNamespace=False" to get the interface out of the namespace. Now when I listen on it everything works fine :)