Monday, January 6, 2014

OpenDaylight

This article looks takes the DDoS example and repeats it using the OpenDaylight controller.

First install Open Daylight in the Mininet testbed.
$ wget https://jenkins.opendaylight.org/controller/job/controller-merge/lastSuccessfulBuild/artifact/opendaylight/distribution/opendaylight/target/distribution.opendaylight-osgipackage.zip
unzip distribution.opendaylight-osgipackage.zip
Next start Mininet.
sudo mn --topo single,3 --controller=remote,ip=127.0.0.1
Enable sFlow on the switch:
sudo ovs-vsctl -- --id=@sflow create sflow agent=eth0  target=\"127.0.0.1:6343\" sampling=10 polling=20 -- -- set bridge s1 sflow=@sflow
Start OpenDaylight.
cd opendaylight
./run.sh
Confirm that the controller is running and has discovered the switch by connecting a browser to port 8080 on the testbed - the screen shot at the start of the article shows the OpenDaylight Devices tab with the switch 00:00:00:00:00:00:00:01 shown in the Nodes Learned list and in the map (the default credentials to log into the OpenDaylight interface are User:admin, Password:admin).

The following sFlow-RT script modified the original to use the OpenDaylight Flow Programmer REST API to push OpenFlow rules to the switch.
include('extras/json2.js');

var flowkeys = 'ipsource';
var value = 'frames';
var filter = 'outputifindex!=discard&direction=ingress&sourcegroup=external';
var threshold = 1000;
var groups = {'external':['0.0.0.0/0'],'internal':['10.0.0.2/32']};

var metricName = 'ddos';
var controls = {};
var enabled = true;
var blockSeconds = 20;
var ruleid = 0;

var flowprogrammer = 'http://127.0.0.1:8080/controller/nb/v2/flowprogrammer/default/node/OF/';
var user = 'admin';
var password = 'admin';
var bridge = '00:00:00:00:00:00:00:01';

function setOpenFlow(bridge,name,spec) {
  http(flowprogrammer+bridge+'/staticFlow/'+name,'put','application/json',
       JSON.stringify(spec),user,password);
}

function deleteOpenFlow(bridge,name) {
  http(flowprogrammer+bridge+'/staticFlow/'+name,'delete','application/json',
       null,user,password);
}

function block(address) {
  if(!controls[address]) {
     var name = 'block' + ruleid++;
     setOpenFlow(bridge,name,{installInHw:true,name:name, 
                 node:{id:bridge, type:'OF'},
                 priority:'11', etherType:'0x0800', 
                 nwSrc: address, actions:['DROP']});
     controls[address] = { name: name, action:'block', 
                           time: (new Date()).getTime() };
  }
}

function allow(address) {
  if(controls[address]) {
     deleteOpenFlow(bridge,controls[address].name);
     delete controls[address];
  }
}

setEventHandler(function(evt) {
  if(!enabled) return;

  var addr = evt.flowKey;
  block(addr);  
},[metricName]);

setIntervalHandler(function() {
  // remove stale controls
  var stale = [];
  var now = (new Date()).getTime();
  var threshMs = 1000 * blockSeconds;
  for(var addr in controls) {
    if((now - controls[addr].time) > threshMs) stale.push(addr);
  }
  for(var i = 0; i < stale.length; i++) allow(stale[i]);
},10);

setHttpHandler(function(request) {
  var result = {};
  try {
    var action = '' + request.query.action;
    switch(action) {
    case 'block':
       var address = request.query.address[0];
       if(address) block(address);
        break;
    case 'allow':
       var address = request.query.address[0];
       if(address) allow(address);
       break;
    case 'enable':
      enabled = true;
      break;
    case 'disable':
      enabled = false;
      break;
    }
  }
  catch(e) { result.error = e.message }
  result.controls = controls;
  result.enabled = enabled;
  return JSON.stringify(result);
});

