nginxでWAF(Web Application Firewall) を作る(第三回) — | サイオスOSS | サイオステクノロジー

nginxでWAF(Web Application Firewall) を作る(第三回)

前回と同様に、引き続きnginx+ModSecurityによるWAFの作成を行います。

こんにちは。SIOS OSSエバンジェリスト/セキュリティ担当の面です。

数回に分けて、nginxでWAFをつくる方法を紹介しています。

前回、nginxとmod_securityのパッケージを作成しました。今回は、前回の作業で作成されたnginxとmodsecurityをインストールし、設定をしてい>きます。


nginxのバージョンアップについて

前回の記事公開の後、nginxもバージョンが上がっており、現在(2016/04/19)は1.9.14が最新となっています。

各バージョンアップの内容に関しては、下記のリンクに細かい記載があります。

今回の記事では最新のものを使用しますので、前回の記事でのnginx-1.9.12を1.9.14に更新します。

nginxのソースパッケージは、nginxのサイト: http://nginx.org/packages/mainline/rhel/7/SRPMS/から取得します。

今回は、nginx-1.9.14-1.src.rpmをダウンロードします。

  1. “rpm -Uvh nginx-1.9.14-1.src.rpm”として、nginx-1.9.14-1のSOURCE/SPECファイルを展開します。
  2. SPECファイルの、前回の記事と同じ箇所(“3. nginxのリビルド”を参照)を修正します。
    --with-ipv6 \
    --add-module=/home/sios/rpmbuild/BUILD/modsecurity-2.9.1/nginx/modsecurity \
    %{?with_http2:--with-http_v2_module}")
    
  3. 今回のnginxのバージョンでは、リビルドに”perl-devel”, “perl-ExtUtils-Embed”が必要になるので、これらをインストールします。
    [root@localhost ~]# yum -y install perl-devel perl-ExtUtils-Embed
    --snip--
    依存性関連をインストールしました:
    gdbm-devel.x86_64 0:1.10-8.el7
    perl-ExtUtils-Install.noarch 0:1.58-286.el7
    perl-ExtUtils-MakeMaker.noarch 0:6.68-3.el7
    perl-ExtUtils-Manifest.noarch 0:1.61-244.el7
    perl-ExtUtils-ParseXS.noarch 1:3.18-2.el7
    systemtap-sdt-devel.x86_64 0:2.8-10.el7
    完了しました!
    
  4. 前回と同様に、”rpmbuild”コマンドでnginxパッケージをリビルドします。
    [sios@localhost SPECS]$ rpmbuild -ba --target=x86_64 ./nginx.spec
    ビルド対象プラットフォーム: x86_64
    ターゲット x86_64 用にビルド中
    --snip--
    実行中(%clean): /bin/sh -e /var/tmp/rpm-tmp.YUbb9Z
    + umask 022
    + cd /home/sios/rpmbuild/BUILD
    + cd nginx-1.9.14
    + /usr/bin/rm -rf /home/sios/rpmbuild/BUILDROOT/nginx-1.9.14-1.el7.centos.ngx.x86_64
    + exit 0
    
  5. RPMS/x86_64以下にnginx-1.9.14-1のパッケージが作成されます。
    [sios@localhost x86_64]$ pwd
    /home/sios/rpmbuild/RPMS/x86_64
    [sios@localhost x86_64]$ ls nginx*
    nginx-1.9.14-1.el7.centos.ngx.x86_64.rpm
    nginx-debuginfo-1.9.14-1.el7.centos.ngx.x86_64.rpm
    nginx-module-geoip-1.9.14-1.el7.centos.ngx.x86_64.rpm
    nginx-module-image-filter-1.9.14-1.el7.centos.ngx.x86_64.rpm
    nginx-module-njs-0.0.20160329.91543c86f412-2.el7.centos.ngx.x86_64.rpm
    nginx-module-perl-1.9.14-1.el7.centos.ngx.x86_64.rpm
    nginx-module-xslt-1.9.14-1.el7.centos.ngx.x86_64.rpm
    

ネットワーク構成

今回作るnginx+WAFですが、既存のWebサーバになるべく手を掛けずに保護するという形にしたいため、下のようなネットワーク構成で作成します。

ネットワーク構成図

外部(アクセステストを行う)ホスト、ngin+WAFのホスト、ターゲットのホストはそれぞれ

  • ext.localdomain
  • nginx.localdomain
  • target.localdomain

となっています。これらは、/etc/hostsファイルに直接書き込んで、全てのホスト間で名前解決ができるようにしてあります。

Virtualboxを使って検証環境を作成しているためにこのようなネットワークになっていますが、実運用環境では負荷分散のための複数NICなど、別途環境に合わせて下さい。

今回の検証環境では、nginx+WAFにPort80で接続すると、適切にフィルタリングを行い、tomcatがPort8080で動作しているマシンにフォワードします。


構築


1. nginx/mod_securityパッケージのインストール

インストール自体は単純に”rpm -ivh 「nginxのパッケージ」「mod_securityのパッケージ」”で完了します。

バージョンアップ等でバージョンを更新したい際には”rpm -Uvh”オプションで実施すれば、パッケージを新しい物に更新してくれます。

以下は、nginxのパッケージを-Uvhオプションで更新した際の例です。

