logstash解析naxsi日志的问题

目前在用naxsi防火墙,使用elk来做一个日志分析,遇到问题如下:

naxsi作为waf会产生error日志,目前我打开了NAXSI_EXLOG日志选项,因为这个选项可以看到具体的请求内容。

对于同一个请求,naxsi会产生2行或者3行的日志,格式如下:

2017/10/23 17:45:36 [error] 744#0: *19 NAXSI_EXLOG: ip=192.168.141.232&server=192.168.182.141&uri=/sqli-labs/Less-11/&id=1009&zone=BODY&var_name=passwd&content=admin'%20or%20'1'='1'%20xxxxxxxxxx, client: 192.168.141.232, server: _, request: "POST /sqli-labs/Less-11/ HTTP/1.1", host: "192.168.182.141:8000", referrer: "1.1.1.1"
2017/10/23 17:45:36 [error] 744#0: *19 NAXSI_EXLOG: ip=192.168.141.232&server=192.168.182.141&uri=/sqli-labs/Less-11/&id=1013&zone=BODY&var_name=passwd&content=admin'%20or%20'1'='1'%20xxxxxxxxxx, client: 192.168.141.232, server: _, request: "POST /sqli-labs/Less-11/ HTTP/1.1", host: "192.168.182.141:8000", referrer: "1.1.1.1"
2017/10/23 17:45:36 [error] 744#0: *19 NAXSI_FMT: ip=192.168.141.232&server=192.168.182.141&uri=/sqli-labs/Less-11/&learning=0&vers=0.55.3&total_processed=4&total_blocked=4&block=1&cscore0=$SQL&score0=22&cscore1=$XSS&score1=40&zone0=BODY&id0=1009&var_name0=passwd&zone1=BODY&id1=1013&var_name1=passwd, client: 192.168.141.232, server: _, request: "POST /sqli-labs/Less-11/ HTTP/1.1", host: "192.168.182.141:8000", referrer: "1.1.1.1"

这是同一个请求产生的结果,因为每次请求都会有一个id值在里面,这个是19:

未分类

问题:如何取出NAXSI_EXLOG里面的content,跟NAXSI_FMT里面的结果合并到一起?

我写的logstash和正则如下:

