現在位置: ホーム / セキュリティ ブログ / nginxでWAF(Web Application Firewall) を作る(第三回)

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のルールについて、更に細かくみていきます。


OSSよろず相談室

サイオスOSSよろず相談室(2)

問い合わせボタン

最新の記事
Apache httpd に複数の脆弱性 ( CVE-2017-3167, CVE-2017-3169, CVE-2017-7659, CVE-2017-7668, CVE-2017-7679 ) 2017年06月20日
Apache mod_http2の脆弱性 ( CVE-2017-7659 ) 2017年06月20日
linux kernelにStack Guard Page迂回の脆弱性( CVE-2017-1000364 ) 2017年06月20日
glibcにStack Guard Page迂回の脆弱性(CVE-2017-1000366) 2017年06月20日
GnuTLS の 脆弱性 (GNUTLS-SA-2017-4 : CVE-2017-7507 ) 2017年06月17日
bind 9 に緊急を含む複数の脆弱性 ( CVE-2017-3140 , CVE-2017-3141 ) 2017年06月15日
linux kernelの脆弱性( CVE-2017-1000380 ) 2017年06月14日
libgcryptの脆弱性( CVE-2017-9526 ) 2017年06月12日
cronの脆弱性(CVE-2017-9525) 2017年06月11日
SambaにDoSの脆弱性(CVE-2017-9461) 2017年06月07日
Tomcatの脆弱性 ( CVE-2017-5664 ) 2017年06月07日
sudoに任意のコマンド実行と情報漏えいの脆弱性( CVE-2017-1000368 ) 2017年06月06日
wiresharkに複数の脆弱性(CVE-2017-9343, CVE-2017-9344, CVE-2017-9345, CVE-2017-9346, CVE-2017-9347, CVE-2017-9348, CVE-2017-9349, CVE-2017-9350, CVE-2017-9351, CVE-2017-9352, CVE-2017-9353, CVE-2017-9354 ) 2017年06月03日
Xenの複数の脆弱性 (XSA-213: CVE-2017-8903 / XSA-214: CVE-2017-8904 / XSA-215: CVE-2017-8905) 2017年06月03日
Keycloak Node.js adapterの脆弱性( CVE-2017-7474 ) 2017年06月02日
FreeRADIUSの脆弱性 ( CVE-2017-9148 ) 2017年06月01日
OpenLDAPの脆弱性 ( CVE-2017-9287 ) 2017年05月31日
sudoに完全な特権昇格の脆弱性( CVE-2017-1000367 ) 2017年05月31日
linux kernelの脆弱性( CVE-2017-9242 ) 2017年05月27日
Zabbixの脆弱性( CVE-2017-2824 ) 2017年05月27日
最新の記事 - もっと...