ELK分析ngx_lua_waf软件防火墙日志

ELK分析ngx_lua_waf软件防火墙日志

ngx_lua_waf介绍及部署可以参考

https://github.com/loveshell/ngx_lua_waf

这个一个基于lua-nginx-module的web应用防火墙,作者是张会源(ID : kindle),微博:@神奇的魔法师。

用途:

防止sql注入,本地包含,部分溢出,fuzzing测试,xss,***F等web***

防止svn/备份之类文件泄漏

防止ApacheBench之类压力测试工具的***

屏蔽常见的扫描***工具,扫描器

屏蔽异常的网络请求

屏蔽图片附件类目录php执行权限

防止webshell上传

总结:

1,Nginx_lua_waf总体来说功能强大,相比其他软件防火墙Modsecurity还稍微简单点。

2,Ngx_lua_waf的bug主要就是防火墙策略写的不严谨导致的,会造成两种结果:一是部分***通过伪装绕过防火墙;二是防火墙策略配置不当会造成误杀。

3,另外根据站点的类型需要配置不同的策略,默认配置后全局生效。比如论坛等比较特殊允许很多html插入,这样的策略需要更宽松。

4,最后生成的hack记录日志可以通过ELK分析,ELK这边需要根据日志格式制作特殊模版,此模版能兼容大部分日志类型,还有少部分完全没有规律的日志分析不了。

5,最后ELK能展示日志分析结果分类,但是还不能区分各种ruletag类型***属于哪一种直白的表示出来。

6,最后建议ngx_lua_waf如果真的要用可以考虑在部分源站站点少量试用,前端站点不建议使用,等对该软件理解深入后才可线上使用。

7,补充:目前对ngx_lua_waf拒绝特定的user agent、拒绝特定后缀文件访问、防止sql注入三大类比较熟悉。

后续计划:

有人(此人人称赵班长项目地址 https://github.com/unixhot/waf) 对ngx_lua_waf进行了二次重构,主要功能有:黑白名单、只记录***日志不限制访问(日志格式可能更友好点待观察)、另外使用openresty部署的,后期计划使用二次重构的waf再次测试下。

计划大概实施步骤:

1,不要一次性部署上线,先部署后,只记录日志,然后观察和调整规则,保证正常的请求不会被误防。

2,使用SaltStack管理规则库的更新。

3,使用ELKStack进行日志收集和分析,非常方便的可以在Kibana上做出一个漂亮的***统计的饼图。(目前也能实现)

以下是具体操作过程中需要注意的问题点

一,ELK新增针对nginx_lua_waf日志切分策略

1,日志格式

 line = realIp.." ["..time.."] \""..method.." "..servername..url.."\" \""..data.."\"  \""..ua.."\" \""..ruletag.."\"\n"

2,日志内容

192.168.200.106 [2016-07-26 16:56:17] "UA i.maicar.com/AuthenService/Frame/login.aspx?ra=0.5440098259132355" "-"  "Baidu-YunGuanCe-ScanBot(ce.baidu.com)" "(HTTrack|harvest|audit|dirbuster|pangolin|nmap|sqln|-scan|hydra|Parser|libwww|BBBike|sqlmap|w3af|owasp|Nikto|fimap|havij|PycURL|zmeu|BabyKrokodil|netsparker|httperf|bench| SF/)"

3,logstash 切分策略

最关键的还是grok正则表达式的书写,这里给两个建议:

1)一是参考系统自带的              /opt/logstash/vendor/bundle/jruby/1.9/gems/logstash-patterns-core-2.0.5/patterns/

该目录下有系统自带的很多日志格式的grok正则切分语法,如:

aws     bro   firewalls      haproxy  junos         mcollective        mongodb  postgresql  redis   bacula  exim  grok-patterns  java     linux-syslog  mcollective-patterns  nagios   rails       ruby

默认没有规律的参考grok-patterns

2)二是网上有两个grok语法验证网站(都得***)

http://grokdebug.herokuapp.com/

http://grokconstructor.appspot.com/do/match#result

也可以手动验证,举例如下

