-
-
[原创]modsecurity 搭建web安全防火墙和流量检测
-
发表于: 2022-1-25 14:17 5312
-
modsecurity 搭建web安全防火墙和流量检测
前言
因工作需要,需要调研WAF和IDS产品,我经过调研选择了Modsecurity作为Web端的防火墙防护软件和Suricata作为tcp和udp层的防护,并且通过logstash将结果输出到elasticsearch中进行分析。
ModSecurity
ModSecurity是一个开源的跨平台Web应用程序防火墙(WAF)引擎,用于Apache,IIS和Nginx,由Trustwave的SpiderLabs开发。作为WAF产品,ModSecurity专门关注HTTP流量,当发出HTTP请求时,ModSecurity检查请求的所有部分,如果请求是恶意的,它会被阻止和记录。
优势
完美兼容nginx,是nginx官方推荐的WAF,支持OWASP规则 3.0版本比老版本更新更快,更加稳定,并且得到了nginx、Inc和Trustwave等团队的积极支持,而且是免费的。
安装
本文假设你已经安装了nginx,如果没有nginx,那么请参考RHEL/CentOS 安装最新版Nginx。
安装依赖
1 2 | yum install epel - release - y yum install gcc - c + + flex bison yajl yajl - devel curl - devel curl GeoIP - devel doxygen zlib - devel pcre pcre - devel libxml2 libxml2 - devel autoconf automake lmdb - devel ssdeep - devel ssdeep - libs lua - devel libmaxminddb - devel git apt - utils autoconf automake build - essential git libcurl4 - openssl - dev libgeoip - dev liblmdb - dev ibpcre + + - dev libtool libxml2 - dev libyajl - dev pkgconf wget zlib1g - dev - y |
下载并且编译
1 2 3 4 5 6 7 8 9 | cd / opt / # 切换到/opt git clone - - depth 1 - b v3 / master - - single - branch https: / / github.com / SpiderLabs / ModSecurity # 下载 cd ModSecurity / git submodule init # 初始化 git submodule update # 更新# . / build.sh . / configure make make install |
ModSecurity-nginx连接器
1 2 | cd / opt / git clone - - depth 1 https: / / github.com / SpiderLabs / ModSecurity - nginx.git |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | nginx - v # 查看当前nginx版本 nginx version: nginx / 1.17 . 5 wget http: / / nginx.org / download / nginx - 1.17 . 5.tar .gz tar - xvf nginx - 1.17 . 5.tar .gz ls ModSecurity ModSecurity - nginx nginx - 1.17 . 5 nginx - 1.17 . 5.tar .gz cd nginx - 1.17 . 5 / . / configure - - with - compat - - add - dynamic - module = .. / ModSecurity - nginx # 如果出现不兼容的问题,请去掉--with-compat参数 make modules # 会生成如下*.so ls . / objs / ngx_http_modsecurity_module.so . / objs / ngx_http_modsecurity_module.so # 查看 cp . / objs / ngx_http_modsecurity_module.so / etc / nginx / modules / # 移动位置 vim / etc / nginx / nginx.conf load_module / etc / nginx / modules / ngx_http_modsecurity_module.so; # 添加到配置文件首行 |
确定nginx模块加载成功:
1 2 3 | nginx - t nginx: the configuration file / etc / nginx / nginx.conf syntax is ok nginx: configuration file / etc / nginx / nginx.conf test is successful # 测试通过 |
启用WAF
- Include:包括modsecurity.conf文件中建议的配置。
- SecRule:创建一个规则,当查询字符串中的testparam参数包含字符串test时,通过阻止请求并返回状态代码403来保护应用程序。
### 下载OWASP规则
下载地址:https://github.com/SpiderLabs/owasp-modsecurity-crs
将规则目录 owasp-modsecurity-crs-master 放置 /usr/local/nginx/conf/ 下,
然后将 owasp-modsecurity-crs-master 目录下的 modsecurity_crs_10_setup.conf.example 改名为 modsecurity_crs_10_setup.conf 。
1 2 3 4 | [root@localhost ~] # mkdir /usr/local/nginx/conf/ [root@localhost ~] # cd /usr/local/nginx/conf/ [root@localhost modsec] # sudo wget https://raw.githubusercontent.com/SpiderLabs/ModSecurity/v3/master/modsecurity.conf-recommended [root@localhost modsec] # sudo mv modsecurity.conf-recommended modsecurity.conf |
1 2 3 4 5 6 7 8 9 10 11 12 13 | [root@localhost modsec] # vim modsecurity.conf # -- Rule engine initialization ---------------------------------------------- ... SecRuleEngine On < = = 设置为On #编辑modsecurity.conf 文件,将`SecRuleEngine`设置为 `on` ,并将你需要的规则导入进来: Include modsecurity - crs / modsecurity_crs_10_setup.conf Include modsecurity - crs / base_rules / modsecurity_crs_35_bad_robots.conf Include modsecurity - crs / base_rules / modsecurity_crs_40_generic_attacks.conf Include modsecurity - crs / base_rules / modsecurity_crs_41_sql_injection_attacks.conf Include modsecurity - crs / base_rules / modsecurity_crs_41_xss_attacks.conf Include modsecurity - crs / base_rules / modsecurity_crs_42_tight_security.conf Include modsecurity - crs / base_rules / modsecurity_crs_45_trojans.conf |
配置nginx
1 2 3 4 5 | location \ { ModSecurityEnabled on; ModSecurityConfig modsecurity.conf; ....其他配置 } |
测试规则
1 | SecRule ARGS:testparam "@contains leishi" "id:1234,deny,log,status:403" |
curl -D - http://localhost/p?p=leishi #则返回"403 Forbidden",说明前面配置的那条modsecuriy规则生效了,并阻拦了testparam参数中带leishi的请求
通过logstash 输出到es中
logstash配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | input { file { #ModSecurity审计日志的存放位置,请根据实际情况进行修改 path = > [ "/var/log/modsecurity/*/*/*" ] start_position = > "beginning" } } filter { json{ source = > "message" remove_field = > [ "message" ] } #以下到filter节点结束的内容,是为了将ModSecurity记录的日期转换为数据库可存放的datetime格式 mutate{ split = > [ "[transaction][time_stamp]" , " " ] add_field = > { "date" = > "yyyy-MM-dd HH:mm:ss" } add_field = > { "month" = > "%{[transaction][time_stamp][1]}" } add_field = > { "day" = > "%{[transaction][time_stamp][2]}" } add_field = > { "time" = > "%{[transaction][time_stamp][3]}" } add_field = > { "year" = > "%{[transaction][time_stamp][4]}" } } if [month] = = "Jan" { mutate { gsub = >[ "month" , "Jan" , '01' ] } } else if [month] = = "Feb" { mutate { gsub = >[ "month" , "Feb" , '02' ] } } else if [month] = = "Mar" { mutate { gsub = >[ "month" , "Mar" , '03' ] } } else if [month] = = "Apr" { mutate { gsub = >[ "month" , "Apr" , '04' ] } } else if [month] = = "May" { mutate { gsub = >[ "month" , "May" , '05' ] } } else if [month] = = "Jun" { mutate { gsub = >[ "month" , "Jun" , '06' ] } } else if [month] = = "Jul" { mutate { gsub = >[ "month" , "Jul" , '07' ] } } else if [month] = = "Aug" { mutate { gsub = >[ "month" , "Aug" , '08' ] } } else if [month] = = "Sep" { mutate { gsub = >[ "month" , "Sep" , '09' ] } } else if [month] = = "Oct" { mutate { gsub = >[ "month" , "Oct" , '10' ] } } else if [month] = = "Nov" { mutate { gsub = >[ "month" , "Nov" , '11' ] } } else if [month] = = "Dec" { mutate { gsub = >[ "month" , "Dec" , '12' ] } } mutate { gsub = >[ "date" , "yyyy" , '%{[year]}' ] gsub = >[ "date" , "MM" , '%{[month]}' ] gsub = >[ "date" , "dd" , '%{[day]}' ] gsub = >[ "date" , "HH:mm:ss" , '%{[time]}' ] } } output { #该节点会将最终日志数据以JSON格式打印到控制台中,便于观测进行调试,测试无问题后可将此节点删除 stdout { codec = > json { charset = > "UTF-8" } } #这是导入到mysql中的 jdbc { driver_jar_path = > "/usr/local/logstash-5.6.16/mysql-connector-java-5.1.48.jar" driver_class = > "com.mysql.jdbc.Driver" connection_string = > "jdbc:mysql://服务器IP地址:数据库端口/modsecurity?user=数据库用户名&password=数据库密码" statement = > [ "insert into data (client_ip,time_stamp,date,server_id,client_port,host_ip,host_port,uri,unique_id,request,response,producer,messages) values (?,?,?,?,?,?,?,?,?,?,?,?,?)" , "[transaction][client_ip]" , "[transaction][time_stamp]" , "[date]" , "[transaction][server_id]" , "[transaction][client_port]" , "[transaction][host_ip]" , "[transaction][host_port]" , "[transaction][request][uri]" , "[transaction][unique_id" , "[transaction][request]" , "[transaction][response]" , "[transaction][producer]" , "[transaction][messages]" ] } # 这是导入到es,这是可以选择 elasticsearch { hosts = > [ "192.168.33.129:9200" ] index = > "logwaf" } } |
最后在es中的数据就是为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | { "_index" : "logwaf" , "_type" : "logs" , "_id" : "AX4Pdd0Mq558YisonVXR" , "_version" : 1 , "_score" : 1 , "_source" : { "date" : "2021-12-31 07:48:07" , "path" : "/var/log/modsecurity/audit/20211231/20211231-0748/20211231-074807-164093688737.386422" , "@timestamp" : "2021-12-31T07:48:08.804Z" , "month" : "12" , "year" : "2021" , "@version" : "1" , "host" : "c8bd4dde6893" , "time" : "07:48:07" , "day" : "31" , "transaction" : { "client_port" : 55174 , "request" : { "http_version" : 1.1 , "headers" : { "Cookie" : "ajs_user_id=%22d08c2741-686f-4bd1-8527-40e1e1760308%22; ajs_anonymous_id=%22764ebc96-e142-4392-ac62-a22cd43aaf1c%22; Pycharm-1a34857a=7256c262-1a06-483b-9e21-e5144bbae1a2; Hm_lvt_f4b3788b2247dd149fb7fdffe8aece79=1635765808; _ga=GA1.1.2010376713.1635765808; __51uvsct__JUFvSBqCDGdznrm5=1; __51vcke__JUFvSBqCDGdznrm5=6f1eaa0d-dafc-5edd-9afd-f6e62ef6ed88; __51vuft__JUFvSBqCDGdznrm5=1636880896220; langCookie=zh; wp-settings-time-1=1639190281; JSESSIONID=FFA49AA3640B99495C68AF8E96FE5E9C; thinkphp_show_page_trace=0|0" , "Accept" : "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9" , "User-Agent" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36" , "Connection" : "keep-alive" , "Sec-Fetch-Site" : "none" , "Sec-Fetch-Dest" : "document" , "Host" : "localhost:8013" , "Accept-Encoding" : "gzip, deflate, br" , "Sec-Fetch-Mode" : "navigate" , "If-None-Match" : " "61cace6a-264" ", "sec-ch-ua" : " " Not A;Brand" ;v = "99" , "Chromium" ;v = "96" , "Google Chrome" ;v = "96" ", "sec-ch-ua-mobile" : "?0" , "Upgrade-Insecure-Requests" : "1" , "sec-ch-ua-platform" : " "macOS" ", "If-Modified-Since" : "Tue, 28 Dec 2021 08:44:26 GMT" , "Sec-Fetch-User" : "?1" , "Accept-Language" : "zh-CN,zh;q=0.9,en;q=0.8,zh-TW;q=0.7,pl;q=0.6" }, "method" : "GET" , "uri" : "/?id=and%201=1" }, "host_ip" : "172.17.0.1" , "unique_id" : "164093688737.386422" , "time_stamp" : [ "Fri" , "Dec" , "31" , "07:48:07" , "2021" ], "host_port" : 80 , "response" : { "http_code" : 200 , "headers" : { "Server" : "nginx" , "ETag" : " "5bca3358-264" ", "Connection" : "keep-alive" , "Last-Modified" : "Fri, 19 Oct 2018 19:41:12 GMT" , "Content-Length" : "612" , "Date" : "Fri, 31 Dec 2021 07:48:06 GMT" , "Content-Type" : "text/html" } }, "producer" : { "components" : [ "OWASP_CRS/3.0.2" " ], "secrules_engine" : "Enabled" , "connector" : "ModSecurity-nginx v1.0.0" , "modsecurity" : "ModSecurity v3.0.2 (Linux)" }, "messages" : [ ], "client_ip" : "172.17.0.1" , "server_id" : "6b4dd6eb31598154db9df92bdbaca527e7b8613d" } } } |
总结
Modsecurity还是非常优秀的,利用这样一款开源免费的产品做web防火墙文档和资料都不会少。而且其作者一直也在更新,值得推荐和研究,web的防火墙我们已经构建,那么tcp和udp的suricata我们下期再讲!
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!