Experiment 4: Handling Intrusion with Ryu Controller : Port Scanning Attack


In this experiment, we will use the Ryu controller to handle intrusion traffic in the form of port scans generated by the Nmap application. The system is the same as the one used in Experiment 3, where we use a RINA distributed application to get the intrusion detection alerts from the VNFs (i.e., Snort) as well as the load of the VNFs. When an intrusion is detected by the VNFs, the information will be passed to the Attack Analyzer residing on the controller node via the RINA distributed application. The Attack Analyzer informs the Ryu controller about the attack, which then blocks the intrusion traffic by updating the OpenFlow rules on the OVS switch.

NOTE: If you have done experiment 2 or experiment 3, you can skip steps 1-3 below.

(1) RINA Distributed Application

(Same as Part (1) in Experiment 2 and Experiment 3)

The RINA distributed application collects the CPU load of VNF1 and VNF2, as well as any Snort alerts generated by the Snort applications running on VNF1 and VNF2. These Snort alerts are collected on the Controller node and saved in file /tmp/snortalerts by the RINA distributed application.

We need Java installed on the VNF1, VNF2 and controller nodes to run the RINA application. Check if Java is installed using: java -version. If not, install java on VNF1, VNF2 and controller nodes in new windows (Type Ctrl-C to exit netcat on the sources and destination). To install Java, execute:  sudo apt-get install openjdk-7-jdk
(If the install fails, you may first run: sudo apt-get update. In some cases, you may need to first run: sudo add-apt-repository ppa:openjdk-r/ppa followed by: sudo apt-get update.)
  1. In the controller window, download the RINA controller code:
  • cd ~
  • wget
  • tar -xvf Control.tar.gz
  1. Type ifconfig to get the IP address of the controller. Save this address as we will need this address to direct the RINA processes on the VNFs to the RINA process on the controller.
  1. In a new VNF1 window, download the RINA VNF1 code:
  • cd ~
  • wget
  • tar -xvf VNF1.tar.gz
  1. In a new VNF2 window, download the RINA VNF2 code.
  • cd ~
  • wget
  • tar -xvf VNF2.tar.gz
  1. Now we will change the IP address in the RINA configuration files for VNF1, VNF2 and controller, so these RINA processes can talk to each other. In the VNF1 window, execute:
  • cd ~/VNF1/RINA
  • nano

At the bottom of the file, change the and to the IP address of the controller. The following screenshot shows an example.

In the VNF2 window, execute:

  • cd ~/VNF2/RINA
  • nano

At the bottom of the file, again change the and to the IP address of the controller.

In the controller window, execute:

  • cd ~/Control/RINA
  • nano

At the bottom of the file, again change the '' and '' to the IP address of the controller.

  1. To run the RINA application, follow these steps (make sure you installed Java as noted above):

o In the controller window, execute the following commands:

  • cd ~/Control/RINA/
  • ./

o In the VNF1 window, execute the following commands:

  • cd ~/VNF1/RINA
  • ./

o In the VNF2 window, execute the following commands:

  • cd ~/VNF2/RINA
  • ./

You should see output on the controller window as shown below:

The RINA application on VNF1 and VNF2 should be run as soon as possible after the RINA application on the controller is started. If you wait for too long, you will get null values for CPU usage, as the controller's RINA app is not able to subscribe to the CPU load of the VNFs. If this is the case, you should restart all RINA processes.
To stop all RINA processes running on a VM, run killall -v java

(2) PI Controller

(Same as Part (2) in Experiment 2 and Experiment 3)

The PI-controller gets the load information of VNF1 and VNF2 using RINA's distributed application and makes the load balancing decision.

The figure below shows the block diagram of the Proportional Integral (PI) controlled NFV system.

