Large Flow Detection & Mitigation with Openflow | Mininet-Floodlight-Sflow

sflow-rt

Figure 1. Sflow Model Lab

Performance aware software defined networking describes how sFlow and OpenFlow can be combined to create SDN applications such as  DDoS mitigationload balancing large flows, and packet capture. This article takes a deep dive, describing how to build a test bed for developing performance aware SDN applications. The test bed is used to build and test a basic DDoS mitigation application and demonstrate how quickly the controller can adapt the network changing traffic conditions.

Inti atau goal pada lab kali ini adalah untuk membuat SDN Application yang bertujuan untuk mendeteksi sekaligus mem-block DDoS packet ketika masuk ke dalam jaringan kita.

Pada lab ini menggunakan komponen berikut :

  • System Operasi Ubuntu 14.04 64-bit
  • Mininet  2.2.0 : Sebagai virtual node
  • Floodlight : Sebagai openflow controler dan network topology
  • sFlow-RT : Digunakan untuk monitor route atau traffic dalam network
  • Nodejs & Phyton : Bahasa yang akan digunakan untuk aplikasi SDN lab ini

Research Background

Figure 2. sFlow and Openflow Mekanism

Figure 2. sFlow and Openflow Mekanism

  1. switch samples packets
  2. switch mengirimkan header dari sampled packets ke sFlow-RT
  3. sFlow-RT akan menerjemahkan ke bahasa yang lebih terstructur (e.g. tcpflags=SYN, icmptype=3…)
  4. jika packet sudah melewati batas threshold yang sudah di tentukan kemudian akan men-trigger event
  5. events ini nantinya akan di akses external aplikasi melalui REST API

Scheme Design

Figure 2. Application Flowchart

Figure 3. Application Flowchart

ICMP Flood Attack

Mekanism:
Perangkat akan mengirimkan flood ping ke satu server dalam jumlah besarFlow Definition:

ipsource=0.0.0.0/0,
ipdestination=10.0.0.5/32, #h3 dijadikan sbg server target
outputifindex!=discard, #digunakan untuk detect flow yang tidak terblock
ipprotocol=1 #ICMP

Match Field in blocking flow entry:

ether-type, protocol, src-ip, dst-ip

 

Application Development

Sebelum melanjutkan diharapkan sudah menginstall mininet dan floodlight terlebih dahulu. Dan juga pastikan mininet dan floodlight sudah terintegrasi dengan baik.