[root@cent7mini sios]# rpm -Uvh ./nginx-1.9.14-1.el7.centos.ngx.x86_64.rpm
準備しています...              ################################# [100%]
更新中 / インストール中...
1:nginx-1:1.9.14-1.el7.centos.ngx  ################################# [ 50%]
整理中 / 削除中...
2:nginx-1:1.9.12-1.el7.centos.ngx  ################################# [100%]
[root@cent7mini sios]# rpm -qa|grep nginx

インストール後、確認のため、”systemctl start nginx”でnginxを起動します。外部ホスト(ext.localdomain)からhttp://nginx.localdomainにアクセスすると、下記のような画面が表示されます。

nginx_site


2. nginxの設定

  1. まず、nginx(192.168.56.102)にPort80で接続すると、tomcat(192.168.56.101、Port8080)に転送を行うようにnginxを設定します。/etc/nginx/conf.d/default.confを修正します。
    server {
    listen       80;
    server_name  nginx.localdomain;
    #charset koi8-r;
    #access_log  /var/log/nginx/log/host.access.log  main;
    proxy_set_header    X-Real-IP       $remote_addr;
    proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header    Host            $http_host;
    proxy_redirect      off;
    proxy_max_temp_file_size    0;
    location / {
    proxy_pass http://target.localdomain:8080;
    root   /usr/share/nginx/html;
    index  index.html index.htm;
    }
    

    listen、及びserver_nameは、nginx/WAFのListenポート番号とIPアドレス(又はFQDN)を指定します。

    proxy_set_header句では、X-Forwarded-Forなどのヘッダをセットしています。

    location / 以下の”proxy_pass”句で、リクエストの転送先とポート番号を設定します。

  2. インストール後、確認のため、”systemctl start nginx”でnginxを起動します。外部ホスト(ext.localdomain)からhttp://nginx.localdomainにアクセスすると、下記のように、192.168.56.101:8080に転送され、画面(サンプルではtomcat)が表示されます。

nginx_forwarded


3. ModSecurityの設定

  1. /etc/nginx/mod_security.confを下記のように修正します。
    1. “SecRuleEngine DetectionOnly”を”SecRuleEngine On”に変更します。
    2. “SecUnicodeMapFile unicode.mapping 20127″を”#SecUnicodeMapFile unicode.mapping 20127″と、コメントにして読まないようにします。
    3. 設定ファイルの最後に、他の設定ファイル(ルールファイル)を読み込むように、行を付け加えます
      # Load all Rule
      Include modsecurity.d/*.conf
      Include modsecurity.d/activated_rules/*.conf
      Include modsecurity.d/local_rules/*.conf
      
  2. 次に、/etc/nginx/conf.d/default.confを下記のように修正します。
        location / {
    #Enable ModSecurity
    
  3. 設定ファイルの修正が終わったら、”systemctl restart nginx”で、nginxを再起動します。

4. ModSecurityのテスト

    1. 外部ホスト(ext.localdomain)からhttp://nginx.localdomainにアクセスすると、通常のtarget.localdomainの画面と同じものが表示されますが、http://nginx.localdomain/?union+selectにアクセスすると”403 Forbidden”が表示されます。WAF_Reject
    2. この時、/var/log/modsec_audit.logには、下記のようなメッセージが表示されています。
      Message: Access denied with code 403 (phase 2). Pattern match "(?i:\\b(?:(?:s(?:t(?:d(?:dev(_pop|_samp)?)?|r(?:_to_date|cmp))|u(?:b(?:str(?:ing(_index)?)?|(?:dat|tim)e)|m)|e(?:c(?:_to_time|ond)|ssion_user)|ys(?:tem_user|date)|ha(1|2)?|oundex|chema|ig?n|pace|qrt)|i(?:s(null|_(free_lock|ipv4_compat|ipv4_mapped|ipv4| ..." at ARGS_NAMES:union select. [file "/etc/nginx/modsecurity.d/activated_rules/modsecurity_crs_41_sql_injection_attacks.conf"] [line "125"] [id "950001"] [rev "2"] [msg "SQL Injection Attack"] [data "Matched Data: union select found within ARGS_NAMES:union select: union select"] [severity "CRITICAL"] [ver "OWASP_CRS/2.2.9"] [maturity "9"] [accuracy "8"] [tag "OWASP_CRS/WEB_ATTACK/SQL_INJECTION"] [tag "WASCTC/WASC-19"] [tag "OWASP_TOP_10/A1"] [tag "OWASP_AppSensor/CIE1"] [tag "PCI/6.5.2"]
      Action: Intercepted (phase 2)
      Apache-Handler: IIS
      Stopwatch: 1460821546000764 764120 (- - -)
      Stopwatch2: 1460821546000764 764120; combined=402, p1=98, p2=269, p3=0, p4=0, p5=35, sr=8, sw=0, l=0, gc=0
      Producer: ModSecurity for nginx (STABLE)/2.9.1 (http://www.modsecurity.org/); OWASP_CRS/2.2.9.
      Server: ModSecurity Standalone
      Engine-Mode: "ENABLED"
      

まとめ

今回はnginxとmodsecurityのパッケージのインストール方法と、WAFの簡単な組み立てまでを説明しました。

次回は更に細かくmodsecurityのルールについて、更に細かくみていきます。


—–

タイトルとURLをコピーしました