如何在CentOS 7,Debian 8和Ubuntu 16.04上为Nginx安装ModSecurity
ModSecurity是一个开放源码的Web应用程序防火墙(WAF)模块,它非常适合保护Apache,Nginx和IIS免受各种网络攻击的攻击,这些网络攻击通常针对各种Web应用程序中的潜在漏洞。
在本文中,我们将在CentOS 7,Debian 8和Ubuntu 16.04上为Nginx安装和配置ModSecurity。
环境要求
- 最新的CentOS 7,Debian 8或Ubuntu 16.04 64位安装。
- 以
root
身份登录。
第1步:更新系统
参照本指南 ,将服务器的内核和软件包更新为最新版本。
第2步:安装依赖关系
在成功编译Nginx和ModSecurity之前,您需要按如下方式安装多个软件包。
a)在CentOS 7上:
yum groupinstall -y "Development Tools"
yum install -y httpd httpd-devel pcre pcre-devel libxml2 libxml2-devel curl curl-devel openssl openssl-devel
shutdown -r now
b)在Debian 8或Ubuntu 16.04上:
apt-get install -y git build-essential libpcre3 libpcre3-dev libssl-dev libtool autoconf apache2-dev libxml2-dev libcurl4-openssl-dev automake pkgconf
第3步:编译ModSecurity
由于ModSecurity for Nginx的master分支存在一些被报告的不稳定性,因此目前推荐尽可能使用最新版本的nginx_refactoring
分支。
下载Nginx的ModSecurity的nginx_refactoring
分支:
cd /usr/src
git clone -b nginx_refactoring https://github.com/SpiderLabs/ModSecurity.git
编译ModSecurity:
a)在CentOS 7上:
cd ModSecurity
sed -i '/AC_PROG_CC/a\AM_PROG_CC_C_O' configure.ac
sed -i '1 i\AUTOMAKE_OPTIONS = subdir-objects' Makefile.am
./autogen.sh
./configure --enable-standalone-module --disable-mlogc
make
注意:上述两个sed
命令用于在使用newerautomake版本时防止警告消息。
b)在Debian 8或Ubuntu 16.04上:
cd ModSecurity
./autogen.sh
./configure --enable-standalone-module --disable-mlogc
make
第4步:编译Nginx
在撰写本文时,下载并解压缩Nginx 1.10.3
的最新Nginx稳定版本:
cd /usr/src
wget https://nginx.org/download/nginx-1.10.3.tar.gz
tar -zxvf nginx-1.10.3.tar.gz && rm -f nginx-1.10.3.tar.gz
a)在CentOS 7上:
首先,你需要为Nginx创建一个专用的用户nginx
和一个专用的nginx
组:
groupadd -r nginx
useradd -r -g nginx -s /sbin/nologin -M nginx
然后在启用ModSecurity和SSL模块的同时编译Nginx:
cd nginx-1.10.3/
./configure --user=nginx --group=nginx --add-module=/usr/src/ModSecurity/nginx/modsecurity --with-http_ssl_module
make
make install
修改Nginx的默认用户:
sed -i "s/#user nobody;/user nginx nginx;/" /usr/local/nginx/conf/nginx.conf
b)在Debian 8或Ubuntu 16.04上:
首先,您应该使用现有的用户www-data
和现有的组www-data
。
然后在启用ModSecurity和SSL模块的同时编译Nginx:
cd nginx-1.10.3/
./configure --user=www-data --group=www-data --add-module=/usr/src/ModSecurity/nginx/modsecurity --with-http_ssl_module
make
make install
修改Nginx的默认用户:
sed -i "s/#user nobody;/user www-data www-data;/" /usr/local/nginx/conf/nginx.conf
成功安装Nginx后,相关文件将位于:
nginx path prefix: "/usr/local/nginx"
nginx binary file: "/usr/local/nginx/sbin/nginx"
nginx modules path: "/usr/local/nginx/modules"
nginx configuration prefix: "/usr/local/nginx/conf"
nginx configuration file: "/usr/local/nginx/conf/nginx.conf"
nginx pid file: "/usr/local/nginx/logs/nginx.pid"
nginx error log file: "/usr/local/nginx/logs/error.log"
nginx http access log file: "/usr/local/nginx/logs/access.log"
nginx http client request body temporary files: "client_body_temp"
nginx http proxy temporary files: "proxy_temp"
nginx http fastcgi temporary files: "fastcgi_temp"
nginx http uwsgi temporary files: "uwsgi_temp"
nginx http scgi temporary files: "scgi_temp"
您可以使用以下方法测试安装:
/usr/local/nginx/sbin/nginx -t
如果没有出错,输出应该是:
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
为方便管理nginx进程,您可以为Nginx设置一个systemd unit配置文件:
cat <<EOF>> /lib/systemd/system/nginx.service
[Service]
Type=forking
ExecStartPre=/usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf
ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
ExecReload=/usr/local/nginx/sbin/nginx -s reload
KillStop=/usr/local/nginx/sbin/nginx -s stop
KillMode=process
Restart=on-failure
RestartSec=42s
PrivateTmp=true
LimitNOFILE=200000
[Install]
WantedBy=multi-user.target
EOF
然后,您可以按如下方式启动/停止/重新启动Nginx:
systemctl start nginx.service
systemctl stop nginx.service
systemctl restart nginx.service
第4步:配置ModSecurity和Nginx
4.1配置Nginx:
vi /usr/local/nginx/conf/nginx.conf
在http {}
块中找到以下代码块:
location / {
root html;
index index.html index.htm;
}
将以下内容插入location / {}
代码块:
ModSecurityEnabled on;
ModSecurityConfig modsec_includes.conf;
#proxy_pass http://localhost:8011;
#proxy_read_timeout 180s;
最终的结果应该是:
location / {
ModSecurityEnabled on;
ModSecurityConfig modsec_includes.conf;
#proxy_pass http://localhost:8011;
#proxy_read_timeout 180s;
root html;
index index.html index.htm;
}
保存并退出:
:wq!
注意:上面的Nginx配置只是将Nginx用作Web服务器而不是反向代理的示例配置。如果您使用Nginx作为反向代理,请删除最后两行中的#
字符并对它们进行适当的修改。
4.2创建一个名为/usr/local/nginx/conf/modsec_includes.conf
的文件:
cat <<EOF>> /usr/local/nginx/conf/modsec_includes.conf
include modsecurity.conf
include owasp-modsecurity-crs/crs-setup.conf
include owasp-modsecurity-crs/rules/*.conf
EOF
注意:上面的配置将应用owasp-modsecurity-crs/rules/
目录中的所有OWASP ModSecurity核心规则。如果您只想应用选择性规则,则应删除include owasp-modsecurity-crs/rules/*.conf
行,然后在步骤4.5之后指定所需的确切规则。
4.3导入ModSecurity配置文件:
cp /usr/src/ModSecurity/modsecurity.conf-recommended /usr/local/nginx/conf/modsecurity.conf
cp /usr/src/ModSecurity/unicode.mapping /usr/local/nginx/conf/
4.4修改/usr/local/nginx/conf/modsecurity.conf
文件:
sed -i "s/SecRuleEngine DetectionOnly/SecRuleEngine On/" /usr/local/nginx/conf/modsecurity.conf
4.5添加OWASP ModSecurity CRS(核心规则集)文件:
cd /usr/local/nginx/conf
git clone https://github.com/SpiderLabs/owasp-modsecurity-crs.git
cd owasp-modsecurity-crs
mv crs-setup.conf.example crs-setup.conf
cd rules
mv REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf
mv RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf.example RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf
第5步:测试ModSecurity
启动Nginx:
systemctl start nginx.service
打开80端口以允许外部访问:
a)在CentOS 7上:
firewall-cmd --zone=public --permanent --add-service=http
firewall-cmd --reload
b)在Debian 8上:
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
iptables -P INPUT DROP
iptables -P OUTPUT ACCEPT
iptables -P FORWARD DROP
touch /etc/iptables
iptables-save > /etc/iptables
c)在Ubuntu 16.04上:
ufw allow OpenSSH
ufw allow 80
ufw default deny
ufw enable
将您的网页浏览器指向:
http://203.0.113.1/?param="><script>alert(1);</script>
使用grep
来获取错误消息,如下所示:
grep error /usr/local/nginx/logs/error.log
输出应包含几个类似于以下内容的错误消息:
2017/02/15 14:07:54 [error] 10776#0: [client 104.20.23.240] ModSecurity: Warning. detected XSS using libinjection.
数据于 4年前 刷新
[line "56"] [id "941100"] [rev "2"] [msg "XSS Attack Detected via libinjection"] [data "Matched Data: found within ARGS:param: \x22><script>alert(1);</script>"] [severity "CRITICAL"] [ver "OWASP_CRS/3.0.0"] [maturity "1"] [accuracy "9"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-xss"] [tag "OWASP_CRS/WEB_ATTACK/XSS"] [tag "WASCTC/WASC-8"] [tag "WASCTC/WASC-22"] [tag "OWASP_TOP_10/A3"] [tag "OWASP_AppSensor/IE1"] [tag "CAPEC-242"] [hostname ""] [uri "/index.html"] [unique_id "ATAcAcAkucAchGAcPLAcAcAY"]
它生效了。如您所见,ModSecurity模块已根据其默认操作策略成功记录此次攻击。如果您想进行更多自定义设置,请仔细查看并编辑/usr/local/nginx/conf/modsecurity.conf
和/usr/local/nginx/conf/owasp-modsecurity-crs/crs-setup.conf
文件。