Introduction
In this article we’re going to look at building a OpenFlow [1] based Software-Defined Network (SDN) for testing. This network is going to be built using software called Mininet [2] and the Floodlight [3] SDN controller.
What We Need
Mininet
Mininet is a tool used to create a virtual SDN on a single machine. It uses Linux network namespaces to create network hosts, and OpenVSwitch (OVS) [4] as virtual switches. Ubuntu and Debian users shouldn’t have a problem getting Mininet using the following command:
apt-get install mininet
If Mininet isn’t available through your packet manager of choice, you can take a look at alternative installation methods here.
A Network Controller
The Floodlight SDN controller is a decent controller to get started with. It’s not regarded as the most modern controller, but it’s very easy to set up, use, develop for, and as a bonus the code is easy to follow.
Floodlight is written is Java, with versions from 1.2 onwards using Java 8. Ubuntu and Mint users can refer to this link for Java 8 installation instructions, Debian users go here.
The tools used to build Floodlight can be gotten using the following command:
apt-get install git build-essential ant maven python-dev
Next, download the Floodlight source from github:
git clone git://github.com/floodlight/floodlight.git
…and finally, install the submodules and build Floodlight. This may take a few minutes.
cd floodlight git submodule init git submodule update ant
Running the Testbed
Running Floodlight
Once Floodlight is built, the following command will run it. This command should be executed from the ‘floodlight’ directory.
java -jar target/floodlight.jar
Adding a ‘ &’ to the end of the above command will run floodlight in the background. When TCP port 6653 opens up Floodlight will be ready to accept OpenFlow connections.
Launching Mininet
The following command will create a small network of 4 hosts and 1 switch, and connect the switch to the Floodlight controller using OpenFlow version 1.3:
sudo mn --controller=remote,ip=127.0.0.1,port=6653 --switch ovsk,protocols=OpenFlow13 --topo single,3
It should only take a few seconds for the network to be created, and once it has, the Mininet CLI will be open.
mininet@ubuntu:~$ sudo mn --controller=remote,ip=127.0.0.1,port=6653 --switch ovsk,protocols=OpenFlow13 --topo single,3 *** Creating network *** Adding controller *** Adding hosts: h1 h2 h3 *** Adding switches: s1 *** Adding links: (h1, s1) (h2, s1) (h3, s1) *** Configuring hosts h1 h2 h3 *** Starting controller *** Starting 1 switches s1 *** Starting CLI: mininet>
If Floodlight was deployed on a different machine, just change ‘127.0.0.1’ to the IP address of the relevant host.
Using the Testbed
Interacting with Mininet Hosts
The Mininet CLI is straight forward to use. The names of the network nodes can be retrieved using the ‘nodes’ command. Connectivity in the network can be verified using the ‘pingall’ command. Just issue the command on the Mininet CLI and Mininet will have each network host ping every other host.
mininet> nodes available nodes are: c0 h1 h2 h3 s1 mininet> mininet> pingall *** Ping: testing ping reachability h1 -> h2 h3 h2 -> h1 h3 h3 -> h1 h2 *** Results: 0% dropped (6/6 received) mininet>
Commands can be executed on individual nodes using the following sequence ‘<node name> <command>’, for example ‘h1 ifconfig’ would execute the ‘ifconfig’ command on node ‘h1’. Moreover, hosts can be instructed to ping each other using this command method. Issuing the command ‘h1 ping h2’ on the Mininet CLI will cause ‘h1’ to ping ‘h2’.
mininet> h1 ping h2 PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data. 64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=32.7 ms 64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=0.516 ms 64 bytes from 10.0.0.2: icmp_seq=3 ttl=64 time=0.044 ms 64 bytes from 10.0.0.2: icmp_seq=4 ttl=64 time=0.039 ms 64 bytes from 10.0.0.2: icmp_seq=5 ttl=64 time=0.041 ms ^C --- 10.0.0.2 ping statistics --- 5 packets transmitted, 5 received, 0% packet loss, time 3999ms rtt min/avg/max/mdev = 0.039/6.672/32.722/13.026 ms mininet>
The ‘xterm’ command can be used to open individual terminals for hosts. This can be useful for when you’d like to run a program from one host and view results or impact from another hosts. For example, pinging from h1 and watching tcpdump on h2.
The ‘help’ command will bring up a full listing of available commands. To shutdown Mininet, issue the ‘exit’ command. When the Mininet CLI has closed, run ‘sudo mn -c’ to clean up anything leftover by the process.
Interacting with Switches
The switches used in the Mininet network are OpenVSwitch switches and rely on the ovs-ofctl [5] tool for interaction. Using ovs-ofctl doesn’t work great from the Mininet CLI, so open a separate terminal window using the ‘xterm s1’ command to interact with switch s1.
In s1’s terminal window, issuing the command ‘ovs-ofctl dump-flows s1’ will print the flows currently installed in the switch. Initially, there shouldn’t be any flows on the switch.
root@ubuntu:~# ovs-ofctl dump-flows s1 NXST_FLOW reply (xid=0x4): root@ubuntu:~#
To cause some flows to be installed, jump back to the Mininet CLI and ping from h1 to h2 using the following command: ‘h1 ping h2’. Going back to the terminal for s1 and dumping the flows should now show that flows are installed in the switch; one to allow IP traffic to go from h1 to h2 and the other to allow IP traffic to move from h2 to h1. There may also be another two flows which allow ARP traffic to be traverse the link between the two endpoints.
root@ubuntu:~# ovs-ofctl dump-flows s1 NXST_FLOW reply (xid=0x4): cookie=0x20000001000000, duration=5.17s, table=0, n_packets=5, n_bytes=490, idle_timeout=5, idle_age=0, priority=1,ip,in_port=1,dl_src=96:a2:61:21:d8:fd,dl_dst=c6:e2:aa:d8:56:87,nw_src=10.0.0.1,nw_dst=10.0.0.2 actions=output:2 cookie=0x20000002000000, duration=5.168s, table=0, n_packets=5, n_bytes=490, idle_timeout=5, idle_age=0, priority=1,ip,in_port=2,dl_src=c6:e2:aa:d8:56:87,dl_dst=96:a2:61:21:d8:fd,nw_src=10.0.0.2,nw_dst=10.0.0.1 actions=output:1 cookie=0x20000000000000, duration=5.232s, table=0, n_packets=1, n_bytes=42, idle_timeout=5, idle_age=0, priority=1,arp,in_port=2,dl_src=c6:e2:aa:d8:56:87,dl_dst=96:a2:61:21:d8:fd actions=output:1 cookie=0x20000003000000, duration=0.153s, table=0, n_packets=0, n_bytes=0, idle_timeout=5, idle_age=0, priority=1,arp,in_port=1,dl_src=96:a2:61:21:d8:fd,dl_dst=c6:e2:aa:d8:56:87 actions=output:2 root@ubuntu:~
Interacting with Floodlight
In general, controllers allow access via a REST interface at the ‘northbound’ interface of the controller. Many controllers also supply a Web UI. Floodlight has both. Firstly, the REST interface on Floodlight expects data to be sent in JSON format and returns data as JSON. Browser based tool like Postman can be used to send and retrieve data from the controller. Alternatively, tools like cURL can be used from the terminal. The REST API is designed to allow external applications access to perform actions upon the network or retrieve information (e.g. statistics) from the network. Everything from installing flows to enabling/disable the firewall can be done. The Floodlight documentation provides full details on the REST API [6].
The following API call will return the switches currently connected to the controller:
curl http://127.0.0.1:8080/wm/core/controller/switches/json
mininet@ubuntu:~$ curl http://127.0.0.1:8080/wm/core/controller/switches/json [{"inetAddress":"/127.0.0.1:45329","connectedSince":1494256438933,"openFlowVersion":"OF_10","switchDPID":"00:00:00:00:00:00:00:01"}]
An Access Control List (ACL) rule can be added using the following command:
curl -X POST -d '{"src-ip":"10.0.0.1/32","dst-ip":"10.0.0.2/32","action":"deny"}' http://127.0.0.1:8080/wm/acl/rules/json
After the above command is issued the the ACL rule is added, dumping the flows on s1 in the Mininet network will show that a new flow has been added which will drop all traffic going from 10.0.0.1 (h1) to 10.0.0.2 (h2).
The Floodlight web UI can be accessed at http://127.0.0.1:8080/ui/index.html. At the time of writing this there’s no authentication needed to access it.
Final Words
A testbed doesn’t only offer the opportunity to test things, it also provides a platform to help better understand a technology. Using Mininet, a good understanding of SDN can be achieved by monitoring OpenFlow traffic between the network switches and the controller. A controller can be better understood by watching how it handles network events and traffic. Furthermore, considering the main focus of the site is SDN security, this testbed can act as a platform for investigating SDN attacks and defences. Both attacks and defences can be better understood the same way the network and controller can, by monitoring traffic, dumping flows, and watching cause and effect.
References
[1] https://www.opennetworking.org/sdn-resources/openflow
[2] https://www.mininet.org
[3] http://www.projectfloodlight.org/floodlight/
[4] http://openvswitch.org/
[5] http://openvswitch.org/support/dist-docs/ovs-ofctl.8.txt
[6] https://floodlight.atlassian.net/wiki/display/floodlightcontroller/Floodlight+REST+API