wiki:GENIExperimenter/Tutorials/OpenFlowNFVFirewall

Version 2 (modified by nriga@bbn.com, 6 years ago) (diff)

--

OpenFlow Firewall

This exercise is based on as assignment by Sonia Famy, Ethan Blanton and Sriharsha Gangam of Purdue University.

TinyUrl: http://tinyurl.com/geni-nfv-nat

Overview:

In this tutorial you will learn how to build a router for a network with a private address space that needs a one-to-many NAT (IP Masquerade) using OpenFlow. We will use the following network topology for this experiment. You will also learn how to take advantage of kernel L3 routing while using OVS . route topology
   

Prerequisites:

For this tutorial you need :

Tools:

All the tools will already be installed at your nodes. For your reference we are going to use a Ryu controller.
   

Where to get help:

For any questions or problem with the tutorial please email geni-users@googlegroups.com

Design/Setup

If you have already reserved the topology from a previous tutorial you can move to Execute.

1. Verify your Environment Setup:

This exercise assumes you have already setup your account at the GENI Portal. In particular ensure that:
  1. You can login to the GENI Portal
  2. You are a member of a GENI Project (there is at least one project listed under the ''Projects'' tab)
  3. You have setup your ssh keys (there is at least one key listed under the ''Profile->SSH Keys'' tab)

