NetEye Security Layer

Contents

NetEye Security Layer

Overview

NetEye Security Layer,also called NS Layer for short, is a framework which is used to arrange and organize the security modules. NS Layer is newly added in SEnginx.
In nginx, NS Layer creates a new phase to handle http request packets, a header filter and a body filter to handle http response packets. Each security module can register its own callback handlers into NS Layer as needed.
NS Layer provides a mechanism used to control the calling sequence of the security modules. For example, you can ask NS Layer to run module 1 first, then jump to module 3 and run it.
NS Layer also provides the mechanism to handle security module's actions together. For instance, all security modules based on NS Layer, when they have inspected an attack behavior, can call NS Layer's action handling API to perform a block action.

How to write a security module by using NS Layer

API Reference

#include <ngx_http_neteye_security.h>
 
 
ngx_int_t ngx_http_neteye_security_request_register(ngx_int_t id, ngx_http_neteye_security_request_pt handler);
 
Description:  Register a request callback hander into NS Layer. The callback handler will be triggered in "NetEye Security Phase"
Parameters:   id: current module's module id in NS Layer
              handler: current module's request callback handler
Return Value: NGX_OK on success,NGX_ERROR on failure
 
 
ngx_int_t ngx_http_neteye_security_header_register(ngx_int_t id, ngx_http_neteye_security_response_header_pt handler);
 
Description:  Register a header callback hander into NS Layer. The callback handler will be triggered in "NetEye Security header filter"
Parameters:   id: current module's module id in NS Layer
              handler: current module's response header filter callback handler
Return Value: NGX_OK on success,NGX_ERROR on failure
 
 
ngx_int_t ngx_http_neteye_security_body_register(ngx_int_t id, ngx_http_neteye_security_response_body_pt handler);
Description:  Register a body callback hander into NS Layer. The callback handler will be triggered in "NetEye Security body filter"
Parameters:   id: current module's module id in NS Layer
              handler: current module's response body filter callback handler
Return Value: NGX_OK on success,NGX_ERROR on failure
 
 
ngx_int_t ngx_http_ns_do_action(ngx_http_request_t *r, ngx_http_ns_action_t *action);
 
Description:  This function handles the actions of NS Layer based security modules. Filling in the action structure and call this function to tell NS Layer to perform the actions.
Parameters:   r: ngx_http_request_t of current request
              action: a structure defined in ngx_http_neteye_security.h
Return Value: NGX_OK when the request is passed,NGX_ERROR when the request is blocked
 
 
ngx_int_t ngx_http_neteye_security_ctx_register(ngx_int_t id, ngx_http_neteye_security_ctx_pt handler);
 
Description:  Register a ctx callback hander into NS Layer
Parameters:   id: current module's module id in NS Layer
              handler: current module's ctx callback handler
Return Value: NGX_OK on success,NGX_ERROR on failure
 
 
void ngx_http_ns_jump_bit_set(ngx_http_request_t *r, ngx_uint_t mod);
void ngx_http_ns_jump_bit_clr(ngx_http_request_t *r, ngx_uint_t mod);
void ngx_http_ns_jump_bit_clr_all(ngx_http_request_t *r);
ngx_uint_t ngx_http_ns_jump_bit_is_set(ngx_http_request_t *r, ngx_uint_t mod);
void ngx_http_ns_jump_bit_set_all(ngx_http_request_t *r);
ngx_uint_t ngx_http_ns_jump_bit_is_set_any(ngx_http_request_t *r);
void ngx_http_ns_set_bypass_all(ngx_http_request_t *r);
void ngx_http_ns_clr_bypass_all(ngx_http_request_t *r);
ngx_uint_t ngx_http_ns_test_bypass_all(ngx_http_request_t *r);
 
Description:  Above APIs are used to adjust the calling sequence of NS Layer based security modules
Parameters:   r: ngx_http_request_t of current request
              mod: current module's module id in NS Layer
Return Value: NGX_OK on success,NGX_ERROR on failure

Example

Now we use robot mitigation module as an example to see how to write a NS Layer based module.

1) Register module's information into NS Layer

First,add the new module's id into 3rd_party/ngx_http_neteye_security/ngx_http_neteye_security.h, in detail, you need to add new entry in the following enum variable:
enum ngx_http_neteye_security_module_ids {
    NGX_HTTP_NETEYE_SECURITY_MODULE_START = 0,
 
    NGX_HTTP_NETEYE_WHITELIST,
    NGX_HTTP_NETEYE_FRIENDLY_BOTSLIST,
    NGX_HTTP_NETEYE_SESSION,
    NGX_HTTP_NETEYE_DYNWHITELIST,
    NGX_HTTP_NETEYE_ROBOT_MITIGATION,
    NGX_HTTP_NETEYE_GOOGLE_RECAPTCHA,
    NGX_HTTP_NETEYE_LOCAL_CAPTCHA,
    NGX_HTTP_NETEYE_COOKIE_POISON,
    NGX_HTTP_NETEYE_PAGE_ACL,
    NGX_HTTP_NETEYE_NAXSI,
    NGX_HTTP_NETEYE_IPS,
    NGX_HTTP_NETEYE_STATUS_PAGE,
    NGX_HTTP_NETEYE_LOG_MODULE,
 
