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

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

数回に分けて、「nginxでWAFを作る」というコンテンツを公開しています。 第二回は、nginx/mod_securityのRPMパッケージ作成について説明します。

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

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

今回は、nginx+ModSecurityのインストールパッケージを作成します。


ModSecurityとは

ModSecurityは、米国「Trustware」社からGPLv2で提供されている、OSSのWeb Application Firewall(WAF)です。このModSecurityは、Apacheやnginxのモジュールとして動作します。今回は、このModSecurityをnginxと組み合わせて使用してみます。


インストール環境

今回、インストール環境としてCentOS7を使用します。また、nginxとModSecurityは、今後の管理の事を考えて、ソースからではなくパッケージを用いてインストールすることとします。

ngixとModSecurityを組み合わせて使用する際には、ModSecurity/nginx双方のコンパイルオプションを修正しなくてはならないため、SRPMパッケージを用いて自前のパッケージを作成することとします。

ダウンロードすることとします。

今回使用したバージョンは

  • nginx-1.9.12-1.el7.ngx.src.rpm

  • mod_security-2.9.1-1.fc25.src.rpm

  • mod_security_crs-2.2.9.20160219git-1.fc25.src.rpm

となっています。

#nginxは、2016年3月29日に1.9.13がリリースされましたが、今回は1.9.12を使用しています。

また、今回はソースからリビルドするために、本来の運用上は不要なパッケージもインストールする必要があります。WAFの動作確認の際には問題ありませんが、実際に運用に使用する場合には、パッケージ作成用の(リビルド時に必要なパッケージもインストールされている)マシンでパッケージのリビルドを行い、リビルドしたパッケージを運用用途のサーバに個別にインストールする方が良いと思われます。


