Tuesday, February 14, 2017

Running NZNOG 2017 on FAUCET


In this video, Brad Cowie describes how the NZNOG 2017 conference was run on FAUCET (see slides, using Ansible to manage and push configuration).

We used hardware switches (AT x930s) together with OVS + DPDK, and we provided IPv4, IPv6, both wired and WiFi and connected to the ISP using BGP. The talk itself was streamed live and recorded over FAUCET.

We plan to make this network a permanent installation at WAND and continue to add features.

Monday, February 6, 2017

FAUCET, VLANs, tagged and untagged

VLANs (virtual LANs) are extensively supported in non-SDN networks (Cisco have a helpful reference) and are used, in general, to provide the illusion of separate networks that are sharing the same physical infrastructure. Cisco helpfully explain in detail why this is useful, but in summary, it allows you to easily and selectively control connectivity between devices on a network (eg you can say, hosts 1 and 2 can see each other, and hosts 3 and 4 can see each other, but hosts 1 and 2 cannot talk to hosts 3 and 4). It also allows you to carry traffic from multiple VLANs on the same physical cable, a concept called "trunking".

In configuring conventional VLANs, you configure a given switch port to be one of two modes - an access port (generally connected to a host), and a trunk port (generally connected to another switch). Hosts connected to access ports generally expect packets without VLAN headers (ie. untagged). Switches (or special hosts) connected to trunk ports, generally expect packets with VLAN headers (tagged), so that they know which VLAN packets belong to.

This tagging of traffic is what enables traffic from several different VLANs to coexist on the same physical cable - "trunking". Trunking allows you then, to connect a special host - an NFV host - to a "trunk" port, which the NFV host can then use to provide services (like DNS and firewalling) to other hosts on the network.

FAUCET supports "trunking." It does it in a different (and less complex) way than a conventional switch - you configure the VLANs in the FAUCET config file, and NOT on the switches. You don't specify a port as a "trunk". Instead, you say which VLANs the port participates in and which ones to tag (you can even receive untagged traffic for one VLAN as well as tagged traffic for other VLANs on a port, should you want to).

Here's an example. In this network there are three hosts, connected to ports 1, 2, 3, and an NFV host on port 9. We want each host to be able to talk to the NFV host, but we don't want the hosts to be able to talk to each other. We are putting host 1 in VLAN 100, host 2 in VLAN 200, and host 3 in VLAN 300, and we are allowing the NFV host to access all the VLANs.

+---------+   +---------+   +---------+    +---------+
|         |   |         |   |         |    |         |
| Host 1  |   | Host 2  |   | Host 3  |    | NFV Host|
|         |   |         |   |         |    |         |
|   +-+   |   |   +-+   |   |   +-+   |    |   +-+   |
|   | |   |   |   | |   |   |   | |   |    |   | |   |
|   +-+   |   |   +-+   |   |   +-+   |    |   +-+   |
+---------+   +---------+   +---------+    +---------+
     |             |             |              |
     |             |             |              |
     |             |             |              |
|   +-+           +-+           +-+            +-+   |
|   |1|           |2|           |3|            |9|   |
|   +-+           +-+           +-+            +-+   |
|                                                    |
| native        native         native       tagged   |
| VLAN 100      VLAN 200       VLAN 300     VLANs    |
|                                           100      |
|                                           200      |
|                                           300      |
| FAUCET controlled OF switch                        |
|                                                    |


You configure this in FAUCET's configuration file:

                native_vlan: 100
                name: "port1.0.1"
                description: "host 1"
                native_vlan: 200
                name: "port1.0.2"
                description: "host 2"
                native_vlan: 300
                name: "port1.0.3"
                description: "host 3"
                tagged_vlans: [100,200,300]
                name: "port1.0.9"
                description: "nfv host"

On the NFV host, you need to configure the port to expect the tagged traffic and split it out to the right virtual interface. Let's say you connected the switch port 9, to eth0 on the NFV host. In Ubuntu, /etc/network/interfaces would have a section like this (you may also have to install the "vlan" package):

