HTTP Session模块

来自SEnginx
跳转至: 导航, 搜索

目录

HTTP Session模块

概要

Session模块提供了对HTTP请求的跟踪功能,其他的一些安全模块会依赖于此模块进行一些处理。
Session会在客户端的浏览器设置一个Cookie用于记录会话信息。
目前依赖于session功能的模块有:

  • Cookie防篡改

命令

session

语法 session on/off
默认值 off
上下文 Server

开启或关闭session功能。

举例:

session on;


session_timeout

语法 session_timeout timeout
默认值 60
上下文 Server

设置session的超时时间,单位是秒。

举例:

session_timeout 600;


session_max_size

语法 session_max_size number
默认值
上下文 HTTP

设定session的最大数量;

举例:

session_max_size 10000;

session_cookie_name

语法 session_cookie_name name
默认值 SENGINX-SESSION-ID
上下文 HTTP/Server/Location

设置session cookie的名称;

举例:

session_cookie_name session-id;

session_blacklist_timeout

语法 session_blacklist_timeout timeout
默认值 session_timeout值
上下文 HTTP/Server/Location

设置基于session的黑名单的超时时间,单位是秒,此时间不能小于session timeout的数值。

举例:

session_blacklist_timeout 600;

session_redirect_timeout

语法 session_redirect_timeout timeout
默认值 5
上下文 HTTP/Server/Location

设置SEnginx发送redirect响应后的等待时间,单位是秒。

举例:

session_redirect_timeout 600;

session_show

语法 session_show on/off
默认值 off
上下文 Location

显示当前所有的session信息;此location所在的server必须开启session功能。
可以使用浏览器直接访问这个location以查看session信息。
举例:

location /show_session {
      session_show on;
}

使用Session API开发模块

session模块提供了一组函数,用于其他依赖于session的模块使用。session本质上是一个数据的存储点,其他模块可以将一些数据存储到session节点上,然后在本模块处理request的时候对这些数据进行操作,主要的API如下表所示:

void * ngx_http_session_shm_alloc(size_t size);
 
void ngx_http_session_shm_free(void *);
 
void * ngx_http_session_shm_alloc_nolock(size_t size);
 
void ngx_http_session_shm_free_nolock(void *);
 
ngx_http_session_ctx_t * ngx_http_session_create_ctx(ngx_http_session_t *session, u_char *name, ngx_int_t (*init)(void *ctx), void (*destroy)(void *data));
 
ngx_http_session_ctx_t * ngx_http_session_find_ctx(ngx_http_session_t *session, u_char *name);
 
void ngx_http_session_destroy_ctx(ngx_http_session_t *session, u_char *name);
 
ngx_http_session_t * ngx_http_session_get(ngx_http_request_t *r);
 
void ngx_http_session_put(ngx_http_request_t *r);
 
ngx_int_t ngx_http_session_is_enabled(ngx_http_request_t *r);

void ngx_http_session_register_create_ctx_handler(ngx_http_session_create_ctx_t handler);

现举例说明这些API的用法

注册创建ctx的回调函数

首先要在模块的初始化阶段向session模块注册创建ctx的回调函数, 此回调函数会被在一个新session建立的时候调用,用于创建ctx. 例如,在cookie poisoning模块中,需要先注册ctx的回调函数

static ngx_int_t                                                                                                         
ngx_http_cp_filter_init(ngx_conf_t *cf)                                                                                  
{                                                                                                                        
    ngx_int_t ret;                                                                                                       
                                                                                                                         
    ret = ngx_http_neteye_security_header_register(                                                                      
            NGX_HTTP_NETEYE_COOKIE_POISONING, ngx_http_cp_header_handler);                                               
                                                                                                                         
    if (ret == NGX_ERROR) {                                                                                              
        return NGX_ERROR;                                                                                                
    }                                                                                                                    
                                                                                                                         
    ngx_http_session_register_create_ctx_handler(                                                                        
            ngx_http_cp_create_session_ctx);                                                                             
                                                                                                                         
    return ngx_http_neteye_security_request_register(                                                                    
            NGX_HTTP_NETEYE_COOKIE_POISONING, ngx_http_cp_handler);                                                      
}  

其中,ngx_http_cp_create_session_ctx的典型实现为:

static void
ngx_http_cp_create_session_ctx(ngx_http_session_t *session)
{
    ngx_http_session_ctx_t           *session_ctx;
    ngx_http_cp_session_ctx_t        *cp_ctx;

    session_ctx = ngx_http_session_create_ctx(session,
            (u_char *)"cookie_poisoning",
            ngx_http_cp_init_session_ctx_handler,
            ngx_http_cp_destroy_session_ctx_handler);
    if (!session_ctx) {
        return;
    }

    /* init cp_ctx */
    cp_ctx = session_ctx->data;

    cp_ctx->bl_times = 0;
    ngx_http_cp_hash_init(&cp_ctx->monitored_cookies,
            NGX_HTTP_CP_DEFAULT_BUCKETS_NUM);
}

使用session存储数据的方法

1. 首先需要获取session结构体:

session = ngx_http_session_get(r);

2. 然后再进行其他操作之前,对这个session加锁:

ngx_shmtx_lock(&session->mutex);

3. 从session中提取之前保存的信息,session上保存的信息是每个模块自己存放的ctx结构:

session_ctx = ngx_http_session_find_ctx(session, action->session_name);
ctx结构是模块自行创建,并保存到session上的,ctx结构以名字为唯一标识

4. 对取出的ctx进行需要的操作以完成模块的特定功能
5. 当不在需要使用ctx中存储的内容时,需要解锁session,并减小引用计数:

ngx_shmtx_unlock(&session->mutex);
ngx_http_session_put(r);

ngx_http_session_create_ctx中的init函数和destroy函数的写法

可以参考robot mitigation的init函数和destroy函数:

static void
ngx_http_rm_destroy_ctx_handler(void *ctx)
{
    ngx_http_session_ctx_t *session_ctx;                                                                                
                                                                                                                         
    session_ctx = (ngx_http_session_ctx_t *)ctx;                                                                        
                                                                                                                         
    return ngx_http_session_shm_free_nolock(session_ctx->data);                                                         
}                                                                                                                       
                                                                                                                         
static ngx_int_t                                                                                                        
ngx_http_rm_init_ctx_handler(void *ctx)                                                                                 
{                                                                                                                       
    ngx_http_session_ctx_t *session_ctx;                                                                                
                                                                                                                         
    session_ctx = (ngx_http_session_ctx_t *)ctx;                                                                        
                                                                                                                         
    /* initial session ctx */                                                                                          
    session_ctx->data =                                                                                                 
        ngx_http_session_shm_alloc_nolock(sizeof(ngx_http_rm_session_ctx_t));                                           
    if (!session_ctx->data) {                                                                                           
        fprintf(stderr, "create ac ctx error\n");                                                                       
        return NGX_ERROR;                                                                                               
    }                                                                                                                   
                                                                                                                         
    memset(session_ctx->data, 0, sizeof(ngx_http_rm_session_ctx_t));                                                    
                                                                                                                         
    return NGX_OK;                                                                                                      
}

在共享内存区域分配内存,需要使用ngx_http_session_shm_alloc/free系列函数

个人工具
名字空间
  • 页面
  • 讨论

变换
操作
导航
其他语言
工具箱