Computer Network 12 | SDN Firewall Project
1. Submission and Rubic
packetcapture.pcap(15)sdn-firewall.py(5)configure.pol(5)Pass SDN firewall unit tests (35 + 15 + 25)
2. Recall: Setup VM
Use
sshfor IDE connectionUse
gitfor code version control and sync to github
Reference: Link
Remeber to clean up mininet in case of any conflicts,
$ mn -c
3. Wireshark
Start a mininet prompt by topo file
ws-topology.py,
$ sudo python ws-topology.py
mininet>
Start two xterm windows for
us1andus2hosts
mininet> us1 xterm&
mininet> us2 xterm&
In us1 xterm window, change the command prompt by,
# export PS1="us1 >"
us1 >
Similarly, in us2 xterm window,
# export PS1="us2 >"
us2 >
Note that this step should only be executed with the non-root role. This means we can not use sudo su -.
In mininet prompt, use wireshark command
tsharkto generate packet information ofus1host.
mininet> us1 sudo tshark -w /tmp/packetcapture.pcap
Simulate network traffic with the following steps
us1:ping 10.0.1.2, then ctrl+C to kill the processus2:ping 10.0.1.1, then ctrl+C to kill the processus1:python test-server.py T 80us2:python test-client.py T 80us1: ctrl+C to kill the processus1:python test-server.py T 8000us2:python test-client.py T 8000us1: ctrl+C to kill the processmininet: ctrl+C to killtsharkprocessexit
mininet,us1,us2
Copy
packetcapture.pcapto project path
$ sudo chmod 755 /tmp/packetcapture.pcap
$ ls -lrt /tmp/packetcapture.pcap
-rwxrwxrwx 1 755 root 19564 Mar 19 01:57 /tmp/packetcapture.pcap
$ cp /tmp/packetcapture.pcap $PROJECT_PATH # replace with the path
(Optional) Use git and github for version control
Use
wiresharkto examine the packet information
$ sudo wireshark
Then File -> Open, choose the packetcapture.pcap we have generated.
4. Firewall Config File Review
In this project, the firewall configuration rules are stated in the configure.pol file. The file is like a csv file format with each line representing a firewall rule. There are 9 fields in a line of rule,
RuleNumber: has to be unique numbers and it is not validated in the program
Action:
BlockorAllow, cannot be-Source MAC: source host MAC addr
Destination MAC: destination host MAC addr
Source IP: source host IP addr
Destination IP: destination host IP addr. For source/dest IP, we have the following hosts/networks defined in
sdn-topology.pyHeadquarters Network: Subnet
10.0.0.0/24forhq1tohq5US Network: Subnet
10.0.1.0/24forus1tous5India Network: Subnet
10.0.20.0/24forin1toin5China Network: Subnet
10.0.30.0/24forcn1tocn5UK Network: Subnet
10.0.40.0/24foruk1touk5
Protocol: protocol number based on IANA
ICMP:
1TCP:
6UDP:
17
Source Port: source host application port. Only for TCP/UDP
Destination Port: destination host application port. Only for TCP/UDP
Comment/Note: extra notes not validated in the program
Let’s see two examples,
1,Block,-,-,10.0.0.1/32,10.0.1.0/24,6,-,80,Block 10.0.0.1 from accessing a web server on the 10.0.1.0/24 network
The first rule basically blocks host hq1 (IP Address 10.0.0.1/32) from accessing a web server on any host on the us network (the subnet 10.0.1.0/24 network). The web server is running on the TCP IP Protocol (6) and uses TCP Port 80.
2,Allow,-,-,10.0.0.1/32,10.0.1.125/32,6,-,80,Allow 10.0.0.1 to access a web server on 10.0.1.125 overriding previous rule
The second rule overrides the initial rule to allow hq1 (IP Address 10.0.0.1/32) to access a web server running on us5 (IP Address 10.0.1.125/32). The web server is running on the TCP IP Protocol (6) and uses TCP Port 80.
5. Basic POX API
Now, let’s see how we can implement the firewall with file sdn-firewall.py. The code is based on OpenFlow and POX (which is a software for OpenFlow control). As it is provided, we must implement code that does the following steps,
Create a OpenFlow Flow Modification object
of.ofp_flow_mod()Create a POX Packet Matching object for the rules
Set up OpenFlow rules with matching attributes
Set up access control with rule’s priority
Create a POX output action to specify what to do with the traffic after it is matched.
Now, let’s view the code in sdn-firewall.py. First, we have to comment out rule = None and replace it with a flow modificatio object with of.ofp_flow_mod().
The flow modification object is the main object used for this project. This adds a rule to the OpenFlow controller that will affect a modification to the traffic flow based on priority, packet characteristic matchin, and an action that will be done to the traffic that is matched. It is defined in Python here and as follows,
class ofp_flow_mod (ofp_header):
def __init__ (self, **kw):
ofp_header.__init__(self)
self.header_type = OFPT_FLOW_MOD
if 'match' in kw:
self.match = None
else:
self.match = ofp_match()
self.priority = OFP_DEFAULT_PRIORITY
self.actions = []
OpenFlow also defines a matching data structure shown above as ofp_match(). This enable us to define a set of headers for the packets to match against. Initially, it will check if there’s a match string in kw to decide whether to create a ofp matching object. Because we are not including string match in kw, we have to create a match object and attach it to the flow modification object manually by,
rule.match = of.ofp_match()
We should also be aware of the following attributes in the ofp matching object,
Name Type Usage
dl_src EthAddr Src MAC Addr
dl_dst EthAddr Dst MAC Addr
dl_type Int Ethertype / length (e.g. 0x0800=IPv4)
nw_proto Int IP protocol (e.g., 6 = TCP)
nw_src String/IPAddr Src IP Addr
nw_dst String/IPAddr Dst IP Addr
tp_src Int TCP/UDP src application port
tp_dst Int TCP/UDP dst application port
These attributed can be specified on the match object to specify the rules. For example,
rule.match.tp_src = 5
rule.match.dl_dst = EthAddr("01:02:03:04:05:06")
For IP address, there are several ways to specify,
Easiest: use the string with mask format
rule.match.nw_src = "192.168.42.0/24"
Formal: use
IPAddrtype
rule.match.nw_src = (IPAddr("192.168.42.0"), 24)
Other: give IP and mask addresses
rule.match.nw_src = "192.168.42.0/255.255.255.0"
In this project, the string method is recommended because it’s the easiest way to do so based on the configure.pol file. Note the policies variable is actually the return value of process_configuration() function defined in file setup-firewall.py. It does use a CSV mapper to go through the configuration file configure.pol so the original values in property should be string type.
Note that in this project, we need to assume all traffic is IPv4 and it’s acceptable to hardcode 0x0800 for dl_type as we have mentioned above.
6. Access Control
In the POX modification object ofp_flow_mod(), there’s another attribute defined as priority. It is initialized as value OFP_DEFAULT_PRIORITY.
In this case, there should be two priorities – one for ALLOW and one for BLOCK. Separate them sufficiently
to override any exact matching behavior that the POX controller implements).
It is suggested the BLOCK priority be 0 or 1 and the ALLOW priority above 10000.
7. OpenFlow Actions
There’s another attribute in OpenFlow modification object ofp_flow_mod.actions. With this, we can define what we want to do for a port after it is matched to a rule.
To make an action, we have to append an ofp_action_output object to the actions list. The ofp_action_output object has the following structure,
class ofp_action_output (object):
def __init__ (self, **kw):
self.port = None
Here the port attribute of this class is the integer output port for the matching packet. Its value could be an actual physical switch port number or one of the
following virtual ports expressed as constants,
of.OFPP_IN_PORT: Send back to input switch portof.OFPP_NORMAL: Process via normal L2/L3 legacy switch configurationof.OFPP_FLOOD: Output to all OpenFlow ports except the input port with flooding enableof.OFPP_ALL: Output to all OpenFlow ports except the input portof.OFPP_CONTROLLER: Send to the OpenFlow controller
Here’s an example if we redirect the matching packet out to physical switch port number 4,
rule.actions.append(of.ofp_action_output(port=4))
8. sdn-firewall.py Test
At project root directory, copy sdn-firewall.py to test-suite/extra. Then go to test-suite/extra. Change all the files to executable.
$ cp sdn-firewall.py test-suite/extra/
$ cd test-suite/extra/
$ chmod -R 777 .
Open two terminal,
One run
$ ./start-firewall.sh configure.polThr other run
$ sudo python test_all.py
A success test should show Passed 15 / 15.
9. Firewall Rules
As we discussed, we also need a CSV-format file configure.pol to create firewall policies. Here’s the tasks we have when creating this firewall.
Note that for the specific IP address of each host, we can go to file sdn-topology.py to check them out.
Also note that we should not use 0.0.0.0/0 to address for world due to the restrictions placed on the implementation by POX. Match arbitrary traffic from anywhere on the network with a - instead.
What’s more, don’t overblock.
TASK 1 - DNS: On the headquarters network, there are two active DNS servers,
hq1provides DNS service to the public, which allows TCP/UDP connects from world at port853hq2provides private DNS service only to 5 corporate networks (us, cn, in, uk, hq). So only hosts in corporate networks can TCP/UDP connect tohq2at port853hq2blocks the world from TCP/UDP access at 853hq2allows corp TCP access at 853hq2allows corp UDP access at 853
TASK 2 - VPN: On the headquarters network,
hq3acts as a VPN serverhq3blocks the world from TCP/UDP access at 1194hq3allows TCP access at 1194 from us3, uk3, in3, and cn3hq3allows UDP access at 1194 from us3, uk3, in3, and cn3
TASK 3 - ICMP: hosts except for the ones in headquarters are not pingable from the world
US, UK, IN, and CN networks are not reachable by ICMP from the world
All corporate hosts can receive a complete ping from any headquarter hosts
TASK 4 - VNC: for remote desktop and VNC purposes
Block the world from TCP access to port 3389 and port 5900
All corporate hosts can TCP connect to headquarter network at port 3389 and port 5900
TASK 5 - Webserver: block corporate hosts for sensitive financial information
Server
us3andus4should block TCP access from uk2, uk3, uk4, uk5, in4, in5, us5, and hq5 at port 8510Note that we should use CIDR notations to make the rules simple. We may use the smallest subnet mask that handles the listed hosts using CIDR notation. We can also use this IP to bin converter to make your life easier.
10. configure.pol Tests
First, clean up the minimap we created through,
$ sudo ./cleanup.sh
At project root directory, copy sdn-firewall.py and configure.pol to test-suite. Then go to test-suite. Change all the files to executable.
$ cp sdn-firewall.py test-suite
$ cp configure.pol test-suite
$ cd test-suite
$ chmod -R 777 .
Open two terminal,
One run
$ ./start-firewall.sh configure.polThr other run
$ sudo python test_all.py
A success test should show Passed 100 / 100.
11. Submission
Go to the git root directory where you implement the code.
$ zip gtusr_sdn.zip packetcapture.pcap configure.pol sdn-firewall.py