Apacheのmod_rewriteを使って簡易WAFの実装
脆弱性を悪用した攻撃から守るるためにApacheのmod_rewriteを使って簡易WAFを実装してみました
簡易WAF
/etc/httpd/conf.d/00-security.inc
ファイルを作成して以下の内容を設定
<IfModule mod_rewrite.c> ### REQUEST_METHOD ### RewriteCond %{REQUEST_METHOD} ^(HEAD|TRACE|DELETE|TRACK) [NC] RewriteRule ^(.*)$ - [R=400,L] ### THE_REQUEST ### RewriteCond %{THE_REQUEST} ^.*(\\r|\\n|%0A|%0D).* [NC] RewriteRule ^(.*)$ - [R=400,L] ### HTTP_REFERER ### RewriteCond %{HTTP_REFERER} ^(.*)(<|>|'|%0A|%0D|%27|%3C|%3E|%00).* [NC] RewriteRule ^(.*)$ - [R=400,L] ### HTTP_COOKIE ### RewriteCond %{HTTP_COOKIE} ^.*(<|>|'|%0A|%0D|%27|%3C|%3E|%00).* [NC] RewriteRule ^(.*)$ - [R=400,L] ### REQUEST_URI ### RewriteCond %{REQUEST_URI} ^.*(,|;|:|<|>|">|"<|\.\.\.).* [NC,OR] RewriteCond %{REQUEST_URI} ^.*(\=|\@|\[|\]|\^|\`|\{|\}|\~).* [NC,OR] RewriteCond %{REQUEST_URI} ^.*(\'|%0A|%0D|%27|%3C|%3E|%00).* [NC] RewriteRule ^(.*)$ - [R=400,L] ### HTTP_USER_AGENT ### RewriteCond %{HTTP_USER_AGENT} ^$ [OR] RewriteCond %{HTTP_USER_AGENT} ^.*(<|>|'|%0A|%0D|%27|%3C|%3E|%00).* [NC,OR] RewriteCond %{HTTP_USER_AGENT} ^.*(HTTrack|clshttp|archiver|loader|email|nikto|miner|python).* [NC,OR] RewriteCond %{HTTP_USER_AGENT} ^.*(winhttp|libwww\-perl|curl|wget|harvest|scan|grab|extract).* [NC] RewriteRule ^(.*)$ - [R=400,L] ### QUERY_STRING ### RewriteCond %{QUERY_STRING} base64_encode.*(.*) [NC,OR] RewriteCond %{QUERY_STRING} ^.*(\<|%3C).*script.*(\>|%3E) [NC,OR] RewriteCond %{QUERY_STRING} ^.*(localhost|loopback|127\.0\.0\.1).* [NC,OR] RewriteCond %{QUERY_STRING} ^.*(;|<|>|'|"|%0A|%0D|%00).* [NC,OR] RewriteCond %{QUERY_STRING} ^.*(md5|benchmark|union|select|insert|cast|decldrop|update|alter).* [NC] RewriteRule ^(.*)$ - [R=400,L] ### REMOTE_ADDR ### # RewriteCond %{REMOTE_ADDR} ^999\.999\.999\.999$ [OR] # RewriteCond %{REMOTE_ADDR} ^999\.999\.999\.999$ # RewriteRule ^(.*)$ - [R=400,L] </IfModule>
※簡易WAFは環境によっては誤検知する場合があるので調整ください。
/etc/httpd/conf.d/11-ip.conf
VirtualHostに先程作成した簡易WAFをInclude
<VirtualHost XXX.XXX.XXX.XXX:80> ServerName XXX.XXX.XXX.XXX DocumentRoot /var/www/ip/html <Directory /var/www/ip> AllowOverride none Options None Require all denied </Directory> <Directory /var/www/ip/html> Require method GET POST Options FollowSymLinks RewriteEngine On ### 簡易WAF ### Include conf.d/00-security.inc </Directory> <Directory /var/www/ip/html/phpMyAdmin> RewriteCond %{HTTPS} off RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R,L] ### IP制限 ### <RequireAll> <RequireAny> Require all denied Require ip 999.999.999.999 </RequireAny> Require method GET POST </RequireAll> </Directory> CustomLog logs/ip_access_log combined_tab env=!nolog ErrorLog logs/ip_error_log </VirtualHost>
※「XXX.XXX.XXX.XXX」はサーバのIPアドレスを設定します。
「999.999.999.999」は接続元(会社/自宅等)のIPアドレスを設定します。
/etc/httpd/conf.d/51-ip-ssl.conf
SSLのVirtualHostにも先程作成した簡易WAFをInclude
<VirtualHost XXX.XXX.XXX.XXX:443> ServerName XXX.XXX.XXX.XXX DocumentRoot /var/www/ip/html SSLEngine on SSLVerifyClient none SSLCompression off SSLHonorCipherOrder on # SSLProtocol all -SSLv3 # SSLCipherSuite HIGH:MEDIUM:!MD5:!RC4 SSLProtocol ALL -SSLv2 -SSLv3 SSLCipherSuite HIGH:!aNULL:!eNULL:!DH:!3DES SSLCertificateKeyFile /etc/tls/apache.key SSLCertificateFile /etc/tls/apache.crt Header always set Strict-Transport-Security "max-age=31536000" <Directory /var/www/ip> AllowOverride none Options None Require all denied </Directory> <Directory /var/www/ip/html> Require method GET POST Options FollowSymLinks RewriteEngine On ### 簡易WAF ### Include conf.d/00-security.inc </Directory> <Directory /var/www/ip/html/phpMyAdmin> ### ベーシック認証・IP制限 ### AuthType Basic AuthName "Input ID and Password." AuthUserFile /var/www/ip/.htpasswd <RequireAll> <RequireAny> Require all denied Require ip 999.999.999.999 </RequireAny> Require method GET POST Require valid-user </RequireAll> </Directory> CustomLog logs/ip_ssl_access_log combined_tab env=!nolog ErrorLog logs/ip_ssl_error_log </VirtualHost>
※「XXX.XXX.XXX.XXX」はサーバのIPアドレスを設定します。
「999.999.999.999」は接続元(会社/自宅等)のIPアドレスを設定します。
シンタックスチェック
# service httpd configtest Syntax OK
※シンタックスエラーがないことを確認
設定ファイルの再読み込み
# systemctl reload httpd.service
簡易WAF実装の確認
「http://サーバのIPアドレス/?union+select」にアクセスして、「HTTPステータスコード=400」となればOKです。
「https://サーバのIPアドレス/?union+select」にアクセスして、「HTTPステータスコード=400」となればOKです。