wget http://www.inmon.com/products/sFlow-RT/sflow-rt.tar.gz
tar -xvzf sflow-rt.tar.g
  1. Jalankan floodlight
    java -jar target/floodlight.jar
  2. Jalankan mininet
    root@randymukti-virtual-machine:/home/randymukti# mn --controller=remote,127.0.0.1,port=6653 --topo=single,3
    
    *** Creating network
    *** Adding controller
    *** Adding hosts:
    h1 h2 h3
    *** Adding switches:
    s1
    *** Adding links:
    (h1, s1) (h2, s1) (h3, s1)
    *** Configuring hosts
    h1 h2 h3
    *** Starting controller
    c0
    *** Starting 1 switches
    s1
    *** Starting CLI:
    mininet>
    mininet> pingall
    *** Ping: testing ping reachability
    h1 -> h2 h3
    h2 -> h1 h3
    h3 -> h1 h2
    *** Results: 0% dropped (6/6 received)
    mininet>

    Pastikan mininet sudah terkomunikasi dengan controller dan juga hasil tes ping 0% dropped artinya semua node bisa saling ping 1 sama lain.

    Dan juga default port disini sudah dirubah menyesuaikan dengan default port floodlight yang saya pakai sekarang merupakan versi terbaru. Kemungkinan jika anda menggunakan floodlight versi lama akan menggunakan port 6633.

    Pastikan pada floodlight web manager node mininet terdaftar dengan benar dengan mengunjungi http://ipserver:8080/ui/pages/topology.html

    Figure 4. Floodlight Web Manager

    Figure 4. Floodlight Web Manager

    Di gambar diatas ada beberapa switch yang sudah saya bikin sebelumnya jadi keliatan banyak, abaikan saja 😀

  3. Konfigurasikan sFlow monitor pada tiap 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

    Itu semisal kalau ada 1 switch saja seperti di lab ini, kalau terdapat lebih dari 1 switch tinggal bikin saja berikutnya semisal switch 2

    sudo ovs-vsctl -- --id=@sflow create sflow agent=eth0  target=\"127.0.0.1:6343\" sampling=10 polling=20 -- -- set bridge s2 sflow=@sflow
  4. Jalankan sFlow-RT
    cd sflow-rt
    ./start.sh

    Untuk memastikan sFlow-RT berfungsi dengan baik bisa mengunjungi http://ipserver:8008/html/index.html

    Figure 5. sFlow Web

    Figure 5. sFlow Web

  5. DDoS Mitigation Aplication
    Berikut ini adalah script yang digunakan untuk detect dan block ddos dijalankan yang saya dapatkan dari http://blog.sflow.com/2013/06/large-flow-detection.html

    var fs = require("fs");
    var http = require('http');
    
    var keys = 'inputifindex,ethernetprotocol,macsource,macdestination,ipprotocol,ipsource,ipdestination';
    var value = 'frames';
    var filter = 'sourcegroup=external&destinationgroup=internal&outputifindex!=discard';
    var thresholdValue = 100;
    var metricName = 'ddos';
    
    // mininet mapping between sFlow ifIndex numbers and switch/port names
    var ifindexToPort = {};
    var nameToPort = {};
    var path = '/sys/devices/virtual/net/';
    var devs = fs.readdirSync(path);
    for(var i = 0; i < devs.length; i++) { var dev = devs[i]; var parts = dev.match(/(.*)-(.*)/); if(!parts) continue; var ifindex = fs.readFileSync(path + dev + '/ifindex'); var port = {"switch":parts[1],"port":dev}; ifindexToPort[parseInt(ifindex).toString()] = port; nameToPort[dev] = port; } var fl = { hostname: 'localhost', port: 8080 }; var groups = {'external':['0.0.0.0/0'],'internal':['10.0.0.2/32']}; var rt = { hostname: 'localhost', port: 8008 }; var flows = {'keys':keys,'value':value,'filter':filter}; var threshold = {'metric':metricName,'value':thresholdValue}; function extend(destination, source) { for (var property in source) { if (source.hasOwnProperty(property)) { destination[property] = source[property]; } } return destination; } function jsonGet(target,path,callback) { var options = extend({method:'GET',path:path},target); var req = http.request(options,function(resp) { var chunks = []; resp.on('data', function(chunk) { chunks.push(chunk); }); resp.on('end', function() { callback(JSON.parse(chunks.join(''))); }); }); req.end(); }; function jsonPut(target,path,value,callback) { var options = extend({method:'PUT',headers:{'content-type':'application/json'} ,path:path},target); var req = http.request(options,function(resp) { var chunks = []; resp.on('data', function(chunk) { chunks.push(chunk); }); resp.on('end', function() { callback(chunks.join('')); }); }); req.write(JSON.stringify(value)); req.end(); }; function jsonPost(target,path,value,callback) { var options = extend({method:'POST',headers:{'content-type':'application/json'},"path":path},target); var req = http.request(options,function(resp) { var chunks = []; resp.on('data', function(chunk) { chunks.push(chunk); }); resp.on('end', function() { callback(chunks.join('')); }); }); req.write(JSON.stringify(value)); req.end(); } function lookupOpenFlowPort(agent,ifIndex) { return ifindexToPort[ifIndex]; } function blockFlow(agent,dataSource,topKey) { var parts = topKey.split(','); var port = lookupOpenFlowPort(agent,parts[0]); if(!port || !port.dpid) return; var message = {"switch":port.dpid, "name":"dos-1", "ingress-port":port.portNumber.toString, "ether-type":parts[1], "protocol":parts[4], "src-ip":parts[5], "dst-ip":parts[6], "priority":"32767", "active":"true"}; console.log("message=" + JSON.stringify(message)); jsonPost(fl,'/wm/staticflowentrypusher/json',message, function(response) { console.log("result=" + JSON.stringify(response)); }); } function getTopFlows(event) { jsonGet(rt,'/metric/' + event.agent + '/' + event.dataSource + '.' + event.metric + '/json', function(metrics) { if(metrics && metrics.length == 1) { var metric = metrics[0]; if(metric.metricValue > thresholdValue
               && metric.topKeys
               && metric.topKeys.length > 0) {
                var topKey = metric.topKeys[0].key;
                blockFlow(event.agent,event.dataSource,topKey);
            }
          }
        }
      );  
    }
    
    function getEvents(id) {
      jsonGet(rt,'/events/json?maxEvents=10&timeout=60&eventID='+ id,
        function(events) {
          var nextID = id;
          if(events.length > 0) {
            nextID = events[0].eventID;
            events.reverse();
            for(var i = 0; i < events.length; i++) {
              if(metricName == events[i].thresholdID) getTopFlows(events[i]);
            }
          }
          getEvents(nextID);  
        }
      );
    }
    
    // use port names to link dpid and port numbers from Floodlight
    function getSwitches() {
      jsonGet(fl,'/wm/core/controller/summary/json',
        function(switches) { 
          for(var i = 0; i < switches.length; i++) {
            var sw = switches[i];
            var ports = sw.ports;
            for(var j = 0; j < ports.length; j++) {
              var port = nameToPort[ports[j].name];
              if(port) {
                port.dpid = sw.dpid;
                port.portNumber = ports[j].portNumber;
              }
            }
          }
          setGroup();
        }
      );
    }
    
    function setGroup() {
      jsonPut(rt,'/group/json',
        groups,
        function() { setFlows(); }
      );
    }
    
    function setFlows() {
      jsonPut(rt,'/flow/' + metricName + '/json',
        flows,
        function() { setThreshold(); }
      );
    }
    
    function setThreshold() {
      jsonPut(rt,'/threshold/' + metricName + '/json',
        threshold,
        function() { getEvents(-1); }
      ); 
    }
    
    function initialize() {
      getSwitches();
    }
    
    initialize();
    

