在这个备忘录(ModSecurity)中,创建一个简易的WAF来阻断包含特定字符串参数的请求

首先

因为想要进行一些简单的验证和确认,我想快速地构建一个WAF,这是当时的备忘录。
尽管发现了owasp/modsecurity的Docker镜像,但在提供的环境变量列表中,并没有设置阻断包含特定字符串的请求的变量,这是触发的原因。

要做的事

使用OWASP提供的ModSecurity的Docker镜像,创建一个能够阻止包含参数中包含“test”关键词的GET/POST请求的WAF。
ModSecurity提供了apache、nginx和IIS三种不同的镜像,但本次我们将使用nginx。
如果想要创建一个更加完善的WAF,我建议加入包含核心规则集(CRS)在内的配置,但本次不会涉及到那些内容。

环境

% sw_vers
ProductName:	macOS
ProductVersion:	11.6
BuildVersion:	20G165
% docker --version
Docker version 20.10.12, build e91ed57
% docker-compose --version
docker-compose version 1.29.2, build 5becea4c

做过的事情

最终准备的文件和目录如下所示。

% tree .
.
├── docker-compose.yml
├── modsecurity
│   ├── custom-error.html
│   ├── default.conf
│   ├── index.html
│   ├── log
│   └── modsecurity.conf
└── nginx
    ├── default.conf
    ├── index.html
    └── succeeded.html

以下是docker-compose.yml文件的内容。
在这里,waf主要是指ModSecurity,nginx被配置为waf后端的应用程序服务器。

version: "3"

services:

  waf:
    image: owasp/modsecurity:nginx
    ports:
      - "8080:80"
    restart: always
    volumes:
      - ./modsecurity/default.conf:/etc/nginx/conf.d/default.conf
      - ./modsecurity/index.html:/var/www/html/index.html
      - ./modsecurity/custom-error.html:/var/www/html/custom-error.html
      - ./modsecurity/modsecurity.conf:/etc/modsecurity.d/modsecurity-override.conf 
      - ./modsecurity/log:/var/log/nginx
    container_name: waf-nginx
    networks:
      - default

  nginx:
    image: nginx:1.20.2
    ports:
      - "80:80"
    restart: always
    volumes:
      - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
      - ./nginx/index.html:/var/www/html/index.html
      - ./nginx/succeeded.html:/var/www/html/nginx/index.html
    container_name: nginx
    networks:
      - default

networks:
  default:

应用服务器(nginx)的配置

在nginx目录下,我们配置了3个nginx的设置文件。
当请求通过waf进来时,我们显示”nginx-succeeded”这个字符串。
为了进行启动时的连通性检查,我们进行了location /的设置。
我们还通过配置error_page来使POST请求返回相同的结果。

server {
    listen       80;
    listen  [::]:80;
    server_name  localhost;

    location /nginx/ {
        root /var/www/html;
        index index.html;
    }

    location / {
        root /var/www/html;
        index index.html;
    }

    error_page 405 =200 $uri;

}
nginx
nginx-succeeded

WAF(基于nginx的ModSecurity)的设置

以下是nginx的配置(default.conf)内容。关于location,当收到http://localhost/nginx的请求时,会将请求传递给后端的nginx。如果请求被ModSecurity拦截,HTTP状态码将变为403,并显示字符串”modsecurity-blocked!”。

server {
    listen       80;
    listen  [::]:80;
    server_name  localhost;

    location / {
        root /var/www/html;
        index index.html;
    }

    location /nginx {
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_redirect http:// https://;
        proxy_pass http://nginx/nginx/;
    }

    error_page 403 /custom-error.html;

    location = /custom-error.html {
        root /var/www/html;
        internal;
    }
}

以下是ModSecurity的配置。
其中两个重要点如下。

SecRuleEngine On … デフォルトがDetectionOnlyになっていて、検知だけして遮断しない設定なので、遮断するようにOnを指定。

SecRule ARGS_NAMES “test” … このSecRuleがdockerコンテナに渡す環境変数として用意されていないので、configファイルを書いてコンテナに渡すようにしました。この設定でGETやPOSTなどのリクエストのパラメータ名が”test”であれば、ログ出力して遮断する設定にしています。POSTだとRequest Bodyを見ないといけないので、”phase:2″を指定しているところが注意点。

SecRuleEngine On
SecRequestBodyAccess On
SecAuditEngine On
SecAuditLog /var/log/nginx/modsec_audit.log
SecAuditLogParts ABCFHZ
SecRule ARGS_NAMES "test" "id:3,phase:2,t:lowercase,deny,log"
modsecurity
modsecurity-blocked!

确认动作

我先运行了docker-compose up -d,然后使用Google Chrome的Advanced REST Client进行了操作确认。

modsecurity.gif

总结

我已經製作了一個簡單的WAF。
雖然SecRule部分有很多參數,也可以使用正則表達式等更多功能,但ARGS_POST無法正常運行且使我遇到了困難。最終,我通過使用ARGS或ARGS_NAMES解決了這個問題,但如果再次有機會接觸,我會更深入地進行研究。

请参考

    • https://qiita.com/housu_jp/items/1c0204c8cf0ce32a7605

 

    • https://atmarkit.itmedia.co.jp/ait/articles/1409/18/news010_4.html

 

    • https://coreruleset.org/docs/rules/creating/

 

    • https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual-(v2.x)

 

    • https://hub.docker.com/r/owasp/modsecurity

 

    https://qiita.com/ryounagaoka/items/fd641e39a196b47db875
广告
将在 10 秒后关闭
bannerAds