Block diagram of the PI-controller NFV system. System load L and target load T(s)=T/s of VNF1 is used to compute X, i.e. ratio of traffic diverted to VNF2. K` = K/T.

The RINA-based distributed monitoring application provides the VNF1 state (average CPU load) information L(t) to the PI controller. The maximum capacity of a VNF instance is T. If the load on VNF1 exceeds T, new traffic flows are forwarded to a second VNF instance, VNF2. Assuming instantaneous feedback / measured load L(t), the PI control equation is given by:

The code for the PI controller is based on the following algorithm. Input IDSload.txt is the file generated by the RINA distributed application. This file has load information of the VNFs.

  1. To run the PI-controller, open a new controller window and execute:
  • cd ~/Control/PI_controller
  • python ~/Control/RINA/NFV1.txt

Note that here we are directing to the NFV1.txt file that is constantly updated by the RINA distributed application with the load information of VNFs.

  1. You should see the VNF state information printed on the screen. A sample output is shown below.

Here the target load on VNF1 is 50.0% of CPU usage, i.e. if the CPU load on VNF1 is more than 50.0%, traffic flows will be diverted to VNF2. The current CPU load shows the load on VNF1. The next line of the output shows the percentage of flows that will be directed to VNF2 and the last line shows the flows that were being directed to VNF2 before the current control update.

Do not close this window; leave the PI controller running.

(3) PI-based Ryu Controller

(Same as Part (3) in Experiment 2 and Experiment 3)

Now we will run the Ryu controller that will get the load balancing decision from the PI-controller and direct the flows accordingly.

  1. First we will update the nfv.config file to direct the controller to the NFV_ratio_PI.txt file generated by the PI-controller, which has the load balancing decision information. In a new controller window, execute:
  • nano /tmp/ryu/ryu/app/nfv.config

o Change the value of controller_type to PI
o Change the value of file_path_pi to the text file that has the PI controller's output.

Change the <UserName> to your user name.

  1. Now we can run the Ryu controller. Execute
  • /tmp/ryu/bin/ryu-manager --verbose /tmp/ryu/ryu/app/

(4) Run Snort

Note: keep the RINA application processes, PI controller process and PI-based Ryu controller process from the previous 3 steps running in the background.

  1. We need to first configure Snort so that we can use our rules, or snort’s build-in rules to detect the intrusion traffic.

To configure Snort, in separate windows for VNF1 and VNF2, execute the following commands

For VNF1:

  • cd ~/VNF1/SnortSetup
  • chmod 755
  • ./

For VNF2:

  • cd ~/VNF2/SnortSetup
  • chmod 755
  • ./
  1. Make sure that file /etc/snort/rules/my.rules is empty. This file contains any custom rules to generate Snort attack alerts. For this experiment, we will be using Snort build-in rules for detecting port-scanning attack.
  1. Update “/etc/snort/snort.conf” to enable the port scanning functionality of Snort. You can update it by uncommenting the following line:
  • preprocessor sfportscan: proto { all } memcap { 10000000 } sense_level { low }

and updating it as follows

  • preprocessor sfportscan: proto { all } memcap { 10000000 } sense_level { medium } logfile { /var/log/snort/alert }
  1. We then run Snort IDS on VNF1 and VNF2. In separate windows for VNF1 and VNF2, execute the following command:
  • sudo /usr/local/bin/snort -A full -dev -c /etc/snort/snort.conf -i eth1

Note: exit from previous instances of Snort if they are still running from earlier experiments before you run this instance of Snort.

Note: this command is different from Experiment 2. Here we specify the file /etc/snort/snort.conf to indicate which rule files to load.

When Snort detects intrusion traffic, it will save the alert messages into the file /var/log/snort/alert. The RINA distributed application keeps reading this alert file, and passes any intrusion information to the Ryu controller which will block the intrusion traffic.

(5) Run Attack Analyzer

The Attack Analyzer reads the Snort alerts saved on the Controller node and makes decisions about which IP addresses to block. The Attack analyzer is the “brain” on the attack control system. It reads the file /tmp/snortalert, which is generated by RINA on controller node and outputs /tmp/attacker.txt file which has the IP addresses of all the nodes that the Attack Analyzer decides to block based on Snort alerts.

Open a separate window for the Controller, and run the attack analyzer.

cd ~/Control/AttackAnalyzer/

python -f /tmp/snortalert

Note: If you want to re-run this experiment, make sure to remove /tmp/attacker.txt and /tmp/snortalert files on the controller node.

(6) Generate background traffic

  1. We will use the iperf application to generate flows between a source and destination. If iperf is not installed on your nodes, execute

sudo apt-get install iperf

  1. Run iperf server on the destination node:

iperf -u -s

  1. Now we will generate traffic from source s1 to the destination node using iperf and see how it affects the CPU utilization at VNF1 and VNF2 running Snort IDS. Note that if we run multiple instances of iperf, we can generate significant load on the VNF instances. To run iperf client on a source, execute:

iperf -u -c destination -t 5000 &

Note that you can run multiple instances of iperf by running iperf -c destination -t 5000 & multiple times in the s1 node. This flow lasts for 5000 seconds. For this experiment, you may try to run 4-5 iperf instances to generate load of around 50% on each of VNF1 and VNF2. To kill all the flows generated at a node, run killall –v iperf

(Optional) Real Time Graphs

On any Linux machine (including MAC OS), you can draw real-time CPU usage graphs for both VNF1 and VNF2 nodes. A Python script is provided to produce these real-time graphs. The script periodically retrieves the CPU usage file from the Controller node and plots the graph for it.

  1. Download the python script to your laptop using the following link.

  1. Run the script and direct it to the CPU usage files (NFV1.txt and NFV2.txt) present at the controller. To run the Python script, type the following in the folder where you saved the file:

python -n <username>@<controller IP address> -k <Path to your ssh key>

Change <username> to your user name, <controller IP address> to the IP address of the controller and <Path to your ssh key> is the path to your ssh key that you use to log into GENI nodes.

  1. You should see real-time CPU graphs as shown below:
To run the Python script to plot graphs, you need the python plotting library matplotlib. If you do not have this library on your laptop, you can use the following link to download it to your computer:

(7) Generate Intrusion Traffic

  1. We will generate attack traffic from source s2, so only s2 is blocked by the system. In a separate window for source s2, ping the destination:

ping destination

Your ping should reach the destination and it should not be blocked.

  1. Install the port scanner application Nmap on s2

sudo apt-get update

sudo apt-get install nmap

  1. Download the Port Scan attack generator file on s2.


change the file permissions so you can run it

chmod 777

  1. Generate the port scanning attack by typing


The file has the following content

Every 0.2 seconds, the source node generates a ping to the destination node and the output of the ping is saved in ping.log file.

Concurrently with these pings, Nmap is used to attack the destination using port scans.

We will count how many pings will go through before the system detects the port scans and blocks source s2.

  1. As soon as the attack is detected, you will see the IP address of the attacking source s2 appearing on the controller window where the is running. All traffic from this IP address is blocked by the OVS switch as instructed by the Ryu controller. At this point, you can stop the attack generated by by typing Ctrl+C.
  1. We can use the ping output file (ping.log) to measure how long it took to block the attack. Since ping requests are made 0.2 seconds apart, we can count the number of successful pings. To open the ping.log file, type

cat ping.log

Here is a sample output

Here you can see that only the first 13 out of a total of 422 ping requests went through. Since ping requests are made every 0.2 seconds, it took 0.2x13 = 2.6 seconds to detect and block the attacker.

(8) Re-run experiment without load balancer

We will re-run the experiment without the load balancer to see the effects of load balancing. You should detect the attack more quickly using the load balancer. To re-run the experiment, you can keep everything running and just remove the /tmp/attacker.txt and /tmp/snortalert files on the controller node. Now, re-do the attack (by running in Section (7)) without the load balancer.

  1. Stop the PI-controller load balancer that we started in (2) above by pressing Ctrl+C on its terminal window.
  1. Make sure the value of X is equal to 0 in file ~/Control/PI_controller/NFV_ratio_PI.txt . If it is not 0 (zero), open it in the editor and make it 0. This will make sure that none of the traffic is sent to VNF2. To open the file, use

nano ~/Control/PI_controller/NFV_ratio_PI.txt

and change it to X=0

You will need to run the experiment multiple times and take the average of the time taken to block the attack, with and without the load balancer. On average, you should see that using the load balancer helps in quickly detecting and stopping the attack.

Next: Finish

Last modified 18 months ago Last modified on 05/24/19 23:15:39