Nikolay Klender

Extending ESA rules with custom function

Discussion created by Nikolay Klender on Feb 29, 2016
Latest reply on Mar 1, 2016 by Nikolay Klender

ESA engine is based on ESPER library, which is actually so powerful that I propose to read Solution patterns to understand espers capabilities

In this article I show you how to create custom based functions to extend ESA capabilities. We create two functions to count lower and upper letters in string, next we will use them to detect abnormal host names in our network (actually you can use regex but this is just for example).

1) Create simple java class EsperUtils with two public static methods: countUpper and countLower

package NKlendar;

public class EsperUtils {

    public static int countUpper(String input){

        int count = 0;   


            for(int i=0; i< input.length();i++){

                if (Character.isUpperCase(input.charAt(i)))



        }catch (Exception e){}

        return count;


    public static int countLower(String input){

        int count = 0;


            for(int i=0; i< input.length();i++){

                if (Character.isLowerCase(input.charAt(i)))



        }catch (Exception e){}

        return count;



2) Generate jar and call it myUtils.jar and copy it somewhere on esa server, in my case to /opt/uib/lib/myUtils.jar

3) Edit /opt/rsa/esa/conf/wrapper.conf and add parameter pointing to our jar file (do not forget to change numeric part):

3) Edit /opt/rsa/esa/conf/esper-config.xml and add new function description (before <engine-settings> section):

<plugin-singlerow-function name="countUpper" function-class="NKlendar.EsperUtils" function-method="countUpper" />

<plugin-singlerow-function name="countLower" function-class="NKlendar.EsperUtils" function-method="countLower" />

3) restart ESA:

service rsa-esa restart

4) use new function to detect anomaly host names in advanced ESA rules (we analyze count of upper and lower cases letters in source hostname which are in windows login events).




Select window(*) from Event(


    AND alias_host[0] IS NOT NULL

    AND event_cat_name like '%Login%'

    AND (alias_host[0]).length()>=14

   AND countLower(alias_host[0])>=3

   AND countUpper(alias_host[0])>=3

).win:time(1 min)

GROUP BY ip_src

output first every 30 min;

6) monitor mem and cpu usage changes!

5) Extend this idea to detect abnormal dns host names and count entropy of letters


Are you continue to use such ugly regexes to filter private IP:

ip_src REGEXP '(10\.[0-9]{1,3}|172\.(3[01]|2[0-9]|1[6-9])|192\.168)\.[0-9]{1,3}\.[0-9]{1,3}'


ip_dst REGEXP '(10\.[0-9]{1,3}|172\.(3[01]|2[0-9]|1[6-9])|192\.168)\.[0-9]{1,3}\.[0-9]{1,3}'

in my rules I use following approach:




So I created NetUtils class with simple functions and registered it in esper engine:

<plugin-singlerow-function name="isPrivateIP" function-class="NKlendar.NetUtils" function-method="isPrivateIP" />

<plugin-singlerow-function name="isPublicIP" function-class="NKlendar.NetUtils" function-method="isPublicIP" />

<plugin-singlerow-function name="isIPInCIDR" function-class="NKlendar.NetUtils" function-method="isIPInCIDR" />

and registered jar in wrapper.conf


If you like this article or have question or interesting ideas for custom functions please post it.