[root@elk logstash]# /opt/logstash/bin/logstash -f /etc/logstash/test1.conf 
Settings: Default pipeline workers: 4
Pipeline main started
192.168.200.106 [2016-07-26 16:56:17] "UA i.maicar.com/AuthenService/Frame/login.aspx?ra=0.5440098259132355" "-"  "Baidu-YunGuanCe-ScanBot(ce.baidu.com)" "(HTTrack|harvest|audit|dirbuster|pangolin|nmap|sqln|-scan|hydra|Parser|libwww|BBBike|sqlmap|w3af|owasp|Nikto|fimap|havij|PycURL|zmeu|BabyKrokodil|netsparker|httperf|bench| SF/)"
{
       "message" => "192.168.200.106 [2016-07-26 16:56:17] \"UA i.maicar.com/AuthenService/Frame/login.aspx?ra=0.5440098259132355\" \"-\"  \"Baidu-YunGuanCe-ScanBot(ce.baidu.com)\" \"(HTTrack|harvest|audit|dirbuster|pangolin|nmap|sqln|-scan|hydra|Parser|libwww|BBBike|sqlmap|w3af|owasp|Nikto|fimap|havij|PycURL|zmeu|BabyKrokodil|netsparker|httperf|bench| SF/)\"",
      "@version" => "1",
    "@timestamp" => "2016-07-28T10:05:43.763Z",
          "host" => "0.0.0.0",
        "realip" => "192.168.200.106",
          "time" => "2016-07-26 16:56:17",
        "method" => "UA",
    "servername" => "i.maicar.com",
           "url" => "/AuthenService/Frame/login.aspx?ra=0.5440098259132355",
          "data" => "-",
     "useragent" => "Baidu-YunGuanCe-ScanBot(ce.baidu.com)",
       "ruletag" => "(HTTrack|harvest|audit|dirbuster|pangolin|nmap|sqln|-scan|hydra|Parser|libwww|BBBike|sqlmap|w3af|owasp|Nikto|fimap|havij|PycURL|zmeu|BabyKrokodil|netsparker|httperf|bench| SF/)"
}

其中test1.conf内容如下:

input{stdin{}}
filter {
       grok {
           match => {
                       "message" =>"%{IPV4:realip}\s+\[%{TIMESTAMP_ISO8601:time}\]\s+\"%{WORD:method}\s+%{HOSTNAME:servername}(?<url>[^\"]+)\"\s+\"(?<data>[^\"]+)\"\s+\"(?<useragent>[^\"]+)\"\s+\"(?<ruletag>[^\"]+)\""
            }
      }
}
output{stdout{codec=>rubydebug}}

最后线上切分策略如下:

filter {
if [type] == "waf194" {
grok {
      match => [ 
                       "message" , "%{IPV4:realip}\s+\[%{TIMESTAMP_ISO8601:time}\]\s+\"%{WORD:method}\s+%{HOSTNAME:servername}(?<url>[^\"]+)\"\s+\"(?<data>[^\"]+)\"\s+\"(?<useragent>[^\"]+)\"\s+\"(?<ruletag>[^\"]+)\""
]
                remove_field => [ "message" ]
}
       }
}

二,ELK新增针对nginx_lua_waf日志的索引模版

其中最关键问题是多个索引模版共存的问题,以前总是后加索引模版会覆盖原来的,参考http://mojijs.com/2015/08/204352/index.html   设置tempalte_name来区分不同的索引模版。

输出模版配置如下:

output {    
  elasticsearch {
    hosts => ["192.168.88.187:9200","192.168.88.188:9200","192.168.88.189:9200"]
    sniffing => false
    manage_template => true
    template => "/opt/logstash/templates/logstashwaf.json"
    template_overwrite => true
    template_name => "logstashwaf.json"
    index => "logstash-%{type}-%{+YYYY.MM.dd}"
    document_type => "%{[@metadata][type]}"
    flush_size => 10000
  }
}

具体logstashwaf.json配置如下,这个是直接参考官方的elasticsearch-logstash.json,就修改了template名字,配置里面只要是string类型的都做了不分词,因为做视图时不分词一来可以节省内存,二来向url,agent,ruletag等等长stings只有不分词才能精确匹配,那种分词的模糊匹配用不上。另外如果只要某些string字段添加不分词,也可以修改"match" : "*",为具体的字段,如:

           "match_pattern": "regex",  #此行为新增加
           "match" : "(realip)|(mothod)(servername)|(url)|(data)|(useragent)|(ruletag)",

