Mikrotik IPS IDS

From MikroTik Wiki
Revision as of 00:38, 16 February 2014 by Paxy (talk | contribs) (IPS Solution)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Regarding a Forum post by "slech", [1] you can enable Mikrotik Router to work with Snort [2] IDS system.

Snort already has developed Subscribed and Free service for attack signature update and mechanism for attack detection and alerting.

As Tap of main Internet line is not ideal solution for some cases, like with redundant routers connected with VRRP, it is great to have solution based only on Mikrotik Sniffing Stream.

IDS Solution

To install IDS Snort solution, you need computer running Linux OS. Download and install Snort following OS Specific manual, or compile it from source if there is no binary for your OS. Snort Installation Procedures ([3]) After full installation, follow configuration parameters to setup Snort. Subscribe to Snort site, to get latest Regular User rules with attack signatures and set them like in manual.

To setup Mikrotik, you need to install Calea package and opet Sniffing Tool. Set Sniffer to listed all Interfaces, and uncheck Only Headers box. Open Streaming tab, and enter IP address of Linux server, check Streaming Enabled, and uncheck Filter Stream. Start your sniffing.


At this point Mikrotik will start to stream any passing packet via Tazmen Sniffer Protocol (TZSP) to specified Streaming Server. Unfortunately, we can not just start Snort on Sniffing mode and collect packets as this streamed packets are encapsulated in TZSP protocol. Packets needs to be de-encapsulated via Mikrotik tool Traft. Download Traft.

wget http://www.mikrotik.com/download/trafr.tgz

Traft receives packet via default UDP port 37008 and you should let it pass on iptable if there is blocking rules.

After unpacking Traft, you should be able to test receiving packets by command:

./trafr -s | tcpdump -r - -n

If you see packet dump by tcpdump it means that MT sends packets, and tcpdump use them de-encapsulated from TZSP correctly.

Next step is to active Snort with Traft with command:

./trafr -s | snort -r -

If you get messages that confirm settings and rules loaded successfully wait few moments and then stop process with Control+C. If statistics shows numbers different then 0, it means that Snort works with Traft just right.

Snort has to be started as process that can not be demonized because of Traft data injection. That means you have to run it directly on console or use tool like "screen".

For my configuration, I have created script to call Snort following way:

trafr -s | snort -c /etc/snort/snort.conf -l /var/log/snort/ -r -

It instruct Snort to use specified configuration and log path.

IPS Solution

Snort has built in IPS (inline) solution but only for case where it is middle device (device between router and internet). At this scenario IDS is dedicated device that just receive and process sniffed data from different MT router. As first step, we should enable logging of IDS alerts at Syslog by removing comment form configuration fail snort.conf at line output alert_syslog: LOG_AUTH LOG_ALERT

That way after any alert, new syslog line will appear.

For Mirkotik IPS solution we should have way to react on different alert and for some alerts create role that block specific malicious traffic. There are different solutions, but none of them support Mikrotik platform. To resolve this issue, I have created few scripts:

On Mikrotik side: Create Script with following code:

:global ip

local time ([/system clock get time]+("00:05:00"))
if ($time > "23:59:59") do={
  :local time "00:05:00"


/ip firewall address-list add list=blacklist address=$ip comment=$time

This script adds some IP, specified by global variable ip, to address list in firewall. Next is to add filter rule that drop or even reject access to address from list blacklist.

/ip firewall filter add src-address-list=blacklist action=reject

Following that you need to create way to automatically remove blocked IP after 5 minutes by adding new Scheduler that is run every minute with next script on it:

:local currentTime [/system clock get time]

foreach i in=[/ip firewall address-list find list=blacklist] do={
:local comment [/ip firewall address-list get $i comment] 
:local ip [/ip firewall address-list get $i address] 
  :if ( $comment < $currentTime ) do={ 
      /ip firewall address-list remove [find address=$ip]


Scheduler, every minute check is there any address in address list that in comment has time passed current time, and deletes this IP. After that, you should create user for ex. ips with some password and restriction to log only from Linux server IP.

/user add name=ips password=1231 address=

Also make sure that you have enabled SSH service for IP of Linux Server.

On IDS side: It is developed small PHP script that check syslog every minute, and if it finds "Priority 1" alert it connect to MT via SSH and active filter script for alerts source IP address. PHP source is following:



exec('cat /var/log/messages | grep "`date -d "-1 minute" "+%b %e %H:%M"`"',$lastMin); foreach($lastMin as $line) {

       if (strpos($line,"Priority: 1")!==FALSE || strpos($line,"portscan")!==FALSE)
                       preg_match("/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/", $line, $matches);
                       if (!in_array($filter, $blocked))
                               if (strpos($filter,"192.168.")!==FALSE) continue; //Protected space
                               sendMikrotik('', 'ips', 'pass',$filter);   // Mikrotik 1
                               sendMikrotik('', 'ips', 'pass',$filter); // Mikrotik 2
                               sendMikrotik('', 'ips', 'pass',$filter); // Mikrotik 3

} function sendMikrotik($mt,$user,$pass,$filter) { $connection = ssh2_connect($mt); ssh2_auth_password($connection,$user,$pass); sleep(1); $stream = ssh2_exec($connection, ':global ip '.$filter); $stream = ssh2_exec($connection, '/system script run filter'); $stream = ssh2_exec($connection, 'quit'); }

PHP script ignores Alerts originate from 192.168. network and react only on alerts Priority 1 and portscan. When new alert is detected, script parse IP addresses and sends via SSH commands to Mikrotik to activate created filter script and block attacker IP address for 5 minutes. In this example, we had more then one Mikrotik ruter that apply same filtering.

Only thing left is to add Cron job to run PHP script every minute so it can process every minute syslog.

* * * * * php /root/ips.php