Open vSwitch with SSL and Mininet

By default, Mininet uses the unencrypted port in Open vSwitch for OpenFlow. This makes total sense since the purpose of Mininet is a research tool, so encryption isn’t usually needed and using unencrypted control traffic allows for the use of tools like Wireshark to see the OpenFlow packets. But there are times when you might want to try and use OpenFlow over SSL. So I did a little research and as usual, doing my brain dump here to keep a record for myself.

To try it out, Mininet comes with the OpenFlow reference controller and the ovs-controller. I looked at the OpenFlow reference, but it doesn’t seem to support SSL.

mininet@mininet:~$ controller --help
controller: OpenFlow controller
usage: controller [OPTIONS] METHOD
where METHOD is any OpenFlow connection method.

Active OpenFlow connection methods:
  nl:DP_IDX               local datapath DP_IDX
  tcp:HOST[:PORT]         PORT (default: 6633) on remote TCP HOST
  unix:FILE               Unix domain socket named FILE
  fd:N                    File descriptor N
Passive OpenFlow connection methods:
  ptcp:[PORT]             listen to TCP PORT (default: 6633)
  punix:FILE              listen on Unix domain socket FILE

But it seems that the ovs-controller supports SSL.

mininet@mininet:~$ ovs-controller --help
ovs-controller: OpenFlow controller
usage: ovs-controller [OPTIONS] METHOD
where METHOD is any OpenFlow connection method.

Active OpenFlow connection methods:
  tcp:IP[:PORT]           PORT (default: 6633) at remote IP
  ssl:IP[:PORT]           SSL PORT (default: 6633) at remote IP
  unix:FILE               Unix domain socket named FILE
Passive OpenFlow connection methods:
  ptcp:[PORT][:IP]        listen to TCP PORT (default: 6633) on IP
  pssl:[PORT][:IP]        listen for SSL on PORT (default: 6633) on IP
  punix:FILE              listen on Unix domain socket FILE
PKI configuration (required to use SSL):
  -p, --private-key=FILE  file with private key
  -c, --certificate=FILE  file with certificate for private key
  -C, --ca-cert=FILE      file with peer CA certificate

So for this little experiment, I just used ovs-controller. Other controllers like RYU can also be used as mentioned in this post that helped me work out some issues. So lets get started.

Create all the keys for both OVS and the ovs-controller we will use and set the SSL parameters for OVS.

cd /etc/openvswitch
sudo ovs-pki req+sign ctl controller
sudo ovs-pki req+sign sc switch
sudo ovs-vsctl set-ssl \
    /etc/openvswitch/sc-privkey.pem \
    /etc/openvswitch/sc-cert.pem \
    /var/lib/openvswitch/pki/controllerca/cacert.pem

The above might not be the most secure way to manage the keys, but again, this is for research and experimentation.

In one window, let’s start the ovs-controller with SSL support.

sudo ovs-controller -v pssl:6633 \
     -p /etc/openvswitch/ctl-privkey.pem \
     -c /etc/openvswitch/ctl-cert.pem \
     -C /var/lib/openvswitch/pki/switchca/cacert.pem

Next, below is the Mininet Python script I used. Run this Mininet script that creates a simple single switch tology and sets the controller to SSL.

#!/usr/bin/python
from mininet.net import Mininet
from mininet.node import Controller, RemoteController
from mininet.cli import CLI
from mininet.log import setLogLevel, info

def emptyNet():
    net = Mininet( controller=RemoteController )
    net.addController( 'c0' )
    h1 = net.addHost( 'h1' )
    h2 = net.addHost( 'h2' )
    s1 = net.addSwitch( 's1' )
    net.addLink( h1, s1 )
    net.addLink( h2, s1 )
    
    net.start()
    s1.cmd('ovs-vsctl set-controller s1 ssl:127.0.0.1:6633')
    
    net.pingAll()
    CLI( net )
    net.stop()
    
if __name__ == '__main__':
    setLogLevel( 'info' )
    emptyNet()

When you run the script, you will see that a PingAll test ran and passed. You can also check and see that switch is connected using SSL.

mininet@mininet:~$ sudo ovs-vsctl show
902d6aa3-6a0a-4708-a286-3301c8b36430
    Bridge "s1"
        Controller "ssl:127.0.0.1:6633"
            is_connected: true
        fail_mode: secure
        Port "s1"
            Interface "s1"
                type: internal
        Port "s1-eth1"
            Interface "s1-eth1"
        Port "s1-eth2"
            Interface "s1-eth2"
    ovs_version: "2.0.1"

This post ‘Open vSwitch with SSL and Mininet’ first appeared on https://gregorygee.wordpress.com/.

Running Open vSwitch in Network Namespace with In-Band Controller

In a previous post, I started the experiment on running Open vSwitch in a network namespace.  I had three scenarios I was trying to accomplish.

  1. OVS in each network namespace running in standalone mode (standard L2 learning switch not under SDN control).
  2. OVS in each network namespace running in secure mode with a local SDN controller for each switch
  3. OVS in each network namespace running in secure mode with a remote in-band SDN controller

In the last post I walked through the first two scenarios but I mentioned I was stuck getting the in-band controller scenario to work. Turns out that the problem I was having was just a simple IP MASK misconfiguration. I had kept thinking of the internal bridge interface (s1 and s2) as being like layer 3 Loopback interface on a router and putting a /32 prefix on them. I realized recently that these are actually an SVI/VLAN interface. Not sure why I got those mixed up. So once I used the correct IP prefix to match the subnet of the network, all worked as planned. So the following are the steps I took to get the last scenario to work.

This script(createBrSdn) creates the bridge in secure mode and adds the ports. Set the controller IP address to the host that will run the controller. In my case, the controller will be running on host h1 which has an IP address of 10.0.0.1/8.

#!/bin/bash

echo Configure OVS for $1
ovs-vsctl --db=unix:/tmp/mininet-$1/db.sock add-br $1
ovs-vsctl --db=unix:/tmp/mininet-$1/db.sock add-port $1 $1-eth0
ovs-vsctl --db=unix:/tmp/mininet-$1/db.sock add-port $1 $1-eth1
ovs-vsctl --db=unix:/tmp/mininet-$1/db.sock set-fail-mode $1 secure
ovs-vsctl --db=unix:/tmp/mininet-$1/db.sock set-controller $1 tcp:10.0.0.1:6633
ovs-vsctl --db=unix:/tmp/mininet-$1/db.sock show

With the script setup, I followed the same instruction I had before but also set the IP address for each of the internal bridge interfaces. So first step was to start the Mininet script and then open XTerms to h1, s1, and s2.

In the xterm for h1 controller:

controller -v ptcp:6633

In the xterm for S1:

startOvsDb s1
startOvs s1
createBrSdn s1
ifconfig s1 inet 10.0.0.100/8

In the xterm for S2:

startOvsDb s2
startOvs s2
createBrSdn s2
ifconfig s2 inet 10.0.0.101/8

Once that was all setup, I could easily get the two hosts to ping each other.

mininet> h1 ping -c 2 h2
PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
64 bytes from 10.0.0.2: icmp_req=1 ttl=64 time=2.52 ms
64 bytes from 10.0.0.2: icmp_req=2 ttl=64 time=1.50 ms

--- 10.0.0.2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 1.502/2.015/2.529/0.515 ms

I’m glad all this finally worked out. I think I might now try and wrap all this into a Mininet custom switch class so people can try their own experiments at using in-band conntroller.

This post ‘Running Open vSwitch in Network Namespace with In-Band Controller’ first appeared on https://gregorygee.wordpress.com/.