Intrusion detection system using Suricata over SDN



One switch with three ports, i.e. port 1, port 2, and port 3. Port 3 is a mirror port that can monitor the traffic in port 1 and port 2. The host that connects to the port 3 has a monitor agent (Suricata) running in it. When it detects the nmap activity, the host 3 will send the command via rest api to the switch to block the traffic sent from nmap sender.



1.      Please read first.

2.      Install nmap and Suricata (

Edit the Suricata.yaml

3.      If you are using vmware, please prepare two network interface cards. (Network Adaptor 2 will be moved to the host 3 that can send the rules to the controller).


[mininet script]

#!/usr/bin/env python

from mininet.cli import CLI

from import Mininet

from import Link,TCLink,Intf

from mininet.node import RemoteController


if '__main__' == __name__:

  net = Mininet(link=TCLink)

  h1 = net.addHost('h1')

  h2 = net.addHost('h2')

  h3 = net.addHost('h3')


  s1 = net.addSwitch('s1')

  c0 = net.addController('c0', controller=RemoteController)


  net.addLink(h1, s1)

  net.addLink(h2, s1)

  net.addLink(h3, s1)

  Intf( 'ens38', node=h3 )


  #open a terminal for s1 and type the following commands

  #ovs-vsctl del-port s1-eth3

  #ovs-vsctl add-port s1 s1-eth3 -- --id=@p get port s1-eth3 -- --id=@m create mirror name=m0 select-all=true output-port=@p -- set bridge s1 mirrors=@m









Set the port 3 as a mirror port and delete the Suricata log.


Get the ip for the interface ens38 so that it can talk to the controller.


Start the Suricata.


Open another terminal for h3 and execute the monitor agent.


import time

import os

import urllib2

import json 


def add_flow_entry(dpid,match,priority,actions):

    url = ""

    post_data = "{'dpid':%s,'match':%s,'priority':%s,'actions':%s}" % (dpid,str(match),priority,str(actions))

    req = urllib2.Request(url,post_data)

    res = urllib2.urlopen(req)

    return res.getcode() 


#print add_flow_entry('0000000000000001',{"dl_type":2048,"nw_src":""},100,[{"type":"DROP"}])


file = open('/var/log/suricata/fast.log')



while 1:

  where = file.tell()

  line = file.readline()

  if not line:



    print line,

    print "*"*80

    if "ET SCAN NMAP" in line:

      #print "nmap_scan:",nmap_scan

      #print str(line.split(' ')[18].split(':')[0]) not in nmap_scan

      if str(line.split(' ')[18].split(':')[0]) not in nmap_scan:

          ##print "????",str(line.split(' ')[18].split(':')[0])

          ##set a rule in the openvswitch

          add_flow_entry('0000000000000001',{"dl_type":2048,"nw_src":str(line.split(' ')[18].split(':')[0])},100,[{"type":"DROP"}])

          nmap_scan.append(str(line.split(' ')[18].split(':')[0]))




Open a terminal for h1 that executes the nmap operation (nmap -T4 -A -v

Open another terminal for h3 that execute the monitor agent (check the log in the /var/log/suricata/fast.log and when it detects the “ET SCAN NMAP”. The Agent will get the nmap sender and sends the rule to the controller. (We can see that the ping operations stop when icmp_seq=25).


We can also see that the rule has been added to block the traffic sent from


Dr. Chih-Heng Ke (

Department of Computer Science and Information Engineering,

National Quemoy University, Kinmen, Taiwan.