2. Setup the Topology:

  1. Login to the GENI Portal
  2. Reserve:
    1. the topology from an InstaGENI rack using the OpenFlow OVS all XEN RSpec (In Portal: "OpenFlow OVS all XEN"; URL: http://www.gpolab.bbn.com/experiment-support/OpenFlowOVS/openflowovs-all-xen.rspec.xml)
    2. at a different InstaGENI rack reserve a XEN OpenFlow Controller RSpec (In Portal: "XEN OpenFlow Controller"; URL: http://www.gpolab.bbn.com/experiment-support/OpenFlowOVS/xen-openflow-controller-rspec.xml)


Execute

3. Test reachability before starting controller

3.1 Login to your hosts

To start our experiment we need to ssh into all the hosts (controller, ovs, host1, host2, host3). Depending on which tool and OS you are using there is a slightly different process for logging in. If you don't know how to SSH to your reserved hosts take a look in this page. Once you have logged in, follow the rest of the instructions.

3.1a Configure OVS

  1. Write down the interface names that correspond to the connections to your hosts (use ifconfig). The correspondence is:
    • h1_if: Interface with IP 10.10.1.11 to host1 - ethX
    • h2_if: Interface with IP 10.10.1.12 to host2 - ethY
    • h3_if: Interface with IP 10.10.1.13 to host3 - ethZ
  2. In the OVS node run:
    wget http://www.gpolab.bbn.com/experiment-support/NFVApps/ovs-nat-conf.sh ; chmod +x ovs-nat-conf.sh
    sudo ./ovs-nat-conf.sh <h1_if> <h2_if> <h3_if> <controller_ip>
    

3.1b Configure hosts

The hosts in your topology are all in the same subnet, 10.10.1.0/24. We will move host3 to a different subnet:

  1. host3: Assign 128.128.128.128 to host3.
     sudo ifconfig eth1 128.128.128.128/24
    
  1. host1, host2: Setup routes at host1 and host1 to 128.128.128.0/24 subnet:
     sudo route add -net 128.128.128.0 netmask 255.255.255.0 gw 10.10.1.100
    

3.2 Test reachability

  1. First we start a ping from inside1 to inside2, which should work since they are both inside the same LAN.
    host1:~$ ping 10.10.1.2 -c 10
    
  1. Then we start a ping from outside to inside1, which should timeout as there is no routing information in its routing table. You can use route -n to verify that.
    host3:~$ ping 10.10.1.2 -c 10
    
  1. Similarly, we cannot ping from insideX to outside.
  1. You can also use Netcat (nc) to test reachability of TCP and UDP. The behavior should be the same.

4 Start controller to enable NAT

4.1 Access a server from behind the NAT

You can try to write your own controller to implement NAT. However, we a provide you a functional controller.

  1. Download the NAT Ryu module. At your controller node run:
    cd /tmp/ryu/
    wget http://www.gpolab.bbn.com/experiment-support/NFVApps/ryu-nat.tar.gz
    tar xvfz ryu-nat.tar.gz
    
  1. Start the controller on NAT host:
    nat:~$ cd /tmp/ryu/; ./bin/ryu-manager ryu-nat.py
    

You should see output similar to following log after the switch is connected to the controller

loading app ryu-nat.py
loading app ryu.controller.dpset
loading app ryu.controller.ofp_handler
instantiating app ryu.controller.dpset of DPSet
instantiating app ryu.controller.ofp_handler of OFPHandler
instantiating app ryu-nat.py of NAT
switch connected <ryu.controller.controller.Datapath object at 0x2185210>
  1. On outside, we start a nc server:
    host3:~$ nc -l 6666
    

and we start a nc client on inside1 to connect it:

host1:~$ nc 128.128.128.2 6666
  1. Now send message between each other and try the same thing between host3 and host2.
  1. On the terminal of controller, in which you started your controller, you should see a log similar to:
    Created mapping 192.168.0.3 31596 to 128.128.128.100 59997
    

Note that there should be only one log per connection, because the rest of the communication will re-use the mapping.

5 Handle ARP and ICMP

One of very common mistakes that people make, when writing OF controller, is forgetting to handle ARP and ICMP message and finding their controller does not work as expected.

5.1 ARP

As we mentioned before, we should insert rules into the OF switch that allow ARP packets to go through, probably after the switch is connected.

5.2 ICMP

Handling ARP is trivial as NAT does not involve ARP. However, it's not the case for ICMP. If you only process translation for TCP/UDP, you will find you cannot ping between outside and insideX while nc is working properly. Handling ICMP is even not as straightforward as for TCP/UDP. Because for ICMP, you cannot get port information to bind with. Our provided solution makes use of ICMP echo identifier. You may come up with different approach involves ICMP sequence number or others.

  1. On inside1, start a ping to outside.
    host1:~$ ping 128.128.128.128
    
  1. Do the same thing on host2.
    host2:~$ ping 128.128.128.128
    

You should see both pinging are working.

  1. On host3, use tcpdump to check the packets it receives.
    host3:~$ sudo tcpdump -i eth1 -n icmp
    

You should see it's receiving two groups of icmp packets, differentiated by id.

Finish

6. Cleanup

After you are done with the exercise and you have captured everything requested for the writeup, you should release your resources so that other experimenters can use them. In order to cleanup your slice :
  1. In Flack, press the Delete button in the bottom of your canvas
  2. Select Delete at used managers and confirm your selection.
Wait and after a few moments all the resources will have been released and you will have an empty canvas again. Notice that your slice is still there. There is no way to delete a slice, it will be removed automatically after its expiration date, but remember that a slice is just an empty container so it doesn't take up any resources.

Tips

  • Remember that you can use “ifconfig” to determine which Ethernet interface (e.g., eth0) is bound to what IP address at each of the nodes.
  • In order to enable IP forwarding of packets on a node you have to execute the following command:
    sudo sh -c 'echo 1 > /proc/sys/net/ipv4/ip_forward'
    

For this experiment we will run an OpenFlow Firewall.

http://groups.geni.net/geni/raw-attachment/wiki/GENIExperimenter/Tutorials/OpenFlowNetworkDevices/Firewall/Firewall-2.png

  1. Log into switch and run the following commands to download and run the firewall controller:
    sudo apt-get install python-pip python-dev libxml2-dev libxslt-dev zlib1g-dev
    sudo pip install oslo.config
    
  2. Run a simple learning switch controller:
    cd /tmp/ryu
    ./bin/ryu-manager --verbose ryu/app/simple_switch.py
    
  3. Verify simple connectivity by logging into right ping left
    ping left
    
    Notice the printouts of the ryu simple switch controller.
  4. Stop your controller by Ctrl-c and remove all your flows
    sudo ovs-ofctl del-flows br0
    
  5. Make your switch into a firewall by downloading and running the appropriate Ryu controller:
    wget http://www.gpolab.bbn.com/exp/OpenFlowExampleExperiment/ryu/gpo-ryu-firewall.tar.gz
    tar xvfz gpo-ryu-firewall.tar.gz
    cd gpo-ryu-firewall/
    /tmp/ryu/bin/ryu-manager simple_firewall.py
    
    WARNING If at some point your controller prints an error, kill it (ctrc-c) and start it again.
  6. Log into right and run a nc server:
    nc -l 5001
    
  7. Log into left and run a nc client:
    nc 10.10.11.1 5001
    
  8. Type some text in left and it should appear in right and vise versa.
  9. In the terminal for switch you should see messages about the flow being passed or not:
    Extracted rule {'sport': '57430', 'dport': '5001', 'sip': '10.10.10.1', 'dip': '10.10.11.1'}
    Allow Connection rule {'dport': '5001', 'dip': '10.10.11.1', 'sip': '10.10.10.1', 'sport': 'any'}
    
  10. CTRL-C to kill nc in each terminal.
  11. Run a nc server on port 5002, then 5003.
    • Compare the observed behavior to the contents of ~/gpo-ryu-firewall/fw.conf. Does the behavior match the configuration file?
    • Stop the Firewall controller and run a simple switch controller. Is there any traffic being blocked now? Don't forget to delete the flows after you stop the controller
    • Feel free to modify the configuration file to allow more traffic.

Return to the main page