DA1 d{4}/d{2}/d{2}
TM1 d{2}:d{2}:d{2}
LEVEL (w+)
NUM1 d+(?:#0: *)
NUM2 d+
EXLOG NAXSI_EXLOG
FMT NAXSI_FMT
ID1 (d+)
ZONE w+
VAR1  (.*)
CONTENT (.*)
T3 w+
T4 HTTP/1.1", host: "(.*)", referrer: "
HOST (.*)

NAXSI %{DA1:date1}s%{TM1:time}s[%{LEVEL:level}]s%{NUM1:num1}%{NUM2:num2}s(?<logtype>NAXSI_EXLOG):sw+=%{HOST:client_ip}&server=%{HOST:hostname}&uri=%{PROG:filepath}&id=%{ID1:id}&zone=%{ZONE:zone}&var_name=%{VAR1:var}&content=%{CONTENT:content},sclient:s%{HOST:ip3},sserver:s(.*)srequest:s"%{T3:method}s%{HOST:uri}sHTTP/1.1",shost:s"%{HOST:host22}"

NAXSI2 %{DA1:date1}s%{TM1:time}s[%{LEVEL:level}]s%{NUM1:num1}%{NUM2:num2}s(?<logtype>NAXSI_EXLOG):sw+=%{HOST:client_ip}&server=%{HOST:hostname}&uri=%{PROG:filepath}&id=%{ID1:id}&zone=%{ZONE:zone}&var_name=%{VAR1:var}&content=%{CONTENT:content},sclient:s%{HOST:ip3},sserver:s(.*)srequest:s"%{T3:method}s%{HOST:uri}sHTTP/1.1",shost:s"%{HOST:host22}",sreferrer:s"(?<referrer>(.*))

FMT %{DA1:date1}s%{TM1:time}s[%{LEVEL:level}]s%{NUM1:num1}%{NUM2:num2}s(?<logtype>NAXSI_FMT):sip=%{HOST:ip}&server=%{HOST:server}&uri=%{UNIXPATH:uri}&learning=%{HOST:learing}&vers=%{HOST:vers}&total_processed=%{HOST:toal_processed}&total_blocked=%{HOST:blocked}&block=%{HOST:block}&cscore0=%{HOST:attack}&score0=%{HOST:score0}&cscore1=%{HOST:xss}&score1=%{HOST:score}&zone0=%{WORD:args}&id0=%{NUMBER:id}&var_name0=%{HOST:varname},sclient:s%{HOST:ip3},sserver:s(.*)srequest:s"%{T3:method}s%{HOST:uri}sHTTP/1.1",shost:s"%{HOST:host22}

logstash.conf:

input {
 file {
       path => "/usr/local/nginx/logs/naxsi.err"
       type => "naxsi-error"
       start_position => "beginning"
   }
   }
   filter {
    if [type] == "naxsi-error" {
    grok {
        patterns_dir => "/opt/logstash-5.5.1/pattern"
        match => [ "message" , "%{NAXSI2}",
               "message" , "%{NAXSI}",
               "message" , "%{FMT}"
            ]

    }
    # aggregate {
    #   task_id => "%{num2}"
    #       code => "map['sql_duration'] = 0"
    #   end_of_task => true
    #   }

}  }
output {
  if [type] == "naxsi-error" {
    elasticsearch {
       hosts => ["localhost"]
       index => "nxapi"
           document_id => "%{num2}"
        }
     }
}

nginx安装配置naxsi waf防火墙

Naxsi 是第三方 nginx 模块 ,它和 Modsecurity 都是开源 WAF ,但是它们的防御模式不同。 Naxsi 不依赖像防病毒软件这样的签名库,因此不会被“未知”攻击模式所规避(就像我们平常说的主动防御)。Naxsi 和其他 WAF 之间的另一个主要区别就是仅过滤 GET 和 POST 请求。

未分类

我之前一直在用 modsecurity ,效果还不错,但是它对 nginx 支持真的不太好~.~ 。经常会产生大量错误日志,不过这个并不影响它的正常功能,只是看着揪心。让我想更换它的主要原因是 Modsecurity 经常在处理某个请求(正常或不正常)时,会突然导致 CPU 99.9% 以上,这是最不能忍受的。

我们先来简单对比下 Naxsi 和 Modsecurity :

未分类

在日常使用中,可以发现 Modsecurity 具有非常严格的防御规则(误报挺多的),并且规则支持较好(有强大的后台?)。如果你使用 Apache 服务器,推荐使用 Modsecurity WAF。如果你使用的是 Nginx 服务器,建议先尝试使用 Naxsi 。

下面就来在 Centos 下编译安装 Nginx + Naxsi WAF 。Modsecurity 的编译安装在这里(http://www.wuedc.com/nginx-installed-configuration-modsecurity-waf/)。

编译 Nginx + Naxsi

首先先运行:

nginx -V

然后可以看到现有的模块,复制保存一下备用。

configure arguments: --prefix=/usr/local/nginx --user=www --group=www --with-http_stub_status_module --with-http_v2_module --with-http_ssl_module --with-ipv6 --with-http_gzip_static_module --with-http_realip_module --with-http_flv_module --with-openssl=../openssl-1.0.2h --with-pcre=../pcre-8.38 --with-pcre-jit --with-ld-opt=-ljemalloc

下载 Nginx 和 Naxsi

Naxsi 应该使用所有高于 0.8.X 的 Nginx 版本。 Naxsi 版本可以在 https://github.com/nbs-system/naxsi 这里,选择 Branch –> Tags 查看版本号。

下载 Nginx 和 Naxsi ,并解压,然后进入解压后的 Nginx 目录:

wget http://nginx.org/download/nginx-x.x.xx.tar.gz
wget https://github.com/nbs-system/naxsi/archive/x.xx.x.tar.gz
tar xvzf nginx-x.x.xx.tar.gz 
tar xvzf naxsi-x.xx.tar.gz
cd nginx-x.x.xx/

Naxsi 不要求任何特定的依赖,它需要的 libpcre ,libssl ,zlib ,gzip 这些 Nginx 已经集成了。

然后编译(记得在 ./configure 后面加上 –add-module=../naxsi-x.xx/naxsi_src/ 和你之前备份的模块):

./configure --conf-path=/etc/nginx/nginx.conf --add-module=../naxsi-x.xx/naxsi_src/ 
--error-log-path=/var/log/nginx/error.log --http-client-body-temp-path=/var/lib/nginx/body 
--http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-log-path=/var/log/nginx/access.log 
--http-proxy-temp-path=/var/lib/nginx/proxy --lock-path=/var/lock/nginx.lock 
--pid-path=/var/run/nginx.pid --with-http_ssl_module 
--without-mail_pop3_module --without-mail_smtp_module 
--without-mail_imap_module --without-http_uwsgi_module 
--without-http_scgi_module --with-ipv6 --prefix=/usr
make
make install

等待编译完成。Naxsi 安装完成。

nginx/naxsi 基本配置

首先将 naxsi 目录下的 naxsi_core.rules 拷贝至 nginx.conf 所在目录。

http 部分配置

打开 nginx.conf 在 http 部分配置:

http {
 include naxsi_core.rules;  #导入 naxsi 核心规则
 ...
}

server 部分配置

在 nginx.conf 的 server 部分配置:

location / {
   #开启 naxsi
   SecRulesEnabled;
   #开启学习模式
   LearningMode;
   #定义阻止请求的位置
   DeniedUrl "/50x.html"; 
   #CheckRules, 确定 naxsi 何时采取行动
   CheckRule "$SQL >= 8" BLOCK;
   CheckRule "$RFI >= 8" BLOCK;
   CheckRule "$TRAVERSAL >= 4" BLOCK;
   CheckRule "$EVADE >= 4" BLOCK;
   CheckRule "$XSS >= 8" BLOCK;
   #naxsi 日志文件
   error_log /.../foo.log;
   ...
  }
  error_page   500 502 503 504  /50x.html;
  #This is where the blocked requests are going
  location = /50x.html {
  return 418; #I'm a teapot o/
  }

server 完整示例配置

server {
listen 80 default;
access_log /wwwlogs/access_nginx.log combined;
root /www/site;
index index.html index.htm index.php;
location ~ [^/].php(/|$) {        
    SecRulesEnabled; 
    #LearningMode;     
    DeniedUrl "/RequestDenied";
    CheckRule "$SQL >= 8" BLOCK;
    CheckRule "$RFI >= 8" BLOCK;
    CheckRule "$TRAVERSAL >= 4" BLOCK;
    CheckRule "$EVADE >= 4" BLOCK;
    CheckRule "$XSS >= 8" BLOCK;    
    error_log /wwwlogs/foo.log;   
    fastcgi_pass unix:/dev/shm/php-cgi.sock;
    fastcgi_index index.php;
    include fastcgi.conf;
}
location /RequestDenied {
    return 403;
}    
location ~ .*.(gif|jpg|jpeg|png|bmp|swf|flv|ico)$ {
    expires 30d;
    access_log off;
    }
location ~ .*.(js|css)?$ {
    expires 7d;
    access_log off;
    }
}

测试

测试 nginx 配置

/nginx/sbin/nginx -t
nginx: the configuration file /nginx/conf/nginx.conf syntax is ok
nginx: configuration file /nginx/conf/nginx.conf test is successful

重启 nginx

service nginx reload

防御测试

浏览器中打开 http://www.test.com/?a=<>‘ ,出现 403 错误,并且在 foo.log 中出现 NAXSI_FMT 开头的日志。恭喜你 Naxsi 启用成功。

白名单规则

Naxsi 社区提供了一些常用的白名单规则,例如 wordpress 。可以在 https://github.com/nbs-system/naxsi-rules 下载白名单规则。

然后将规则 include 到 server 内的 location 中。重启 nginx 即可。不过目前这些白名单最近的修改日期显示是1年前~.~ ,可根据自身需要添加白名单规则。

详细的白名单规则以及 Naxsi 其他支持,可参考 Naxsi WIKI。