nginxでWAF(Web Application Firewall) を作る(第二回)
こんにちは。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のソースパッケージは、nginxのサイト: http://nginx.org/packages/mainline/rhel/7/SRPMS/から
ModSecurityのパッケージはFedora Rawhide: http://ftp.iij.ad.jp/pub/linux/fedora//development/rawhide/Everything/source/tree/Packages/m/から
ダウンロードすることとします。
今回使用したバージョンは
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のリビルド
まずは作業用ユーザ(例ではsios)で、”rpm -ivh mod_security_XXX.src.rpm”として、ソースパッケージをインストールします。
リビルド時に必要なパッケージ(lua-devel, yajl-devel)をyumを使ってインストールします。
“/home/sios/rpmbuild/SPECS”以下にSPECファイル(mod_security.spec)がありますので、こちらを下記のように修正します。
ModSecurity関連のファイルは、今回nginxと連携させるに辺り、/etc/nginx, /usr/lib64/nginx以下などに配置したかったため、”_httpd_confdir”等のディレクトリは適宜”/etc/nginx/conf.dir”等に変更しています。
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が期待通りに動作しなくなります。
同様に、configureオプションに”–enable-standalone-module”を追加してnginx対応にします。
mod_security.confの雛形をmodsecurity.conf-recommendedからコピーするようにしています。
修正が終わったら、”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
/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
# /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-------------------------------------
2. CRS(Core Rule Set)パッケージのリビルド
“rpm -ivh mod_security_crs-XXX.src.rpm”として、ソースパッケージをインストールします。
“/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
/etc/httpd以下にディレクトリ・ファイルを作成するようになっていますので、これを/etc/nginx以下に配置するように変更します。
修正が終わったら、”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
/home/sios/rpmbuild/RPMS/noarch以下にパッケージが作成されます。
3. nginxのリビルド
まずは作業用ユーザ(例ではsios)で、”rpm -ivh nginx-XXX.src.rpm”として、ソースパッケージをインストールします。
“/home/sios/rpmbuild/SPECS”以下にSPECファイル(nginx_security.spec)がありますので、こちらを下記のように修正します。
nginxのconfigure時に参照するmodsecurityのソースを指定します。今回は、”/home/sios/rpmbuild/”以下を参照しています。
修正が終わったら、”rpmbuild -ba ./mod_security_crs.spec”として、パッケージをリビルドします。
/home/sios/rpmbuild/RPMS/x86_64以下にパッケージが作成されます。
--with-ipv6 \ --add-module=/home/sios/rpmbuild/BUILD/modsecurity-2.9.1/nginx/modsecurity \ %{?with_http2:--with-http_v2_module}")
まとめ
今回は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をインストールし、設定をしていきます。