    NGX_HTTP_NETEYE_SECURITY_MODULE_MAX
};
For instance, add NGX_HTTP_NETEYE_ROBOT_MITIGATION into this enum variable.
Then define the new module in 3rd_party/ngx_http_neteye_security/ngx_http_neteye_security.c
/*XXX: do not insert gap among the rank values */
static ngx_http_neteye_security_module_t ngx_http_neteye_security_modules[] = {
    {NGX_HTTP_NETEYE_WHITELIST,
        "Permanent IP Whitelist", NULL, NULL, NULL, 1, 0, 0, NULL},
    {NGX_HTTP_NETEYE_SESSION,
        "Session Mechanism", NULL, NULL, NULL,      2, 1, 0, NULL},
    {NGX_HTTP_NETEYE_DYNWHITELIST,
        "Dynamic White list", NULL, NULL,NULL,      3, 0, 0, NULL},
    {NGX_HTTP_NETEYE_FRIENDLY_BOTSLIST,
        "Friendly Bots list", NULL, NULL, NULL,     4, 0, 0, NULL},
    {NGX_HTTP_NETEYE_ROBOT_MITIGATION,
        "Active/Challenge", NULL, NULL, NULL,       5, 0, 0, NULL},
    {NGX_HTTP_NETEYE_GOOGLE_RECAPTCHA,
        "Google Recaptcha", NULL, NULL, NULL,       6, 0, 0, NULL},
    {NGX_HTTP_NETEYE_LOCAL_CAPTCHA,
        "Local Captcha", NULL, NULL, NULL,          7, 0, 0, NULL},
    {NGX_HTTP_NETEYE_COOKIE_POISON,
        "Cookie Poison", NULL, NULL, NULL,          8, 3, 0, NULL},
    {NGX_HTTP_NETEYE_PAGE_ACL,
        "Page Access Control", NULL, NULL, NULL,    9, 0, 0, NULL},
    {NGX_HTTP_NETEYE_NAXSI,
        "NetEye modified NAXSI", NULL, NULL, NULL,    10, 0, 0, NULL},
    {NGX_HTTP_NETEYE_IPS,
        "NetEye IPS Module", NULL, NULL, NULL,      0, 2, 1, NULL},
    {NGX_HTTP_NETEYE_STATUS_PAGE,
        "Status Page", NULL, NULL, NULL,            0, 4, 0, NULL},
    {NGX_HTTP_NETEYE_LOG_MODULE,
        "NetEye Log", NULL, NULL, NULL,             0, 0, 0, NULL},
};
Add a new line in the array, the new line consists of the following columns:
  1. Module ID, which is defined above
  2. Nodule name, a string to describe the module
  3. Three callback pointer, leave them as blank, because they should be registered at the module initializing phase.
  4. The following 3 columns are the rank of calling sequence for request, header filter and body filter callback handlers of this module. If the module doesn't have a corresponding handler, set it to 0
  5. The last column is the handler of session ctx, leave it as blank, this handler is also registered at the module initializing phase
For instance, robot mitigation module defines its NS Layer based module as the following:
{NGX_HTTP_NETEYE_ROBOT_MITIGATION, "Active/Challenge", NULL, NULL, NULL, 5, 0, 0, NULL},
This means the module only has a request callback handler, the calling sequence's rank is 5

2) After inserted module definition information in above files, you can registered the callback handlers in your module's postconfiguration function:

define postconfiguration function in nginx's module structure:
static ngx_http_module_t                                                                                                
ngx_http_robot_mitigation_module_ctx = {                                                                                
    NULL,                                    /* preconfiguration */                                                    
    ngx_http_rm_init,                        /* postconfiguration */                                                   
                                                                                                                         
    NULL,                                    /* create main configuration */                                           
    NULL,                                    /* init main configuration */                                             
                                                                                                                         
    NULL,                                    /* create server configuration */                                         
    NULL,                                    /* merge server configuration */                                          
                                                                                                                         
    ngx_http_rm_create_loc_conf,             /* create location configuration */                                       
    ngx_http_rm_merge_loc_conf,              /* merge location configuration */                                        
};
then register the corresponding NS Layer callback handlers in the postconfiguration function:
static ngx_int_t ngx_http_rm_init(ngx_conf_t *cf)
{
    ngx_int_t ret;
    ret = ngx_http_neteye_security_ctx_register(NGX_HTTP_NETEYE_ROBOT_MITIGATION,
            ngx_http_rm_request_ctx_init);
    if (ret != NGX_OK) {
        return ret;
    }
    /* we only need a request handler for this feature */
    return ngx_http_neteye_security_request_register(
            NGX_HTTP_NETEYE_ROBOT_MITIGATION,
            ngx_http_rm_request_handler);
}

3) Finally you can implement other functions of your module. The module must follow the rule of creating a new nginx module, but don't register your module as a http filter module in nginx, NS Layer will ensure your callback handlers will be triggered in correct hook point. The following is the config file of robot mitigation module:

ngx_addon_name=ngx_http_robot_mitigation_module
CORE_INCS="$CORE_INCS $ngx_addon_dir"
CORE_DEPS="$CORE_DEPS $ngx_addon_dir/ngx_http_robot_mitigation.h"
HTTP_MODULES="$HTTP_MODULES ngx_http_robot_mitigation_module"
NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_robot_mitigation.c $ngx_addon_dir/ngx_http_robot_mitigation_tpl.c"
have=NGX_HTTP_ROBOT_MITIGATION_MODULE . auto/have