Hello there! Today we’re going to see how to implement a Layer-2 SDN Firewall using the POX Controller and Mininet. We are also going to reuse the same Tree topology we created last time (albeit with some minor changes). In case you are new to Mininet, you are highly recommended to first go through the previous blog post on using Mininet, here
Here is what you’re going to learn today -
- How to use the Python based POX OpenFlow controller instead of the default Mininet Controller
- Understand what an SDN based Firewall does and implement it from scratch using POX
- Mininet: While you can use the Mininet VM like last time, I recommend installing the package if you’re on Linux. For Ubuntu, just run:
sudo apt-get install mininetin terminal and you’re good to go.
- POX: For the POX controller you just need to clone the git repository. I’m assuming you have git installed and know how to work it. If this is not the case, this is a good resource. To clone the repository type the following in terminal and hit enter:
git clone https://github.com/noxrepo/pox
A Firewall can be understood to be something that obstructs traffic coming its way and filters it according to some rules. A general Firewall can be employed to protect a network from the internet. For an SDN based Firewall, we are going to use the OpenFlow controller to filter traffic between hosts according to some rules and accordingly let it pass through or not. The way we will do this is by using the POX controller to establish our required policies or rules (we will come to these later) and filter traffic between hosts using the switches. An example of such an SDN Firewall with two hosts is shown in the figure below:
Topology set up in Mininet
The topology we are going to implement is going to be the same as last time. To recall, here is the diagram of the topology below -
Now, we can basically use the same file as last time,
tree.py but with some modifications. These will basically be minor changes like referencing a remote controller instead of the default Mininet controller and specifying simple MAC addresses for our hosts so that we may reference them easily when we create rules for the Layer-2 Firewall. To recall, the code we were working with last time in
tree.py was as follows:
The changes we are going to make are just going to be two -
- Changing the controller to a remote one so we may use POX. We need to first import
RemoteControllerinstead of the regular
Controllerin our module import statements and then we can pass that through to the Mininet class. These changes are basically -
- Adding MAC addresses while initializing the hosts so that we can easily define the Layer-2 rules for our Firewall. Thus, we initialize the hosts this way -
tree.py file now looks like this:
Firewall Rules and POX Implementation
Firstly, we need to decide on the rules we will enforce through our firewall. It should also be noted that it will be a bi-directional block, and if a rule exists, the controller will ensure that switches neither let incoming or outgoing traffic from either host reach the other. So for our Firewall, we can have the following 4 rules:
- h1 and h2 are mutually blocked
- h2 and h4 are mutually blocked
- h2 and h7 are mutually blocked
- h3 and h8 are mutually blocked
Moving on to POX– I’m going to assume that you cloned the git repo and put it in the home directory to simplify things. Change the commands to reflect where your files are to avoid any problems.
Here is how we will proceed:
cdinto the pox directory and then type
cd pox/misc/. This is where we will place our firewall code
- Create a new file called firewall.py in which we write our code:
- First, we import all the classes we will require -
- Then we specify our rules for the Firewall by writing down the Layer-2 addresses of the hosts. We then put each of these as rows in a list so that we may iterate over each rule separately later:
- Next we create our SDNFirewall class in which the actual controller is going to be accessing and checking flows and modifying flow tables accordingly. The first function
__init__is just a constructor. The second and more interesting function,
_handle_ConnectionUpwill fire up each time a host tries to reach another through the switches. When this happens, we will first iterate over each rule in our list of rules. Here we create match fields by providing the two hosts in the rule, specified by
block. We then create an OpenFlow flow_mod message using
of.ofp_flow_mod()and set its match field to our blocking rule. At the end, we use
event.connection.send(flow_mod)to send our blocking rule to the switch so that it can be enforced. Lastly, we create the
launchfunction that POX requires and pass our
SDNFirewallclass to it. The code for this is as follows:
This completes our developing the controller to fulfill our needs. The script in its entirety is shown below. Moreover, in the next section we will run our code and see if the Firewall implementation actually did what it was supposed to.
This just requires us to start our Mininet topology emulation and the POX controller with the Firewall implemented.
- To start the Mininet emulation is simple. Just run
sudo python tree.py(Don’t forget– Mininet needs to run as root) in the terminal and you should see the hosts and switches initialized and the Mininet CLI started:
- To run the controller, first
cdinto the pox directory. Now type in the command given below. It is good to observe that the way POX takes in arguments is in the form of folders and files separated by ‘.’:
./pox.py log.level --DEBUG openflow.of_01 forwarding.l2_learning misc.firewall
As long as you don’t see any error messages, there should be no problem.
Now, we go back to the Mininet CLI and type in
pingall to see if our Firewall actually works. The
pingall command will just go ahead and ping each node from every other node. Here are the results:
Yes, according to our Firewall rules, h1 and h2 were never able to connect, neither were h2 and h4, h3 and h8, h2 and h7 able to connect respectively too! We see that there is a packet loss of 14%, which is absolutely correct. Thus, we were successful in our endeavour of implementing an SDN Firewall!
In this post, we saw how to implement a Layer-2 Firewall using the POX Controller. Using rules specifying Layer-2 characteristics we were able to control the switches using POX to either permit traffic between hosts or restrict it. The next time, I will be discussing the P4 programming language and how it seeks to revolutionize networks completely. Stay tuned and keep being awesome!