线上总体配置如下:

{
  "template" : "logstash-waf194*",
  "settings" : {
    "index.refresh_interval" : "5s"
  },
  "mappings" : {
    "_default_" : {
       "_all" : {"enabled" : true, "omit_norms" : true},
       "dynamic_templates" : [ {
         "message_field" : {
           "match" : "message",
           "match_mapping_type" : "string",
           "mapping" : {
             "type" : "string", "index" : "analyzed", "omit_norms" : true
           }
         }
       }, {
         "string_fields" : {
           "match" : "*",
           "match_mapping_type" : "string",
           "mapping" : {
             "type" : "string", "index" : "analyzed", "omit_norms" : true,
               "fields" : {
                 "raw" : {"type": "string", "index" : "not_analyzed", "ignore_above" : 256}
               }
           }
         }
       } ],
       "properties" : {
         "@version": { "type": "string", "index": "not_analyzed" },
         "geoip"  : {
           "type" : "object",
             "dynamic": true,
             "properties" : {
               "location" : { "type" : "geo_point" }
             }
         }
       }
    }
  }
}

三,Ngx_lua_waf生成的hack日志ELK上展示如下

其中制作视图制作模版等都省略

分析小部分日志结果如下:

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏程序员叨叨叨

compileSdkVersion 'android-24' requires JDK 1.8 or later to compile

今天,好久没有写Android程序的我突发奇想,想简单写一个每日任务APP。好的!新建工程->写好代码框架->开启模拟器->运行!哎哎哎?!那啥!咋报错了嘞?!...

1164
来自专栏Java工程师日常干货

Redis高级特性介绍及实例分析Redis基础类型回顾 Redis发展过程中的三种模式:主从、哨兵、集群 哨兵模式 Redis的简单事务 Redis持久化机制 发布与订阅消息 Redis案例设计

本文将为大家介绍Redis的一些高级特性以及结合一个具体的实际案例来对Redis进行设计分析。

1672
来自专栏happyJared

程序员神器,IntelliJ IDEA 2018.1 正式发布

3月27日,jetbrains正式发布期待已久的IntelliJ IDEA 2018.1,再次让人眼前一亮:什么,还能这么玩?

951
来自专栏静晴轩

Gulp探究折腾之路(I)

前言: gulp是前端开发过程中对代码进行构建的工具,是自动化项目的构建利器;她不仅能对网站资源进行优化,而且在开发过程中很多重复的任务能够使用正确的工具自动完...

3728
来自专栏老九学堂

Java开发常用工具

Java开发常用工具 小贴士 Java是目前最流行的软件开发语言,其IDE环境也备受开发者关注,IDE可以极大的提高开发速 一 UltraEdit ? Ultr...

3315
来自专栏腾讯云Elasticsearch Service

Elasticsearch调优实践

本文基于ES 5.6.4,从性能和稳定性两方面,从linux参数调优、ES节点配置和ES使用方式三个角度入手,介绍ES调优的基本方案。当然,ES的调优绝不能一概...

3341
来自专栏bboysoul

linux 终端下最简单的代理方式(proxychains)

我以前写过给linux终端设置代理 这个是用polipo这个工具把socks5代理转换成为http和https代理来实现终端下代理的,那么终端下有没有原生的使...

1792
来自专栏一只程序汪的自我修养

使用requirejs编写模块化代码

2435
来自专栏AhDung

弹出移动设备时报正在使用肿么办

当确信没有程序在占用该设备时,这种提示让我觉得很操蛋,NTM说明白点会死啊~好吧,这时还不忍心直接拔的童鞋可以接着往下看:

1442
来自专栏Jaycekon

Python-WXPY实现微信监控报警

概述:   本文主要分享一下博主在学习wxpy 的过程中开发的一个小程序。博主在最近有一个监控报警的需求需要完成,然后刚好在学习wxpy 这个东西,因此很巧妙的...

2.2K8

扫码关注云+社区

领取腾讯云代金券