1. ModSecurityのリビルド

  1. まずは作業用ユーザ(例ではsios)で、"rpm -ivh mod_security_XXX.src.rpm"として、ソースパッケージをインストールします。

  2. リビルド時に必要なパッケージ(lua-devel, yajl-devel)をyumを使ってインストールします。

  3. "/home/sios/rpmbuild/SPECS"以下にSPECファイル(mod_security.spec)がありますので、こちらを下記のように修正します。

  4. # /etc/httpd/conf.d with httpd < 2.4 and defined as /etc/httpd/conf.modules.d wi
    th httpd >= 2.4
    %{!?_httpd_modconfdir: %{expand: %%global _httpd_modconfdir %%{_sysconfdir}/ngin
    x/conf.d}}
    %{!?_httpd_confdir:    %{expand: %%global _httpd_confdir    %%{_sysconfdir}/ngin
    x/conf.d}}
    %{!?_httpd_moddir:    %{expand: %%global _httpd_moddir    %%{_libdir}/nginx/modu
    les}}
    ---------------------snip-------------------------------------
    %build
    export CFLAGS='-DDEFAULT_USER=\"nginx\" -DDEFAULT_GROUP=\"nginx\"';
    %configure --enable-pcre-match-limit=1000000 \
               --enable-pcre-match-limit-recursion=1000000 \
               --with-apxs=%{_httpd_apxs} \
               --with-yajl \
               --enable-standalone-module
    
    ---------------------snip-------------------------------------
    install -d %{buildroot}%{_bindir}
    install -d %{buildroot}%{_libdir}/nginx
    install -d %{buildroot}%{_sysconfdir}/nginx/modsecurity.d/
    install -d %{buildroot}%{_sysconfdir}/nginx/modsecurity.d/activated_rules
    install -d %{buildroot}%{_sysconfdir}/nginx/modsecurity.d/local_rules
    
    install -m0755 apache2/.libs/mod_security2.so %{buildroot}%{_libdir}/nginx/mod_security2.so
    
    %if "%{_httpd_modconfdir}" != "%{_httpd_confdir}"
    # 2.4-style
    install -Dp -m0644 %{SOURCE2} %{buildroot}%{_sysconfdir}/nginx/10-mod_security.conf
    install -Dp -m0644 %{_builddir}/modsecurity-%{version}/modsecurity.conf-recommended  %{buildroot}%{_sysconfdir}/nginx/mod_security.conf
    sed  -i 's/Include/IncludeOptional/'  %{buildroot}%{_sysconfdir}/nginx/mod_security.conf
    %else
    # 2.2-style
    install -d -m0755 %{buildroot}%{_sysconfdir}/nginx
    cat %{SOURCE2} %{SOURCE1} > %{buildroot}%{_sysconfdir}/nginx/mod_security.conf
    %endif
    install -m 700 -d $RPM_BUILD_ROOT%{_localstatedir}/lib/%{name}
    
    # Local rules example
    install -Dp -m0644 %{SOURCE3} %{buildroot}%{_sysconfdir}/nginx/modsecurity.d/local_rules/
    ---------------------snip-------------------------------------
    %files
    %doc CHANGES LICENSE README.TXT NOTICE
    %{_libdir}/nginx/mod_security2.so
    %config(noreplace) %{_sysconfdir}/nginx/*.conf
    %if "%{_httpd_modconfdir}" != "%{_sysconfdir}/nginx"
    %config(noreplace) %{_sysconfdir}/nginx/*.conf
    %endif
    %dir %{_sysconfdir}/nginx/modsecurity.d
    %dir %{_sysconfdir}/nginx/modsecurity.d/activated_rules
    %dir %{_sysconfdir}/nginx/modsecurity.d/local_rules
    %config(noreplace) %{_sysconfdir}/nginx/modsecurity.d/local_rules/*.conf
    %attr(770,apache,root) %dir %{_localstatedir}/lib/%{name}
    ---------------------snip-------------------------------------
    
    1. ModSecurity関連のファイルは、今回nginxと連携させるに辺り、/etc/nginx, /usr/lib64/nginx以下などに配置したかったため、"_httpd_confdir"等のディレクトリは適宜"/etc/nginx/conf.dir"等に変更しています。

    2. CFLAGSとして"DEFAULT_USER"/"DEFAULT_GROUP"をそれぞれ"nginx"に設定しています。これをやっておかないと、ModSecurity/nginxをインストール後にnginxサーバが(正常であれ異常であれ)アクセスを受けた際に、/var/log/nginx/error.log等に「ModSecurity: Audit log: Failed to unlock global mutex: Permission denied」と出力され、ModSecurityが期待通りに動作しなくなります。

    3. 同様に、configureオプションに"--enable-standalone-module"を追加してnginx対応にします。

    4. mod_security.confの雛形をmodsecurity.conf-recommendedからコピーするようにしています。

  5. 修正が終わったら、"rpmbuild -ba --target=x86_64 ./mod_security.spec"として、パッケージをリビルドします。

    [sios@cent72 SPECS]$ rpmbuild -ba --target=x86_64 ./mod_security.spec
    ビルド対象プラットフォーム: x86_64
    ターゲット x86_64 用にビルド中
    実行中(%prep): /bin/sh -e /var/tmp/rpm-tmp.ZemSRC
    --snip--
    書き込み完了: /home/sios/rpmbuild/RPMS/x86_64/mod_security-debuginfo-2.9.1-1.el7.centos.x86_64.rpm
    実行中(%clean): /bin/sh -e /var/tmp/rpm-tmp.vFuvRE
    + umask 022
    + cd /home/sios/rpmbuild/BUILD
    + cd modsecurity-2.9.1
    + /usr/bin/rm -rf /home/sios/rpmbuild/BUILDROOT/mod_security-2.9.1-1.el7.centos.x86_64
    + exit 0
    
  6. /home/sios/rpmbuild/RPMS/x86_64以下にパッケージが作成されます。

    [sios@cent72 SPECS]$ ls /home/sios/rpmbuild/RPMS/x86_64/
    mod_security-2.9.1-1.el7.centos.x86_64.rpm
    

2. CRS(Core Rule Set)パッケージのリビルド

  1. "rpm -ivh mod_security_crs-XXX.src.rpm"として、ソースパッケージをインストールします。

  2. "/home/sios/rpmbuild/SPECS"以下にSPECファイル(mod_security_crs.spec)がありますので、こちらを下記のように修正します。

    ---------------------snip-------------------------------------
    %install
    rm -rf %{buildroot}
    
    install -d %{buildroot}%{_sysconfdir}/nginx/modsecurity.d/
    install -d %{buildroot}%{_sysconfdir}/nginx/modsecurity.d/activated_rules
    ---------------------snip-------------------------------------
    %files
    %doc CHANGES INSTALL LICENSE README.md
    %config(noreplace) %{_sysconfdir}/nginx/modsecurity.d/activated_rules/*
    %config(noreplace) %{_sysconfdir}/nginx/modsecurity.d/modsecurity_crs_10_config.conf
    
    1. /etc/httpd以下にディレクトリ・ファイルを作成するようになっていますので、これを/etc/nginx以下に配置するように変更します。

  3. 修正が終わったら、"rpmbuild -ba ./mod_security_crs.spec"として、パッケージをリビルドします。

    [sios@cent72 SPECS]$ rpmbuild -ba ./mod_security_crs.spec
    実行中(%prep): /bin/sh -e /var/tmp/rpm-tmp.l5ljsB
    + umask 022
    + cd /home/sios/rpmbuild/BUILD
    
    ---------------------snip-------------------------------------
    + rm -rf /home/sios/rpmbuild/BUILDROOT/mod_security_crs-2.2.9.20160219git-1.el7.centos.x86_64
    + exit 0
    
  4. /home/sios/rpmbuild/RPMS/noarch以下にパッケージが作成されます。


3. nginxのリビルド

  1. まずは作業用ユーザ(例ではsios)で、"rpm -ivh nginx-XXX.src.rpm"として、ソースパッケージをインストールします。

  2. "/home/sios/rpmbuild/SPECS"以下にSPECファイル(nginx_security.spec)がありますので、こちらを下記のように修正します。

  3.         --with-ipv6 \
            --add-module=/home/sios/rpmbuild/BUILD/modsecurity-2.9.1/nginx/modsecurity \
            %{?with_http2:--with-http_v2_module}")
    
    1. nginxのconfigure時に参照するmodsecurityのソースを指定します。今回は、"/home/sios/rpmbuild/"以下を参照しています。

  4. 修正が終わったら、"rpmbuild -ba ./mod_security_crs.spec"として、パッケージをリビルドします。

  5. /home/sios/rpmbuild/RPMS/x86_64以下にパッケージが作成されます。


まとめ

今回はnginxとmodsecurityのパッケージのリビルド方法を説明しました。

最終的に、下記のパッケージがx86_64又はnoarch以下に作成されているはずです。

  • mod_security-2.9.1-1.el7.centos.x86_64.rpm

  • nginx-1.9.12-1.el7.centos.ngx.x86_64.rpm

  • mod_security_crs-2.2.9.20160219git-1.el7.centos.noarch.rpm

次回は今回の作業で作成されたnginxとmodsecurityをインストールし、設定をしていきます。


[参考]
OSSよろず相談室

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

問い合わせボタン