I have been working with OpenStack(devstack) for a while and I must say it is quite convenient to bring up a test setup using devstack. At times, I still feel it is an overkill to use devstack for a quick test to verify your understanding of the network/security rules/routing etc.
This is where Mininet shines. It is very lite on resources and extremely fast in getting your topology up and running. It cuts the setup to the absolute necessities and needless to say, it has proven invaluable to me while trying out various topologies and tests.
Lacking Security Device simulation
The default Mininet toolbox comes with a switch and hosts nodes. The switch is primarily a controller based SDN switch like OpenVSwitch or IVS. The primary focus of Mininet has been L2 networks with SDN controllers.
While for me the goal was to test routing and security much like what is available on OpenStack. I found an example topology in the Mininet code simulating a LinuxRouter. Basically, a Host node (Namespace) was configured to do l3 forwarding.
This give me the initial idea of implementing security devices with Mininet, after all the reference network services (routing and firewall) in OpenStack are based on Namespaces
A Simulated Perimeter Firewall
As IPTables are available within the namespace I decided to use them to implement a Perimeter Firewall that would inspect the traffic between the Networks. I used a separate table to have my firewall rules and redirected all traffic hitting the FORWARD table to my custom table PFW. The last rule in the FORWARD table was to drop all traffic.
So now when I started my topology with the perimeter Firewall the ping test confirmed that no traffic was flowing between the networks.
To allow traffic we need to specifically configure the Firewall to allow packets.
This took care of securing the Network boundary, but how about traffic flowing within the network. OpenStack supports this using micro segmentation with Security Groups.
Simulating Micro Segmentation with OpenStack like Security Groups
Well as I was using OpenVSwitch for my topology in standalone mode, I decided to configure the OVS packet filtering capabilities to implement a firewall within the Network itself. Here is some sample OVS rules to do L3 packet match and filter.
ovs-ofctl add-flow switch1 dl_type=0x0800,nw_src=22.214.171.124,nw_dst=126.96.36.199s, action=DROP
And produces the following setting (can be verified with ovs-ofctl dump-flows switch1)
cookie=0x0, duration=9.050s, table=0, n_packets=0, n_bytes=0, idle_age=9, ip,nw_src=188.8.131.52,nw_dst=184.108.40.206 actions=drop
Updated CLI to allow Firewall Rules
All this looks good but it’s a lot of work to manually configure all the rules. And I was thinking, how can this be automated?
I extended the switch node in Mininet to implement a Secure Switch and while at it I also implement the Perimeter Firewall as a specialized Host Node. My intention of implementing these special nodes was to add the capability of configuring the nodes with security settings. By this time, it was already looking like an interesting Weekend Project 🙂
So, got into it an implemented a set of CLI commands for Mininet to configure the firewall capabilities on the topology(using the security nodes that I introduced). I was calling it the Secure Network.
I wanted to keep things simple to start with and so kept the rule definitions very coarse, namely only L3 filtering only(I may look at L4 in future). So here is the CLI I came up with.
Securenet] secrule add allow [addr1] to [addr2] Securenet] secrule add deny [addr1] to [addr3]
Here addr1, addr2 and addr3 are Micro Segments(or Security Groups)
Now, to define Firewall rules with Micro Segments (let’s call it Security Groups as this is what is was trying to simulate at the first place) I needed a way to define the Security Groups and associate Hosts to it.
To keep things simple I went for an automatic creation of Security Groups and when a Host association command is entered. This was done by extending the host commands. Here is an example of creating a Security Group and associating a Host with it.
Securenet] h30 bind sg1
Above command creates a Security Group called SG1 and associates host h30 to it.
To add another Host to the same SG issue the same command with a different Host name
Securenet] h31 bind sg1
This adds h31 to sg1. To view the members of the security group use the sghosts command
Securenet] sghosts sg1 0: h30 1: h31
Reacting to Security Group changes with events
By this time, I was already too excited to stop and was thinking of the interactions between the Firewall rules and Security Group definitions.
As the high-level Firewall rules are composed of Security Groups, the firewall must react to the changes to Security Group definition. This means the change in Security Group definition must produce some kind of event that is observable by the Firewall and then it must update its configuration accordingly to keep the firewall rule constrains satisfied.
To do this I extended the Topology and Mininet class so that any change in the SG definition can trigger a re-evaluation of the Firewall rules.
Again to keep things reasonably simple I went with a rip and replace of Firewall configuration (both IPTables and OVS) and did not bother about the traffic impact (we are in simulation after all). But this might be an interesting area to explore in future.
One thing that I was missing while defining the Firewall rules was a way to target a set of external IP address. As the IP addresses associated to a Security Group definition was derived out of its member Hosts, so there was no way to define rules based on addresses that are not part of the topology.
So, another set of CLI commands were introduced to define groups based on IP addresses manually and without any topology based constrains.
Securenet] secrule ipg add ipg1 220.127.116.11 Securenet] secrule ipg add ipg2 18.104.22.168 Securenet] secrule ipg add ipg3 22.214.171.124
CLI to view a list of IPGs
Securenet] secrule ipg list 0: ipg2 1: ipg3 2: ipg1
And to view its content use the following
Securenet] secrule ipg show ipg1 0: ipgh-126.96.36.199/32
With IPGs it was possible to have rules with arbitrary addresses.
Here is a run of a simple set of commands on the secure net topology
The updated IPTables config in the Perimeter Firewall.
And the security rules in OVS
This was more of a fun long weekend project for me. Once I dived into the project I realized a number of challenges that are posed by such an undertaking like rule optimization, minimizing the config changes, targeting the right device to push a security rule, figuring out duplicate rules and conflicts etc. Also, as I thought through more use cases I realized that the firewall rule definition needs a language of its own.
But at the end of the weekend I feel mostly it was a lot of fun.