目录
- CentOS下Nginx+ModSecurity(3.0.x)安装及配置WAF规则
- 一、安装相关依赖工具
- 二、安装Modsecurity
- 三、安装nginx与ModSecurity-nginx
- 四、测试效果
- 五、配置WAF规则
- 六、重新加载Nginx测试效果
- 七、其他补充
- ModSecurity日志保存至MySQL数据库(通过Logstash)
- 二、配置JDK
- 四、安装logstash-output-jdbc
- 五、创建日志同步配置文件
- 六、创建数据库
- 七、配置ModSecurity记录审计日志
- 八、同步日志
- 九、最后工作(可选)
CentOS下Nginx+ModSecurity(3.0.x)安装及配置WAF规则
本文主要介绍ModSecurity v3.0.x在CentOS+Nginx环境下的安装、WAF规则文件配置、以及防御效果的验证,因此对于Nginx仅进行简单化安装。
服务器操作系统:CentOS-7-x86_64-DVD-1810.iso;
一、安装相关依赖工具
yum install -y git wget epel-release
yum install -y gcc-c++ flex bison yajl yajl-devel curl-devel curl GeoIP-devel doxygen zlib-devel pcre-devel lmdb-devel libxml2-devel ssdeep-devel lua-devel libtool autoconf automake
二、安装Modsecurity
cd /usr/local
git clone https://github.com/SpiderLabs/ModSecurity
cd ModSecurity
git checkout -b v3/master origin/v3/master
git submodule init
git submodule update
sh build.sh
./configure
make && make install
三、安装nginx与ModSecurity-nginx
cd /usr/local
git clone https://github.com/SpiderLabs/ModSecurity-nginx
wget http://nginx.org/download/nginx-1.16.1.tar.gz
tar -xvzf nginx-1.16.1.tar.gz
cd /usr/local/nginx-1.16.1
./configure --add-module=/usr/local/ModSecurity-nginx
make
make install
四、测试效果
启动nginx
/usr/local/nginx/sbin/nginx
模拟攻击,测试未启动ModSecurity时的访问效果,访问URL为:http://服务器IP/?param=%22%3E%3Cscript%3Ealert(1);%3C/script%3E
效果如下:
五、配置WAF规则
创建用于存在配置文件的文件夹
mkdir /usr/local/nginx/conf/modsecurity
将/usr/local/Modsecurity/modsecurity.conf-recommended
复制到/usr/local/nginx/conf/modsecurity
,并重命名为modsecurity.conf
;
将/usr/local/Modsecurity/unicode.mapping
复制到/usr/local/nginx/conf/modsecurity
;
下载规则文件压缩包,解压后复制crs-setup.conf.example
到/usr/local/nginx/conf/modsecurity/
下并重命名为crs-setup.conf
;
复制rules
文件夹到/usr/local/nginx/conf/modsecurity/
下,同时修改REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example
与RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf.example
两个文件的文件名,将".example"删除,可将自己写的规则放置于此两个文件中;
编辑nginx.conf
在http
或server
节点中添加以下内容(在http节点添加表示全局配置,在server
节点添加表示为指定网站配置.
modsecurity on;
modsecurity_rules_file /usr/local/nginx/conf/modsecurity/modsecurity.conf;
编辑modsecurity.conf
SecRuleEngine DetectionOnly
改为SecRuleEngine On
同时添加以下内容:
Include /usr/local/nginx/conf/modsecurity/crs-setup.conf
Include /usr/local/nginx/conf/modsecurity/rules/*.conf
六、重新加载Nginx测试效果
/usr/local/nginx/sbin/nginx -s reload
七、其他补充
如果要确保ModSecurity v3.0.3在记录审计日志时保存请求体,SecAuditLogParts需要添加配置C,而不是IJ,否则审计日志将无法记录请求体
ModSecurity日志保存至MySQL数据库(通过Logstash)
一、软件上传
将上述JDK及Logstash的软件压缩包下载后,上传至服务器/usr/local目录下并解压,将JDBC上传至解压后的Logstash目录下。
cd /usr/local
tar -zxvf jdk-8u241-linux-x64.tar.gz
tar -zxvf logstash-5.6.16.tar.gz
二、配置JDK
如果服务器中已经安装了其他版本的JDK,且不可随意变更,可对Logstash进行单独的JDK配置,将以下内容复制到Logstash目录下bin/logstash、bin/logstash.lib.sh两个文件的首行位置即可:
export JAVA_HOME=/usr/local/jdk1.8.0_241
三、测试Logstash
首先,测试Logstash是否可以正常工作,在控制台输入以下命令等待Logstash启动:
/usr/local/logstash-5.6.16/bin/logstash -e 'input { stdin { } } output { stdout {} }'
启动成功的结果类似于下图(电脑端右击图片点击“在新标签页中打开图片”即可查看大图):
然后直接输入字符串,如“Test”回车,如出现类似以下信息,表明Logstash可正常工作
测试结束后通过Ctrl+C结束进程
四、安装logstash-output-jdbc
由于要把日志输入到数据库中,因此需要安装logstash-output-jdbc,该插件为第三方所开发,并未在Logstash 6.3及以上版本进行测试。
/usr/local/logstash-5.6.16/bin/logstash-plugin install logstash-output-jdbc
由于要从国外ubygems.org下载插件,因此在线安装过程较慢,如果发现无法在线安装,可下载logstash-output-jdbc.zip,上传至Logstash目录下。该安装包为本人基于Logstash 5.6.16在线安装logstash-output-jdbc成功后,所生成的离线安装包,其他版本的Logstash不一定适用。运行以下命令即可进行离线安装:
/usr/local/logstash-5.6.16/bin/logstash-plugin install file:///usr/local/logstash-5.6.16/logstash-output-jdbc.zip
五、创建日志同步配置文件
在Logstash目录下创建文件mslogtomysql.conf,并将以下内容复制进文件中,保存时要使用UTF8格式,或将中文注释删除,否则Logstash启动时会报错:
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"}}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]" ]}
}
六、创建数据库
创建名为modsecurity的数据库,并执行以下SQL创建数据表
SET FOREIGN_KEY_CHECKS=0;-- ----------------------------
-- Table structure for `data`
-- ----------------------------
DROP TABLE IF EXISTS `data`;
CREATE TABLE `data` (`id` int(11) NOT NULL AUTO_INCREMENT,`client_ip` varchar(255) DEFAULT NULL,`time_stamp` varchar(255) DEFAULT NULL,`date` datetime DEFAULT NULL,`server_id` varchar(255) DEFAULT NULL,`client_port` int(11) DEFAULT NULL,`host_ip` varchar(255) DEFAULT NULL,`host_port` int(11) DEFAULT NULL,`uri` varchar(255) DEFAULT NULL,`unique_id` varchar(255) DEFAULT NULL,`request` mediumtext,`response` mediumtext,`producer` mediumtext,`messages` mediumtext,PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
七、配置ModSecurity记录审计日志
modsecurity.conf文件需进行以下配置:
SecAuditEngine On
#注意,ModSecurity 3.x版本中目前不支持使用IJ记录请求体内容,如果要记录请求体,请用C代替IJ
#但此时会有一个情况,如果通过网站进行文件上传,文件的内容也会被记录到日志中,因此请勿通过网站上传大容量文件
SecAuditLogParts ABIJDEFHZ
#设置并行方式记录日志
SecAuditLogType Concurrent
#配置存放日志的目录,该目录必须存在且赋予777权限,否则可能无法正常写入日志
SecAuditLogStorageDir /var/log/modsecurity/
#配置记录的日志为JSON格式
SecAuditLogFormat JSON
配置完成后需要重新加载WEB服务
八、同步日志
运行以下命令,使Logstash以指定的配置文件启动:
/usr/local/logstash-5.6.16/bin/logstash -f /usr/local/logstash-5.6.16/mslogtomysql.conf
启动成功的结果类似于下图(电脑端右击图片点击“在新标签页中打开图片”即可查看大图):
启动后,网站的最新访问,会先被ModSecurity记录,然后同步到数据库中
九、最后工作(可选)
编写脚本,将Logstash以后台服务方式运行,并设置开机自启;
编写定时脚本,在凌晨1点时,将前一天的ModSecurity审计日志删除,避免日志越来越多,占用磁盘空间。