setGroups(groups);
setFlow(metricName,{keys:flowkeys,value:value,filter:filter});
setThreshold(metricName,{metric:metricName,value:threshold,byFlow:true,timeout:5});
The following command line argument loads the script on startup:
-D file.script=odl.js
Repeating the simulated denial of service attack without the controller active and with the controller active shows the same results demonstrated in the previous article:
When the controller is disabled, the attack traffic exceeds 6,000 packets per second and persists until the attacker stops sending. When the controller is enabled, traffic is stopped the instant it hits the 1,000 packet per second threshold in the application. The control is removed 20 seconds later and re-triggers if the attacker is still sending traffic.

DDoS mitigation is only one use case for large flow control, others described on this blog include: ECMP / LAG load balancing, traffic marking and packet capture. This script can be modified to address these different use cases. The Mininet test bed provides a useful way to test OpenFlow control schemes before moving them into production using physical switches.

34 comments:

  1. Hello, i want to run the same example with Helium, what are the changes in the above script, in order to be compatible with Helium?

    e.g. --> 1) var flowprogrammer = 'http://127.0.0.1:8181/controller/nb/v2/flowprogrammer/default/node/OF/'; ???

    2) var bridge = 'openflow:1'; ???

    thanks in advance!

    ReplyDelete
    Replies
    1. How do you solve this problem,my opendaylight is boron,but the api is different to helium

      Delete
  2. Hello,

    I'd like to use sFlow to monitor my mininet network (custom topology). I use the OpenDaylight controller. I tried to run the command to enable sFlow in the mininet CLI, but I get the following error:

    ovs-vsctl: no row "127.0.0.1" in table Bridge

    Do you know why I'm getting this message?

    Thanks!
    Toni.

    ReplyDelete
    Replies
    1. Try running the command in a different terminal (not in the mininet CLI). Also, take a look at the sFlow-RT extras/leafandspine.py script. There is configSFlow function that you could modify and incorporate in the script that builds your custom topology.

      Delete
  3. Hello peter,

    i want build a virtual data centre with openstack, can i implement this method to openstack? Then how to deploy or install or enable sflow in openstack environment?

    thanks peter


    regret
    ryanda

    ReplyDelete
    Replies
    1. You should be able to implement this technique as part of an OpenStack deployment, provided that you were using Open vSwitch, but I haven't tried it, so I can't help with the implementation details.

      Delete
  4. Hello Peter,

    when i run the sflow-rt, i get this message :

    2015-09-10T20:49:48-0400 INFO: Listening, sFlow port 6343
    2015-09-10T20:49:48-0400 INFO: Starting the Jetty [HTTP/1.1] server on port 8008
    2015-09-10T20:49:48-0400 INFO: Starting com.sflow.rt.rest.SFlowApplication application
    2015-09-10T20:49:48-0400 INFO: Listening, http://localhost:8008
    2015-09-10T20:49:48-0400 INFO: odl.js started
    2015-09-10T20:49:48-0400 WARNING: bad group name [object Object]
    Is that message is fine?
    and when i move to web UI i cannot see DDOS in metric? why it happened?

    Thanks Peter

    Regards,
    Ryanda

    ReplyDelete
    Replies
    1. The syntax for defining groups and including them in flow definitions has changed:
      var filter = 'outputifindex!=discard&direction=ingress&group:ipsource:ddos=external';
      ...
      setGroups('ddos',groups);

      Delete
    2. Hi Peters,

      why the flow not shown in the opendaylight gui?

      Thanks Peter


      Regards,
      Ryanda

      Delete
  5. Hi Peter,

    Is there a version of the Javascript that works on newer versions of OpenDayLight running RESTCONF Northbound APIs?

    Many thanks,
    Silvio

    ReplyDelete
    Replies
    1. I don't know if anyone has updated this script to use the latest OpenDaylight RESTCONF APIs. You might try asking the questions on the sFlow-RT mailing list at sflow-rt.com.

      Delete
  6. it doesn't work in the slow-rt 2.0-r1201?

    ReplyDelete
    Replies
    1. sFlow-RT doesn't natively integrate with OpenDaylight. Instead is has a generic http() function that can be used in scripts to interact with OpenDaylight's REST API. You need to modify the script in this example to work with the latest version of the the OpenDaylight REST API.

      Delete
  7. only the large flow can judge the ddos attack?

    ReplyDelete
    Replies
    1. This example is intended to mitigate volumetric DDoS attacks and focuses on large flows. A different controller could target anomalous traffic, e.g. Blacklists

      Delete
  8. Hi There,

    Your articles are great! I've learnt a lot reading them. However, I'm a bit stuck adding the script. When run the script (in a separate MN cli session) I receive these errors:

    ./extras/ODL.js: line 2: var: command not found
    ./extras/ODL.js: line 3: var: command not found
    ./extras/ODL.js: line 4: var: command not found
    etc..
    ./extras/ODL.js: line 19: syntax error near unexpected token 'bridge,name,spec'
    ./extras/ODL.js: line 19: 'function setOpenFlow(bridge,name,spec) {'

    I don't suppose you know what these errors may mean?

    P.s. Where do I run this command? -D file.script=ODL.js

    Thanks!

    ReplyDelete
    Replies
    1. This is a very old article. The OpenDaylight REST API has changed and the syntax of some of the JavaScript function in sFlow-RT have changed. You can get the latest documentation at sFlow-RT.com. Some of the changes are described in the comments to this article.

      System Properties describes how to set properties, for example you might run the command:

      env "RTPROP=-Dscript.file=ODL.js" ./start.sh

      The best place to get sFlow-RT support is on the sFlow-RT forum.

      Delete
  9. hi Peter ,
    thank you for a useful explanation. what I'm looking exactly is how to launch DDoS attack and mitigate this attack on SDN by using Opendaylight controller. could you please write. e the steps with the commands.
    thanks

    ReplyDelete
    Replies
    1. I haven't used OpenDaylight since this article was published. However, you might want to take a look at ONOS measurement based control. You should be able to adapt the example to use OpenDaylight's REST API.

      Delete
  10. -D file.script=odl.js What does this line mean and where to run it?since we tried running it showing unknown file

    ReplyDelete
    Replies
    1. The file path is relative to the sflow-rt home directory, so you need to copy odl.js into the sflow-rt directory. Also the correct argument for the latest version of sFlow-RT is -Dscript.file=odl.js. Alternatively, you could specify the absolute path to the script.

      Note the other comments on this article. The information is outdated and will not work with the current versions of ODL and sFlow-RT.

      Delete
  11. is there any site or can you provide us with the latest script and info.

    ReplyDelete
    Replies
    1. The latest information on sFlow-RT is on the the sFlow-RT.com web site. It shouldn't be hard to modify one of the more recent examples on this blog to work with the latest OpenDaylight REST API.

      If you get stuck, you might try posting your questions to the sFlow-RT community and/or to the OpenDaylight mailing list.

      Delete
    2. Sir can you give me a full link of latest script of opendaylight.i did not found it.. please help..
      Thanks alot..

      Delete
  12. hello peter, i just have one more doubt that how can we run a script on any controller/ i.e C0. any reference you can provide.

    ReplyDelete
    Replies
    1. Ryu measurement based control and ONOS measurement based control are recent examples using RYU and ONOS respectively.

      I don't have any recent OpenDaylight examples, but it should be relatively straightforward to adapt one of these examples to use the OpenDaylight REST API.

      Delete
  13. Hi Peter,

    do you have any recent example to carry attack on Opendaylight controller and get the stats on Sflow-RT ?

    ReplyDelete
    Replies
    1. I don't have any recent examples with OpenDaylight. I don't believe the latest versions of OpenDaylight support OpenFlow so this example won't work.

      Delete
    2. do you have any working example for ddos attack on opendaylight controller which makes it unavailable. ?

      Delete
    3. PLease help me with working example of DDOS attack on opendaylight controller in mininet. i can use any version but it should be on ODL.

      Delete
    4. The first challenge is to find a version of OpenDaylight that works with Mininet. Once you have done that, a script similar to the one in this article should work.

      Ryu measurement based control is a more recent example using the Ryu controller. Ryu is a lot easier to use than OpenDaylight and works well with Mininet.

      Delete
  14. DO you know any one who made projects as a freelance ... i am in dire need .... I will pay them as well ?

    ReplyDelete