Changes between Initial Version and Version 1 of GENIEducation/SampleAssignments/OpenFlowFirewallAssignment/ForInstructors


Ignore:
Timestamp:
05/30/13 16:12:10 (11 years ago)
Author:
shuang@bbn.com
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • GENIEducation/SampleAssignments/OpenFlowFirewallAssignment/ForInstructors

    v1 v1  
     1[[PageOutline]]
     2
     3= Materials and Guidance for leading this exercise: <OpenFlow Firewall ASSIGNMENT> =
     4
     5== Exercise materials ==
     6Anything that the instructor might need, e.g.:
     7 * Instructions can be found [http://www.gpolab.bbn.com/experiment-support/OpenFlowExampleExperiment/forInstructors/of-instructor.pdf Here]
     8
     9
     10== Guidance for leading the exercise ==
     11 * useful commands:
     12 You will find it helpful to know what is going on inside your OpenFlow controller and its associated switch when implementing these exercises.
     13This section contains a few tips that may help you out if you are using the Open vSwitch implementation provided with this tutorial.
     14If you are using a hardware OpenFlow switch, your instructor can help you find equivalent commands. [[BR]]
     15The Open vSwitch installation provided by the RSpec included in this tutorial is located in ''/opt/openvswitch-1.6.1-F15''. You will find Open vSwitch commands in ''/opt/openvswitch-1.6.1-F15/bin'' and ''/opt/openvswitch-1.6.1-F15/sbin''. Some of these commands may be helpful to you. If you add these paths to your shell’s ''$PATH'', you will be able to access their manual pages with man. Note that ''$PATH'' will not affect sudo, so you will still have to provide the absolute path to sudo; the absolute path is omitted from the following examples for clarity and formatting.
     16
     17 - '''2.1 ovs-vsctl'''[[BR]]
     18 Open vSwitch switches are primarily configured using the ''ovs-vsctl'' command. For exploring, you may find the ''ovs-vsctl show'' command useful, as it dumps the status of all virtual switches on the local Open vSwitch instance. Once you have some information on the local switch configurations, ''ovs-vsctl'' provides a broad range of capabilities that you will likely find useful for expanding your network setup to more complex configurations for testing and verification. In particular, the subcommands ''add-br'', ''add-port'', and ''set-controller'' may be of interest.
     19 - '''2.2 ovs-ofctl''' [[BR]]
     20 The switch host configured by the given rspec listens for incoming OpenFlow connections on localhost port 6634.
     21 You can use this to query the switch state using the ''ovs-ofctl'' command. In particular, you may find the ''dump-tables'' and ''dump-flows'' subcommands useful. For example, ''sudo ovs-ofctl dump-flows tcp:127.0.0.1:6634'' will output lines that look like this:
     22 {{{
     23cookie=0x4, duration=6112.717s, table=0, n packets=1, n bytes=74, idle age=78,priority=5,tcp,
     24nw src=10.10.10.0/24 actions=CONTROLLER:65535
     25 }}}
     26 This indicates that any TCP segment with source IP in the 10.10.10.0/24 subnet should be sent to the OpenFlow controller for processing, that it has been 78 seconds since such a segment was last seen, that one such segment has been seen so far, and the total number of bytes in packets matching this rule is 74. The other fields are perhaps interesting, but you will probably not need them for debugging. (Unless, of course, you choose to use multiple tables — an exercise in OpenFlow 1.1 functionality left to the reader.)
     27 - '''2.3 Unix utilities'''[[BR]]
     28 You will want to use a variety of Unix utilities, in addition to the tools listed in [http://groups.geni.net/geni/wiki/GENIEducation/SampleAssignments/OpenFlowAssignment/ExerciseLayout ExerciseLayout], to test your controllers. The standard ping and ''/usr/sbin/arping'' tools are useful for debugging connectivity (but make sure your controller passes ''ICMP ECHO REQUEST'' and ''REPLY'' packets and ''ARP'' traffic, respectively!), and the command ''netstat -an'' will show all active network connections on a Unix host; the TCP connections of interest in this exercise will be at the top of the listing. The format of netstat output is out of the scope of this tutorial, but information is available online and in the manual pages.
     29
     30== Solutions ==
     31 - '''3.1 Building a Firewall with OpenFlow [[BR]]'''
     32 A firewall observes the packets that pass through it, and uses a set of rules to determine whether any given packet should be allowed to pass. A stateless firewall does this using only the rules and the current packet. A stateful firewall keeps track of the packets it has seen in the past, and uses information about them, along with the rules, to make its determinations. [[BR]]
     33 In this exercise, you will build a stateful firewall controller for TCP connections in OpenFlow. The first packet of each connection will be handled by the controller, but all other connection packets will be handled by the OpenFlow-enabled router or switch without contacting your controller. This design will allow you to write powerful firewall rule sets without unduly impacting packet forwarding speeds. Your controller will parse a simple configuration file to load its rules. Complete stateful firewalls often handle multiple TCP/IP protocols (generally at least both TCP and UDP), track transport protocol operational states, and often understand some application protocols, particularly those utilizing multiple transport streams (such as FTP, SIP, and DHCP). The firewall you will implement for this exercise, however, needs handle only TCP, and will not directly process packet headers or data. [[BR]] [[BR]]
     34
     35  Question 1. fill up the blanks in function `switch_ready` to insert rules into the openflow switch that allow ICMP and ARP packets to go through [[BR]]
     36  Question 2. fill up the blanks in function `packet_in` to insert a flow match in the OpenFlow device that allows the packets (as well as those in the reverse path) that match rules in the fw.conf to pass [[BR]]
     37  Question 3. fill up the blanks in function `packet_in` to insert rules that drops all other packets that does not match the rules specified in fw.conf [[BR]]
     38  '''Solution: the source code for the OpenFlow Controller as well as a sample configuration file can be downloaded from [http://www.gpolab.bbn.com/experiment-support/OpenFlowExampleExperiment/firewall-solution1.rb firewall-solution1.rb] and [http://www.gpolab.bbn.com/experiment-support/OpenFlowExampleExperiment/fw-solution1.conf fw-solution1.conf] [[BR]]'''
     39  '''Change the name to firewall.rb and fw.conf respectively after you downloaded these two files''' [[BR]]
     40  To verify your implementation, run the following on the switch:
     41{{{
     42/opt/trema-trema-8e97343/trema run 'firewall.rb fw.conf'
     43}}}
     44  Then try to ping from left to right. Ping should go through since you allowed ICMP packets and ARP packets to pass. [[BR]]
     45  If you are using the fw.conf we provided, try to run a TCP session from left to right using iperf using port 5001, 5002, 5003.
     46  Since in the fw.conf file we provided, we specifically allow TCP to go through port 5001 and 5002, but not port 5003, you should be able to see that iperf gives back throughput results for port 5001 and 5002 but not 5003.
     47
     48  Try play with the code as well as the fw.conf file to setup more rules, then verify your setting via iperf or telnet. [[BR]]
     49  You can check the flow table on the OpenFlow Switch via:
     50{{{
     51sudo /opt/openvswitch-1.6.1-F15/bin/ovs-ofctl dump-flows tcp:127.0.0.1:6634
     52}}}
     53  A sample output should be something like the following:
     54{{{
     55NXST_FLOW reply (xid=0x4):
     56 cookie=0x1, duration=165.561s, table=0, n_packets=6, n_bytes=360, idle_age=17,priority=65535,arp actions=NORMAL
     57 cookie=0xa, duration=43.24s, table=0, n_packets=3, n_bytes=222, idle_timeout=300,idle_age=22,priority=65535,tcp,in_port=1,vlan_tci=0x0000,dl_src=00:02:b3:65:d1:2b,dl_dst=00:03:47:94:c7:fd,nw_src=10.10.10.1,nw_dst=10.10.11.1,nw_tos=0,tp_src=46361,tp_dst=5003 actions=drop
     58 cookie=0x5, duration=147.156s, table=0, n_packets=18289, n_bytes=27682198, idle_timeout=300,idle_age=137,priority=65535,tcp,in_port=1,vlan_tci=0x0000,dl_src=00:02:b3:65:d1:2b,dl_dst=00:03:47:94:c7:fd,nw_src=10.10.10.1,nw_dst=10.10.11.1,nw_tos=0,tp_src=33385,tp_dst=5001 actions=NORMAL
     59 cookie=0x9, duration=105.294s, table=0, n_packets=4, n_bytes=296, idle_timeout=300,idle_age=60,priority=65535,tcp,in_port=1,vlan_tci=0x0000,dl_src=00:02:b3:65:d1:2b,dl_dst=00:03:47:94:c7:fd,nw_src=10.10.10.1,nw_dst=10.10.11.1,nw_tos=0,tp_src=46360,tp_dst=5003 actions=drop
     60 cookie=0x7, duration=124.764s, table=0, n_packets=17902, n_bytes=27095256, idle_timeout=300,idle_age=114,priority=65535,tcp,in_port=1,vlan_tci=0x0000,dl_src=00:02:b3:65:d1:2b,dl_dst=00:03:47:94:c7:fd,nw_src=10.10.10.1,nw_dst=10.10.11.1,nw_tos=0,tp_src=57908,tp_dst=5002 actions=NORMAL
     61 cookie=0x3, duration=165.561s, table=0, n_packets=1, n_bytes=74, idle_timeout=300,idle_age=124,priority=65535,tcp,nw_src=10.10.10.0/24,nw_dst=10.10.11.0/24,tp_dst=5002 actions=CONTROLLER:65535
     62 cookie=0x4, duration=165.561s, table=0, n_packets=1, n_bytes=74, idle_timeout=300,idle_age=147,priority=65535,tcp,nw_src=10.10.10.0/24,nw_dst=10.10.11.0/24,tp_dst=5001 actions=CONTROLLER:65535
     63 cookie=0x2, duration=165.561s, table=0, n_packets=0, n_bytes=0, idle_age=165,priority=65535,icmp actions=NORMAL
     64 cookie=0x6, duration=147.156s, table=0, n_packets=9387, n_bytes=624254, idle_timeout=300,idle_age=137,priority=65535,tcp,nw_src=10.10.11.1,nw_dst=10.10.10.1,tp_src=5001,tp_dst=33385 actions=NORMAL
     65 cookie=0x8, duration=124.764s, table=0, n_packets=9257, n_bytes=617666, idle_timeout=300,idle_age=114,priority=65535,tcp,nw_src=10.10.11.1,nw_dst=10.10.10.1,tp_src=5002,tp_dst=57908 actions=NORMAL
     66}}}
     67  Note that for tp_dst=5003, the action is drop, for tp_dst=5001 and 5002 (as well as the reverse path), the action is NORMAL [[BR]]
     68
     69  '''Extra Credit''' --- I have not done it yet [[BR]]
     70  For extra credit (if permitted by your instructor), generate TCP reset segment at the firewall to reset rejected connections.
     71
     72 - '''3.2 Extending the Firewall''' [[BR]]
     73 OpenFlow controllers can also make complex flow decisions based on arbitrary state. This is one benefit to removing the controller from the network device — the controller is free to perform any computation required over whatever data is available when making decisions, rather than being constrained to the limited computing power and storage of the network device. For this exercise, you will extend the firewall described in Section 3.1 to include rudimentary denial of service prevention using this capability. [[BR]]
     74
     75  '''Solution: the source code for the OpenFlow Controller as well as a sample configuration file can be downloaded from [http://www.gpolab.bbn.com/experiment-support/OpenFlowExampleExperiment/firewall-solution2.rb firewall-solution2.rb] and [http://www.gpolab.bbn.com/experiment-support/OpenFlowExampleExperiment/fw-solution1.conf fw-solution2.conf] [[BR]]'''
     76  '''Change the name to firewall.rb and fw.conf respectively after you downloaded these two files''' [[BR]]
     77  To verify your implementation, run the following on the switch:
     78{{{
     79/opt/trema-trema-8e97343/trema run 'firewall.rb fw.conf'
     80}}}
     81  In this OpenFlow controller, I set the idle_timeout to 30 seconds so that you will not need to wait for too long before the connection times out and the flow entries got removed. [[BR]]
     82  I set the maximum number of allowed flows for port 5002 to be 10 in fw.conf. [[BR]]
     83  When the controller is up, run the following on right node:
     84{{{
     85/usr/local/etc/emulab/emulab-iperf -s -p 5002
     86}}}
     87  Run the following on the left node to create 10 flows sending to port 5002:
     88{{{
     89/usr/local/etc/emulab/emulab-iperf -c 10.10.11.1 -p 5002 -P 10
     90}}}
     91  Iperf would go through since it allows 10 flows to pass. At the same time, the OpenFlow Controller (firewall.rb) should output the following:
     92{{{
     93action=allow, datapath_id=0x2b3861f8b, count=1, limit=10, message={wildcards = 0(none), in_port = 1, dl_src = 00:02:b3:65:d1:2b, dl_dst = 00:03:47:94:c7:fd, dl_vlan = 65535, dl_vlan_pcp = 0, dl_type = 0x800, nw_tos = 0, nw_proto = 6, nw_src = 10.10.10.1/32, nw_dst = 10.10.11.1/32, tp_src = 35288, tp_dst = 5002}
     94action=allow, datapath_id=0x2b3861f8b, count=2, limit=10, message={wildcards = 0(none), in_port = 1, dl_src = 00:02:b3:65:d1:2b, dl_dst = 00:03:47:94:c7:fd, dl_vlan = 65535, dl_vlan_pcp = 0, dl_type = 0x800, nw_tos = 0, nw_proto = 6, nw_src = 10.10.10.1/32, nw_dst = 10.10.11.1/32, tp_src = 35289, tp_dst = 5002}
     95action=allow, datapath_id=0x2b3861f8b, count=3, limit=10, message={wildcards = 0(none), in_port = 1, dl_src = 00:02:b3:65:d1:2b, dl_dst = 00:03:47:94:c7:fd, dl_vlan = 65535, dl_vlan_pcp = 0, dl_type = 0x800, nw_tos = 0, nw_proto = 6, nw_src = 10.10.10.1/32, nw_dst = 10.10.11.1/32, tp_src = 35290, tp_dst = 5002}
     96action=allow, datapath_id=0x2b3861f8b, count=4, limit=10, message={wildcards = 0(none), in_port = 1, dl_src = 00:02:b3:65:d1:2b, dl_dst = 00:03:47:94:c7:fd, dl_vlan = 65535, dl_vlan_pcp = 0, dl_type = 0x800, nw_tos = 0, nw_proto = 6, nw_src = 10.10.10.1/32, nw_dst = 10.10.11.1/32, tp_src = 35291, tp_dst = 5002}
     97action=allow, datapath_id=0x2b3861f8b, count=5, limit=10, message={wildcards = 0(none), in_port = 1, dl_src = 00:02:b3:65:d1:2b, dl_dst = 00:03:47:94:c7:fd, dl_vlan = 65535, dl_vlan_pcp = 0, dl_type = 0x800, nw_tos = 0, nw_proto = 6, nw_src = 10.10.10.1/32, nw_dst = 10.10.11.1/32, tp_src = 35292, tp_dst = 5002}
     98action=allow, datapath_id=0x2b3861f8b, count=6, limit=10, message={wildcards = 0(none), in_port = 1, dl_src = 00:02:b3:65:d1:2b, dl_dst = 00:03:47:94:c7:fd, dl_vlan = 65535, dl_vlan_pcp = 0, dl_type = 0x800, nw_tos = 0, nw_proto = 6, nw_src = 10.10.10.1/32, nw_dst = 10.10.11.1/32, tp_src = 35293, tp_dst = 5002}
     99action=allow, datapath_id=0x2b3861f8b, count=7, limit=10, message={wildcards = 0(none), in_port = 1, dl_src = 00:02:b3:65:d1:2b, dl_dst = 00:03:47:94:c7:fd, dl_vlan = 65535, dl_vlan_pcp = 0, dl_type = 0x800, nw_tos = 0, nw_proto = 6, nw_src = 10.10.10.1/32, nw_dst = 10.10.11.1/32, tp_src = 35294, tp_dst = 5002}
     100action=allow, datapath_id=0x2b3861f8b, count=8, limit=10, message={wildcards = 0(none), in_port = 1, dl_src = 00:02:b3:65:d1:2b, dl_dst = 00:03:47:94:c7:fd, dl_vlan = 65535, dl_vlan_pcp = 0, dl_type = 0x800, nw_tos = 0, nw_proto = 6, nw_src = 10.10.10.1/32, nw_dst = 10.10.11.1/32, tp_src = 35295, tp_dst = 5002}
     101action=allow, datapath_id=0x2b3861f8b, count=9, limit=10, message={wildcards = 0(none), in_port = 1, dl_src = 00:02:b3:65:d1:2b, dl_dst = 00:03:47:94:c7:fd, dl_vlan = 65535, dl_vlan_pcp = 0, dl_type = 0x800, nw_tos = 0, nw_proto = 6, nw_src = 10.10.10.1/32, nw_dst = 10.10.11.1/32, tp_src = 35296, tp_dst = 5002}
     102action=allow, datapath_id=0x2b3861f8b, count=10, limit=10, message={wildcards = 0(none), in_port = 1, dl_src = 00:02:b3:65:d1:2b, dl_dst = 00:03:47:94:c7:fd, dl_vlan = 65535, dl_vlan_pcp = 0, dl_type = 0x800, nw_tos = 0, nw_proto = 6, nw_src = 10.10.10.1/32, nw_dst = 10.10.11.1/32, tp_src = 35297, tp_dst = 5002}
     103}}}
     104  Pay attention to the `count` and `limit` in the output. [[BR]]
     105  now if you quickly do the following on the left node to add another flow before the current 10 flows expire:
     106{{{
     107/usr/local/etc/emulab/emulab-iperf -c 10.10.11.1 -p 5002
     108}}}
     109  You may find that iperf will not go through, and the controller outputs the following:
     110{{{
     111action=block, datapath_id=0x2b3861f8b, count=10, limit=10, message={wildcards = 0(none), in_port = 1, dl_src = 00:02:b3:65:d1:2b, dl_dst = 00:03:47:94:c7:fd, dl_vlan = 65535, dl_vlan_pcp = 0, dl_type = 0x800, nw_tos = 0, nw_proto = 6, nw_src = 10.10.10.1/32, nw_dst = 10.10.11.1/32, tp_src = 36399, tp_dst = 5002}
     112}}}
     113  This indicates that this additional flow is blocked.
     114  Next, if you wait enough time, in our case here, 30 seconds, you will find the controller outputting the following:
     115{{{
     116Flow Entry Expired or Removed!!!!!!!!!!!action=allow, datapath_id=0x2b3861f8b, count=9, limit=10, message={wildcards = 0(none), in_port = 1, dl_src = 00:02:b3:65:d1:2b, dl_dst = 00:03:47:94:c7:fd, dl_vlan = 65535, dl_vlan_pcp = 0, dl_type = 0x800, nw_tos = 0, nw_proto = 6, nw_src = 10.10.10.1/32, nw_dst = 10.10.11.1/32, tp_src = 35290, tp_dst = 5002}
     117Flow Entry Expired or Removed!!!!!!!!!!!action=allow, datapath_id=0x2b3861f8b, count=8, limit=10, message={wildcards = 0(none), in_port = 1, dl_src = 00:02:b3:65:d1:2b, dl_dst = 00:03:47:94:c7:fd, dl_vlan = 65535, dl_vlan_pcp = 0, dl_type = 0x800, nw_tos = 0, nw_proto = 6, nw_src = 10.10.10.1/32, nw_dst = 10.10.11.1/32, tp_src = 35293, tp_dst = 5002}
     118Flow Entry Expired or Removed!!!!!!!!!!!action=allow, datapath_id=0x2b3861f8b, count=7, limit=10, message={wildcards = 0(none), in_port = 1, dl_src = 00:02:b3:65:d1:2b, dl_dst = 00:03:47:94:c7:fd, dl_vlan = 65535, dl_vlan_pcp = 0, dl_type = 0x800, nw_tos = 0, nw_proto = 6, nw_src = 10.10.10.1/32, nw_dst = 10.10.11.1/32, tp_src = 35295, tp_dst = 5002}
     119Flow Entry Expired or Removed!!!!!!!!!!!action=allow, datapath_id=0x2b3861f8b, count=6, limit=10, message={wildcards = 0(none), in_port = 1, dl_src = 00:02:b3:65:d1:2b, dl_dst = 00:03:47:94:c7:fd, dl_vlan = 65535, dl_vlan_pcp = 0, dl_type = 0x800, nw_tos = 0, nw_proto = 6, nw_src = 10.10.10.1/32, nw_dst = 10.10.11.1/32, tp_src = 35292, tp_dst = 5002}
     120Flow Entry Expired or Removed!!!!!!!!!!!action=allow, datapath_id=0x2b3861f8b, count=5, limit=10, message={wildcards = 0(none), in_port = 1, dl_src = 00:02:b3:65:d1:2b, dl_dst = 00:03:47:94:c7:fd, dl_vlan = 65535, dl_vlan_pcp = 0, dl_type = 0x800, nw_tos = 0, nw_proto = 6, nw_src = 10.10.10.1/32, nw_dst = 10.10.11.1/32, tp_src = 35291, tp_dst = 5002}
     121Flow Entry Expired or Removed!!!!!!!!!!!action=allow, datapath_id=0x2b3861f8b, count=4, limit=10, message={wildcards = 0(none), in_port = 1, dl_src = 00:02:b3:65:d1:2b, dl_dst = 00:03:47:94:c7:fd, dl_vlan = 65535, dl_vlan_pcp = 0, dl_type = 0x800, nw_tos = 0, nw_proto = 6, nw_src = 10.10.10.1/32, nw_dst = 10.10.11.1/32, tp_src = 35296, tp_dst = 5002}
     122Flow Entry Expired or Removed!!!!!!!!!!!action=allow, datapath_id=0x2b3861f8b, count=3, limit=10, message={wildcards = 0(none), in_port = 1, dl_src = 00:02:b3:65:d1:2b, dl_dst = 00:03:47:94:c7:fd, dl_vlan = 65535, dl_vlan_pcp = 0, dl_type = 0x800, nw_tos = 0, nw_proto = 6, nw_src = 10.10.10.1/32, nw_dst = 10.10.11.1/32, tp_src = 35288, tp_dst = 5002}
     123Flow Entry Expired or Removed!!!!!!!!!!!action=allow, datapath_id=0x2b3861f8b, count=2, limit=10, message={wildcards = 0(none), in_port = 1, dl_src = 00:02:b3:65:d1:2b, dl_dst = 00:03:47:94:c7:fd, dl_vlan = 65535, dl_vlan_pcp = 0, dl_type = 0x800, nw_tos = 0, nw_proto = 6, nw_src = 10.10.10.1/32, nw_dst = 10.10.11.1/32, tp_src = 35289, tp_dst = 5002}
     124Flow Entry Expired or Removed!!!!!!!!!!!action=allow, datapath_id=0x2b3861f8b, count=1, limit=10, message={wildcards = 0(none), in_port = 1, dl_src = 00:02:b3:65:d1:2b, dl_dst = 00:03:47:94:c7:fd, dl_vlan = 65535, dl_vlan_pcp = 0, dl_type = 0x800, nw_tos = 0, nw_proto = 6, nw_src = 10.10.10.1/32, nw_dst = 10.10.11.1/32, tp_src = 35297, tp_dst = 5002}
     125Flow Entry Expired or Removed!!!!!!!!!!!action=allow, datapath_id=0x2b3861f8b, count=0, limit=10, message={wildcards = 0(none), in_port = 1, dl_src = 00:02:b3:65:d1:2b, dl_dst = 00:03:47:94:c7:fd, dl_vlan = 65535, dl_vlan_pcp = 0, dl_type = 0x800, nw_tos = 0, nw_proto = 6, nw_src = 10.10.10.1/32, nw_dst = 10.10.11.1/32, tp_src = 35294, tp_dst = 5002}
     126}}}
     127  This means that the controller caught the flow entry removed event from the OpenFlow switch and it updated the count value for the corresponding rule. [[BR]]
     128  Next, if you try to send a TCP flow using iperf again, it would go through.
     129
     130
     131 * Answers can be found [http://www.gpolab.bbn.com/experiment-support/OpenFlowExampleExperiment/forInstructors/ Here]