ModSecurity 3.0 —— 强大的 WAF 工具

关于 ModSecurity 3.0

ModSecurity 其实也有很久的历史了,原本是 Apache 上的一款开源 WAF 模块,可以有效的增强 Web 安全性。然后逐渐支持Nginx 和 IIS,配合 Nginx 的灵活和高效可以打造成生产级的 WAF,是保护和审核 Web 安全的利器。

ModSecurity 2.0 时代,ModSecurity 对于 Nginx 的支持一直很不完善,性能损耗比较大,还有内存泄漏的 bug 一直没有很好的解决,所以使用 Naxsi 会相对更好一些。然而到了 ModSecurity 3.0 时代,情况反转了,得益于 libmodsecurity 的引入,ModSecurity 与 Nginx 兼容性、性能方面都大大提升。于此同时,ModSecurity 3.0 还作为 Nginx-Plus 官方钦定 WAF 引入了商业市场,有官方背书,可靠性自然得以保证。反观 Naxsi,在诸如 HTTP/2 等新特性支持方面一直慢半拍。

Nginx-Plus 的 WAF 是作为一个商业产品售卖的,然而实际上就是官方帮你编译好了一个 libmodsecurity,普通用户无需购买几千刀一年的 Nginx-Plus,也可以享受到 ModSecurity 3.0 这款优秀的防火墙。

安装 ModSecurity 3.0

编译 libmodsecurity

编译 libmodsecurity 需要的硬件配置其实是蛮高的,性能低一些的机器(1U 512M 那种)基本是很难编译成功的。
  • 首先安装必备软件包:
apt install -y apt-utils autoconf automake build-essential git libcurl4-openssl-dev libgeoip-dev liblmdb-dev libpcre++-dev libtool python-dev libxml2-dev libyajl-dev pkgconf wget zlib1g-dev screen liblua5.3-dev
  • 下载并编译 libmodsecurity:
git clone --depth 1 -b v3/master --single-branch https://github.com/SpiderLabs/ModSecurity.git && cd ModSecurity
git submodule init && git submodule update
./build.sh && ./configure
screen make && make install

make 花费的时间应该比较久,可以耐心的喝杯茶等待

编译 Modsecurity-Nginx

git clone --depth 1 https://github.com/SpiderLabs/ModSecurity-nginx.git

在编译 Nginx 时加上参数 --with-compat --add-module=../ModSecurity-nginx 即可。

带上这个模块的话,Nginx 的编译也要用上不少时间。

配置 ModSecurity 和 OWASP-CRS 规则:

这部分的设置其实比较复杂,首先解释一下什么是 OWASP-CRS,OWASP 是一个安全社区,开发和维护着一套免费的应用程序保护规则,这就是所谓 OWASP 的 ModSecurity 的核心规则集(即CRS)。ModSecurity 之所以强大就在于 OWASP 提供的规则,我们可以根据自己的需求选择不同的规则,也可以通过 ModSecurit y手工创建安全过滤器、定义攻击并实现主动的安全输入验证。

ModSecurity CRS 提供以下类别的保护来防止攻击:

HTTP Protection(HTTP防御);
Real-time Blacklist Lookups(实时黑名单查询);
HTTP Denial of Service Protections(HTTP的拒绝服务保护);
Common Web Attacks Protection(常见的Web攻击防护);
Automation Detection(自动化检测);
Integration with AV Scanning for File Uploads(文件上传防病毒扫描);
Tracking Sensitive Data(跟踪敏感数据);
Trojan Protection(木马防护);
Identification of Application Defects(应用程序缺陷的鉴定);
Error Detection and Hiding(错误检测和隐藏)

安装配置 ModSecurity CRS

  • 创建配置和规则文件
cd /etc/nginx && git clone --depth 1 -b v3.0/master https://github.com/SpiderLabs/owasp-modsecurity-crs.git modsec && cd modsec