auto eth0
iface eth0 inet manual
  pre-up /sbin/ethtool -K $IFACE tso off gso off
  up ip link set $IFACE up
  down ip link set $IFACE down

auto eth0.100
iface eth0.100 inet manual
  up ip link set $IFACE up
  down ip link set $IFACE down

auto eth0.200
iface eth0.200 inet manual
  up ip link set $IFACE up
  down ip link set $IFACE down

auto eth0.300
iface eth0.300 inet manual
  up ip link set $IFACE up
  down ip link set $IFACE down

You could also of course assign IP addresses, etc to eth0.300, etc. You could even bridge those interfaces in turn to other bridges (using Linux bridges or OVS). Linux will untag the traffic for you (so for example, traffic from host 1, will appear on eth0.100, with no tag).

You can of course have multiple hosts in the same VLAN. For example, you could put hosts 1 and 2 both in VLAN 100, in which case they could see each other and the NFV host.

NB. Some FAUCET controlled switches need to be configured to expect a VLAN tag, even though the VLAN isn't configured on the switch (eg Allied Telesis switches require you to add VLAN numbers to the switch's VLAN database - see the quickstart article).

Thursday, January 5, 2017

enforcing DNSSEC client validation with FAUCET

DNSSEC is considered very important, because it provides a way for a DNS client to validate results.

However, not all DNS servers, will perform this validation on behalf of their clients (or the clients may be configured to use the wrong resolvers).

Using FAUCET with some NFV, though, you can force clients to use a validating DNS server.

First, you'll need to provide an NFV'd DNS server that performs validation. There is a guide for BIND - it boils down to a couple of extra configuration settings.

Then, you'll need to configure FAUCET to intercept DNS requests, and output them to the NFV port where the DNS server is. Here is a FAUCET config snippet that does that:

In this example, we force DNS requests, UDP and TCP, to go out port 1, VLAN 2001, which is where the NFV'd DNS server is running.

    # Force DNS
        - rule:
            dl_type: 0x800
            nw_proto: 17
            tp_dst: 53
                    vlan_vid: 2001
                    port: 1
        - rule:
            dl_type: 0x800
            nw_proto: 6
            tp_dst: 53
                    vlan_vid: 2001
                    port: 1
        - rule:

                allow: 1

                tagged_vlans: [2001,2002,2003]
                name: "port1.0.1"
                description: "windscale"
                native_vlan: 2001
                name: "port1.0.2"
                description: "vek-x"
                acl_in: 2001