Test & Evaluation

a) Without mitigation
h1 ICMP attack ke h3 dengan : h1 ping h3 -f

Figure 6. ICMP Attack

Figure 6. ICMP Attack

network traffic flow

Figure 7. Normal Network Flow

Figure 7. Normal Network Flow

b) With mitigation
Kemudian jalankan ddos script tadi

Figure 8. Aktivate ddos protection

Figure 8. Aktivate ddos protection

sdn8

Figure 9. Packet exceeds threshold

Setelah script dijalankan, kemudian attack ping lagi dan traffic flow berubah.

Note :
Script mitigati diatas tidak akan berhenti meski attack sudah di stop, perlu command dibawah supaya hilang.

curl http://localhost:8080/wm/staticflowentrypusher/clear/all/json

Sumber :

2 thoughts on “Large Flow Detection & Mitigation with Openflow | Mininet-Floodlight-Sflow

  1. fepi says:

    assalamualaikum.wr.wb mas.
    mas saya coba nerapin sdn pakai controller floodlight kok mininetnya ga bisa conect ya? selalu X terus host di mininet kalo pingall. sedangkan kalo saya coba pake controller opendaylight, mininetnya bisa conect mas, topologi ny tampil.
    terus saya coba script nodejs untuk mitigation ddos kok selalu error ya? gimana sih mas cara jalanin script js tersebut? 😦 mohon pencerahannya mas. terima kasih.
    wassalamualaikum.wr.wb

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.