wget https://raw.githubusercontent.com/SpiderLabs/ModSecurity/v3/master/modsecurity.conf-recommended && mv modsecurity.conf-recommended modsecurity.conf && mv crs-setup.conf.example crs-setup.conf && cd rules && mv RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf.example RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf && mv REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf && cd ..

sed -i 's/SecRuleEngine DetectionOnly/SecRuleEngine On/' /etc/nginx/modsec/modsecurity.conf

cat >> /etc/nginx/modsec/main.conf << EOF
# Include the recommended configuration
Include /etc/nginx/modsec/modsecurity.conf
# OWASP CRS v3 rules
Include /etc/nginx/modsec/crs-setup.conf
Include /etc/nginx/modsec/rules/*.conf
EOF
  • 在 Nginx vhost 配置中引入

我的配置直接写在了 Typecho 全局 location 的位置:

location / {
    try_files $uri $uri/ /index.php$is_args$args;
    modsecurity on;
    modsecurity_rules_file /etc/nginx/modsec/main.conf;
}

进一步修改和增强 crs-setup.conf

修改被屏蔽的措施

找到 SecDefaultAction 配置项,默认的情况是 phase:1,log,auditlog,pass 将其# 注释,然后找到 SecDefaultAction "phase:1,log,auditlog,deny,status:403" 这对应两行,取消注释,然后将 status 设置为 444,即如果触犯规则直接拒绝相应,或者你也可以选择 SecDefaultAction "phase:1,log,auditlog,redirect:'http://%{request_headers.host}/',tag:'Host: %{request_headers.host}'",并且设置跳转页面,即如果触犯规则就跳转到某个页面。

HTTP Policy Settings

SecAction \
 "id:900200,\
  phase:1,\
  nolog,\
  pass,\
  t:none,\
  setvar:'tx.allowed_methods=GET HEAD POST OPTIONS'"

找到这一块设置,并且取消注释,即只允许特定的 HTTP 访问方式。

Project Honey Pot HTTP Blacklist

Honey Pot 即俗称的“蜜罐”,由专业公司维护,通过公开蜜罐的方式采集了一大批从事网络攻击的 Bad IP
官网 注册并获取 API KEY,然后修改如下配置:

SecHttpBlKey xxxxxxxxx (填你的API KEY)
SecAction "id:900500,\
  phase:1,\
  nolog,\
  pass,\
  t:none,\
  setvar:tx.block_search_ip=1,\
  setvar:tx.block_suspicious_ip=1,\
  setvar:tx.block_harvester_ip=1,\
  setvar:tx.block_spammer_ip=1"

GEO IP
如果你想屏蔽特定国家的 IP,可以修改如下配置:

SecGeoLookupDB util/geo-location/GeoIP.dat

SecAction \
 "id:900600,\
  phase:1,\
  nolog,\
  pass,\
  t:none,\
  setvar:'tx.high_risk_country_codes='UA ID YU LT EG RO BG TR RU PK MY CN"

更新 GEO IP 库需要在 /etc/nginx/modsec/util 下执行 python upgrade.py --geoip
然后在 tx.high_risk_country_codes 中填写要屏蔽的国别缩写即可。

DDoS Protection

这边的防护属于 L7 防御,单个 IP 在某指定段时间访问过于频繁就予以屏蔽。
有个优点是这边的屏蔽只计算动态访问而不考虑静态文件,因为 Nginx 处理静态文件非常高效一般不是瓶颈。

SecAction \
 "id:900700,\
  phase:1,\
  nolog,\
  pass,\
  t:none,\
  setvar:'tx.dos_burst_time_slice=10',\
  setvar:'tx.dos_counter_threshold=20',\
  setvar:'tx.dos_block_timeout=86400'"

基本的介绍就这么多,还有更高级的配置这边就不多介绍了。

接下来 service nginx restart 然后享受 ModSecurity 3.0 带来的防护吧。

Last modification:March 26th, 2018 at 03:22 pm

Leave a Comment