Injecting services into the dataplane with coprocessing

With the coprocessor feature, FAUCET allows an external NFV host to receive packets from the dataplane, inject arbitrary packets, or both. In particular, coprocessing allows you to inject services into the dataplane, or even override services on hosts already present.

In this example, we have a real host 192.168.2.1 (a router) which has an ssh service. We have a host on the network, 192.168.2.5. 192.168.2.5 may do anything it likes, but if it should try to connect to ssh on 192.168.2.1, we want to redirect that connection to a fake service running on the coprocessor server.

First we will need to tell FAUCET to intercept the service using an ACL, which will be applied to the test host’s port. Port 18 is the coprocessor port, and port 13 is the test host.

acls:
  coprocessssh:
    - rule:
        dl_type: 0x806
        actions:
          allow: 1
          output:
            ports: [18]
    - rule:
        dl_type: 0x800
        ip_proto: 6
        tcp_dst: 22
        actions:
          output:
            ports: [18]
    - rule:
        actions:
          allow: 1
vlans:
  trusted:
    vid: 2
dps:
  dp:
    interfaces:
      13:
        native_vlan: trusted
        acls_in: [coprocessssh]
      18:
        coprocessor: {strategy: vlan_vid}

FAUCET will now redirect port 22 to the coprocessor port. We will now need to set up an OVS switch on the coprocessor so we can start fake services, and allow ARP to work in parallel with the real host. The fake host will need to use the same MAC address as the real one, which won’t cause a conflict because FAUCET is intercepting just the TCP service and FAUCET knows not to re-learn the real host on the coprocessor port.

Note the OVS actions for setting VID to 4098 – that’s the VID for the trusted VLAN (2) or’d with the VID present bit (4096). That will cause packets from the coprocessor to have the right VID to be switched back into the trusted VLAN.

root@coprocessor:/home/pi# cat setupcopro.sh 
#!/bin/sh

NFVINT=enx0023565c8859
FAKEHW=aa:56:63:87:9e:e9
FAKEIP=192.168.2.1/24
NS=copro

ip netns add $NS
ifconfig $NFVINT up
ip link add dev fake0 type veth peer name fakeovs0
ifconfig fakeovs0 up
ip link set fake0 netns $NS
ip netns exec $NS ifconfig fake0 hw ether $FAKEHW $FAKEIP up
for i in $NFVINT fakeovs0 ovs-system ; do
  echo 1 > /proc/sys/net/ipv6/conf/$i/disable_ipv6
done
ifconfig ovs-system 0.0.0.0

ovs-vsctl del-br br0
ovs-vsctl add-br br0
ovs-ofctl del-flows br0

for i in $NFVINT fakeovs0 ; do
  ovs-vsctl add-port br0 $i
done

ovs-ofctl add-flow -OOpenFlow13 br0 "in_port=1,actions=output:2"
ovs-ofctl add-flow -OOpenFlow13 br0 "in_port=2,vlan_tci=0x0000/0x1fff,ip,tcp,actions=push_vlan:0x8100,set_field:4098->vlan_vid,output:1"
ovs-ofctl add-flow -OOpenFlow13 br0 "in_port=2,vlan_tci=0x0000/0x1fff,arp,actions=push_vlan:0x8100,set_field:4098->vlan_vid,output:1"

Now we will start a fake service on the coprocessor and connect to it from the test host.

root@coprocessor:/home/pi# cat fakessh.sh 
#!/bin/sh

while /bin/true ; do echo completely awesome ssh service| ip netns exec copro nc -l 192.168.2.1 22 ; done
root@coprocessor:/home/pi# ./fakessh.sh
pi@pi8021x:~ $ telnet 192.168.2.1 22
Trying 192.168.2.1...
Connected to 192.168.2.1.
Escape character is '^]'.
completely awesome ssh service
^]
telnet> close
Connection closed.

That’s it. We could run other services on the fake host – for example to broadcast CDP to impersonate a router, for example, or redirect other services.

One reply on “Injecting services into the dataplane with coprocessing”

Comments are closed.