Next, we configure the NFV host to intercept those DNS requests. This can be done with iptables - for example (the NFV host's IP, is

-A PREROUTING -i br1 -p tcp --dport 53 -j DNAT --to-destination
-A PREROUTING -i br1 -p udp --dport 53 -j DNAT --to-destination

Any client on port 2 is now compelled to use that DNS server (and only that DNS server). For example, they can visit a test site which will verify that DNSSEC is being used.

You might imagine using the same technique to force proxy other protocols, such HTTP, etc.

V1.3 released

To: faucet-dev, faucet-users

Hi all;

We have just pushed another stable release, V1.3, including new pip packages (https://pypi.python.org/pypi/ryu-faucet).

This release most notably makes a change to the pipeline (ACL table now comes first), and removes support for the old V1 config file format - only version V2 is supported.

There are a number of other changes to improve test reliability and some IP routing fixes.


Wednesday, January 4, 2017

LINK022 - OF controlled WiFi

In this post, I'll describe LINK022 - an experimental WiFi AP, powered by PoE, and controlled by OpenFlow (and FAUCET in particular). LINK022 can be used for practical use cases like eduroam, which is a global roaming WiFi service for research and education - which I'll describe as a working example.

Because OpenFlow is used to control WiFi traffic, you can dynamically filter, mirror, etc traffic as soon as it enters the network (rather than by the time it reaches a firewall), perhaps based on user ID - an external process can update and signal FAUCET to apply the appropriate policy.

At the moment, non-OpenFlow configuration is manually specified (eg, SSID). In the future, OpenConfig will be used.

LINK022 is based on Raspberry Pi 3. While the 3 does have onboard WiFi, it's suggested you use a separate WiFi adaptor (eg, you might want one with better/multiple antennas).

LINK022 requires a host switch that can provide PoE, and also runs OpenFlow (so both can be controlled by FAUCET).

The key software components of LINK022 are:
  • hostapd (manages the WiFi radio, and implements 802.1x authentication via RADIUS)
  • OVS (switches packets from WiFi, and implements security controls, like FAUCET ACLs)
  • FAUCET (controls OVS, and the host wired switch - runs on a separate host)
In the following diagram, LINK022 is on the left; the host switch is on the right, and the controller/NFV host (where FAUCET runs) is top right. 

FAUCET is used to implement VLAN 100 between AP and host switch, for  OpenFlow, RADIUS, and management traffic.

FAUCET also implements VLAN 2002, which WiFi clients are bridged onto, and the NFV host provides DHCP, DNS, etc, via the host wired switch.

To implement the eduroam use case, you will need to do the following (including obtain RADIUS credentials; if you don't have eduroam, you could use your own RADIUS server):

  • Set up a host OpenFlow wired switch with controller/NFV host, as above, running FAUCET.
  • Set up FAUCET config for the port, where you will connect LINK022.

                tagged_vlans: [100,2002]
                name: "port1.0.9"
                description: "link022 WiFi AP"
  • Set up FAUCET config to control LINK022 (OVS controls only the user traffic):

        dp_id: 0xb827eb608918
        hardware: "Open vSwitch"
                tagged_vlans: [2002]
                native_vlan: 2002
  • On LINK022, set up wired interface to use VLAN 100 by default, and set up a Linux bridge with veth pair (for OVS to connect to the WiFi radio). This is accomplished by using the following for /etc/network/interfaces:
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static 

auto eth0.100
iface eth0.100 inet dhcp
        vlan-raw-device eth0

auto wlan0
iface wlan0 inet static

auto wlanbr0
iface wlanbr0 inet static
        pre-up ip link add veth1 type veth peer name veth2
        up ifconfig veth1 up
        up ifconfig veth2 up
        bridge_ports veth1
  • Install OVS on the Pi (I used 2.6.1). The Pi isn't very powerful, so it will take a while to compile.
  • Configure OVS to be controlled by FAUCET, and add eth0 and veth2 to br0. Your br0 should look like this:
root@link022:/home/pi# ovs-vsctl show

    Bridge "br0"
        Controller "tcp:<FAUCET IP>:6636"
            is_connected: true
        Port "veth2"
            Interface "veth2"
        Port "br0"
            Interface "br0"
                type: internal
        Port "eth0"
            Interface "eth0"
    ovs_version: "2.6.1"

  • Install hostapd, with the following config as /etc/hostapd/hostapd.conf


auth_server_addr=<RADIUS SERVER IP>

That's it! From now on, if you have eduroam credentials, you will be able to authenticate and browse the network.

Some further reading:

Thursday, December 15, 2016

NFV'ing LLDP (making IP phones work)

Many IP phones use LLDP to figure out what VLAN to use, for DHCP (having a built in switch - the phone accepts both tagged and untagged traffic - the untagged traffic is switched through to a connected device like a PC, and the tagged traffic the phone keeps to itself).

The phone generally waits for an LLDP server to send it an LLDP frame to cue it with the right VLAN to use. FAUCET doesn't do LLDP itself, but, it does of course support doing via NFV. Simply run lldpd on your NFV host, and configure the NFV interface to be in the same untagged (native) VLAN as the port with the phone (the phone's interface will have both tagged and native configuration).

You will also have to specify "drop_lldp: False" in the datapath section of FAUCET's config, to tell FAUCET not to drop LLDP by default.

lldpd should have configuration like (to quote the man page - http://manpages.ubuntu.com/manpages/trusty/man8/lldpcli.8.html):

configure med policy application voice vlan 500 priority voice dscp 46

For an extra level of rigor, you could configure a FAUCET ACL that ensures LLDP from client ports is unconditionally forwarded to the NFV host (so that no other connected device could potentially spoof LLDP).