現在位置: ホーム / セキュリティ ブログ / 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)

問い合わせボタン

最新の記事
Sambaに共有以外のファイルにアクセスされる脆弱性(CVE-2017-2619) 2017年03月24日
Subscription-managerの脆弱性( CVE-2017-2663 ) 2017年03月22日
binutilsに複数の脆弱性( CVE-2017-6965, CVE-2017-6966, CVE-2017-6969, CVE-2017-7209 , CVE-2017-7210 , CVE-2017-7223, CVE-2017-7224, CVE-2017-7225, CVE-2017-7226, CVE-2017-7227 ) 2017年03月22日
linux kernelの脆弱性( CVE-2017-7187 ) 2017年03月21日
linux kernelの脆弱性( CVE-2017-6353 , CVE-2017-5986 ) 2017年03月21日
Ubuntu 16.10のkernelの脆弱性( CVE-2017-7184 ) 2017年03月20日
pcreの脆弱性( CVE-2017-7186 ) 2017年03月20日
binutilsの脆弱性( CVE-2017-6965 , CVE-2017-6966 , CVE-2017-6969 ) 2017年03月19日
MySQL(MariaDB) 5.5/5.6のmysql clientの脆弱性( Riddle : CVE-2017-3305 ) 2017年03月18日
linux kernelの脆弱性( CVE-2017-6951 ) 2017年03月17日
Apache Struts2の脆弱性 ( CVE-2017-5638 ) 2017年03月15日
linux kernelの脆弱性( CVE-2017-6874 ) 2017年03月15日
tomcatに情報漏えいの脆弱性( CVE-2016-8747 ) 2017年03月14日
QEMUの脆弱性( CVE-2016-9603 ) (Xen: XSA-211) 2017年03月14日
lxcの脆弱性(CVE-2017-5985) 2017年03月10日
wgetの脆弱性(CVE-2017-6508) 2017年03月08日
linux kernelに特権昇格の脆弱性( CVE-2017-2636 ) 2017年03月08日
( PoC ) linux kernel特権昇格脆弱性( CVE-2017-6074 ) の暫定回避策の確認 2017年03月06日
linux kernelの脆弱性( CVE-2016-9083 , CVE-2016-9084 ) 2017年03月03日
linux kernelに複数の脆弱性( CVE-2017-6345 , CVE-2017-6346 , CVE-2017-6347 , CVE-2017-6348 ) 2017年03月01日
Katello/Foremanによる運用管理 (Part4) 2017年02月28日
util-linux / coreutils の脆弱性(CVE-2017-2616) 2017年02月24日
linux kernelの脆弱性( CVE-2017-6214 ) 2017年02月24日
linux kernelに特権昇格の脆弱性( CVE-2017-6074 ) 2017年02月23日
curlの脆弱性 ( CVE-2017-2629 ) 2017年02月22日
QEMUの脆弱性( CVE-2017-2620 ) (Xen: XSA-209) 2017年02月22日
Tomcatの脆弱性 ( CVE-2017-6056 ) 2017年02月21日
Katello/Foremanによる運用管理 (Part3) 2017年02月21日
OpenSSLの脆弱性 ( CVE-2017-3733 ) 2017年02月16日
linux kernelの脆弱性( CVE-2017-6001 , (was CVE-2016-6786) ) 2017年02月16日
QEMUの脆弱性( CVE-2017-2630 ) 2017年02月15日
glibcの脆弱性(CVE-2015-8982, CVE-2015-8983, CVE-2015-8984) 2017年02月15日
vimの脆弱性 ( CVE-2017-5953 ) 2017年02月14日
Oracle Javaの脆弱性(Oracle Critical Patch Update Advisory - January 2017) 2017年02月14日
libxml2の脆弱性(CVE-2017-5969) 2017年02月13日
「linux kernel-4.9」でのLSMモジュールについて 2017年02月13日
linux kernelの脆弱性( CVE-2017-5970 ) 2017年02月13日
linux kernelの脆弱性( CVE-2016-8636 ) 2017年02月12日
bind 9 に設定依存の脆弱性 ( CVE-2017-3135 ) 2017年02月09日
bashの自動補完機能の脆弱性( CVE-2017-5932 ) 2017年02月08日
spiceの脆弱性( CVE-2016-9577 , CVE-2016-9578 ) 2017年02月08日
QEMUの脆弱性( CVE-2017-5898 ) 2017年02月08日
linux kernelの脆弱性( CVE-2017-5897 ) 2017年02月08日
linux kernelの脆弱性( CVE-2016-10208 ) 2017年02月06日
ntfs-3gの脆弱性(CVE-2017-0358) 2017年02月02日
QEMUの脆弱性( CVE-2017-2615 ) 2017年02月02日
tcpdumpに複数の脆弱性(CVE-2016-7922 等) 2017年01月30日
libgdに複数の脆弱性情報 (CVE-2016-9317, CVE-2016-6912, CVE-2016-10167, CVE-2016-10168, CVE-2016-10169) 2017年01月29日
OpenSSLに複数の脆弱性 ( CVE-2017-3730 , CVE-2017-3731 , CVE-2017-3732 ) 2017年01月27日
RunCに関しての脆弱性( CVE-2016-9962 )のPoCとSELinuxによるリスクの軽減 2017年01月26日
systemdの重要な脆弱性( CVE-2016-10156 ) 2017年01月25日
linux kernelの複数の脆弱性( CVE-2016-10153, CVE-2016-10154, CVE-2017-5547, CVE-2017-5548, CVE-2017-5549, CVE-2017-5550, CVE-2017-5551) 2017年01月25日
Katello/Foremanによる運用管理 (Part2) 2017年01月24日
linux kernel(KVMを有効にしている場合)で複数の脆弱性( CVE-2016-10150, CVE-2017-2583 ) 2017年01月21日
OpenSCAP 1.2.13のリリース情報 2017年01月16日
Oracle Javaの脆弱性(CVE-2016-5542, CVE-2016-5554, CVE-2016-5582, CVE-2016-5597, CVE-2016-5573) 2017年01月13日
bind に複数の脆弱性 ( CVE-2016-9131 , CVE-2016-9147 , CVE-2016-9444 , CVE-2016-9778 ) 2017年01月12日
Dockerに特権昇格の脆弱性 ( CVE-2016-9962 ) 2017年01月11日
GnuTLS の 脆弱性 (GNUTLS-SA-2017-1 : CVE-2017-5334 , GNUTLS-SA-2017-2 : CVE-2017-5335 , CVE-2017-5336 , CVE-2017-5337 ) 2017年01月11日
OpenSSLの脆弱性(CVE-2016-7056 ) 2017年01月11日
最新の記事 - もっと...