先ほどのエントリーの続きです。
「実際に筆者が施している」
Apache設定を元に「どういう動きをしているのか」を紹介します。
サンプル例
サイト名やIPアドレスなどはダミーにしています。
# ============================================================
# 【HTTP: 80番ポート】常時HTTPS(SSL/TLS)へのリダイレクト
# ============================================================
<VirtualHost *:80>
ServerName example.com
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</VirtualHost>
# ============================================================
# 【HTTPS: 443番ポート】要塞化されたメインサーバー設定
# ============================================================
<VirtualHost *:443>
ServerName example.com
DocumentRoot /var/www/html/public
# --------------------------------------------------------
# 1. アクセスログの間引き(ノイズカット)設定
# --------------------------------------------------------
# 自身の監視用IPなど、ログに記録させたくないIPを指定
SetEnvIf Remote_Addr "192.168.1.100" dontlog
SetEnvIf Remote_Addr "10.0.0.1" dontlog
# 検索エンジンのクローラー(健全なBot)もログから除外してノイズを減らす
SetEnvIfNoCase User-Agent "Googlebot" dontlog
SetEnvIfNoCase User-Agent "GoogleOther" dontlog
# 【外部ファイル連携】定期的・自動的に更新する悪質ボットのリストを読み込む
# ※ファイル内で「SetEnv bad_bot 1」などのフラグを立てる想定
Include /etc/apache2/conf-available/blacklist-bots.txt
# dontlogフラグが付いたアクセスは記録しない
CustomLog /var/log/apache2/example_access.log combined env=!dontlog
ErrorLog /var/log/apache2/example_error.log
# --------------------------------------------------------
# 2. メインディレクトリ制御(mod_rewrite × 環境変数)
# --------------------------------------------------------
<Directory /var/www/html/public>
Options -MultiViews
AllowOverride All
# 大量の拒否アクセスによるエラーログ肥大化を抑制(重大エラーのみ記録)
LogLevel authz_core:crit
<IfModule mod_rewrite.c>
RewriteEngine On
# 【攻撃検知】特定の動的ページに対する「大量のタグ連結」などのボット挙動を迎撃
# 例:特定のURLパスにアクセスがあり、かつクエリにURLエンコードされたカンマ等が大量に含まれる場合
SetEnvIf Request_URI "^/search/tags" is_target_page
SetEnvIf Query_String "tag=.*(%2c|,|%e3%80%81).*(%2c|,|%e3%80%81).*(%2c|,|%e3%80%81)" bad_tag_stacking
# 条件に合致したら、ログを残さず「404 Not Found(存在しない)」を返して虚無へ葬る
RewriteCond %{ENV:is_target_page} 1
RewriteCond %{ENV:bad_tag_stacking} 1
RewriteRule ^ - [E=dontlog:1,R=404,L]
# 【外部ファイル連携】スパムIPアドレスのブラックリストを読み込んで404を返す
Include /etc/apache2/conf-available/spam-ips.txt
</IfModule>
# 【アクセス拒否】上記の設定や外部リストで「bad_bot」と判定された通信を遮断
<RequireAll>
Require not env bad_bot
Require all granted
</RequireAll>
</Directory>
# 403 Forbidden(拒否)を返すと攻撃者に「防御されている」とバレるため、
# 403の際も「404 Not Found(最初から何も無い)」として処理する
ErrorDocument 403 /404.html
# --------------------------------------------------------
# 3. セキュリティヘッダーの強化(mod_headers)
# --------------------------------------------------------
Header always set Strict-Transport-Security "max-age=63072000"
Header always set X-Content-Type-Options "nosniff"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set X-XSS-Protection "1; mode=block"
# --------------------------------------------------------
# 4. Nepenthes(ウツボカズラ)トラップ設定(mod_alias)
# --------------------------------------------------------
# 攻撃者が盲目的にスキャンしてくる「脆弱性のあるパス」を、ダミーの静的ファイルへ吸い込ませる
<IfModule mod_alias.c>
# WordPressを使っていない(または構成が違う)のに狙われるパス
Alias /wp-login.php /var/www/nepenthes/dummy_login.html
Alias /wp-admin /var/www/nepenthes/dummy_login.html
Alias /wordpress /var/www/nepenthes/dummy_login.html
# 漏洩すると致命的な .git ディレクトリへのスキャン対策
Alias /.git /var/www/nepenthes/dummy_git.html
# robots.txtで「巡回禁止」にしているにもかかわらず、
# 行儀悪くスクラップ(収集)しにくるAI自動巡回エージェント用のトラップ
Alias /assets-archive /var/www/nepenthes/dummy_login.html
# トラップ用ディレクトリへのアクセスを許可
<Directory /var/www/nepenthes>
Require all granted
</Directory>
</IfModule>
# --------------------------------------------------------
# 5. SSL/TLS暗号化プロトコル設定
# --------------------------------------------------------
SSLEngine on
Protocols h2 http/1.1
# 安全性の低い古いプロトコルを徹底排除(TLS 1.2 / 1.3 のみ許可)
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 -TLSv1.2
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384
SSLHonorCipherOrder off
SSLSessionTickets off
SSLCertificateFile /etc/ssl/certs/example.com.crt
SSLCertificateKeyFile /etc/ssl/private/example.com.key
# --------------------------------------------------------
# 6. WAF(ModSecurity)のチューニング
# --------------------------------------------------------
<IfModule security2_module>
SecRuleEngine On
# ファイルアップロードの容量制限を引き上げ(必要に応じて調整)
SecRequestBodyInMemoryLimit 524288000
SecRequestBodyLimit 524288000
SecRequestBodyNoFilesLimit 524288000
# --- 偽陽性(誤検知)の除外ルール ---
# ※システム(RedmineやWordPressなど)の特性に応じて、正常な通信が遮断されないよう調整
SecRuleRemoveById 920420 # 特定JavaScriptの誤検知対策
SecRuleRemoveById 200004 # マルチパート解析エラーの除外
SecRuleRemoveById 920300 # HTTPプロトコル違反の除外
SecRuleRemoveById 920260
SecRuleRemoveById 920270
SecRuleRemoveById 920240
# --- 記憶抹消刑(Damnatio Memoriae)システム ---
# あらかじめリスト化した凶悪なIP(negativelist.txt)からのアクセスは、
# 404エラーを返しつつ、Apacheのログ(auditlog等含む)に一切記録させず存在を抹消する
SecRule REMOTE_ADDR "@pmFromFile negativelist.txt" "phase:1,id:2,status:404,msg:'Damnatio Memoriae',nolog,noauditlog"
</IfModule>
</VirtualHost>
では、各設定の意図は後回しにして、「どういう動きなのか」を見てみましょう。
パターン1: http→httpsへの変更
http(80番)で来たアクセスを強制的にhttps(443)に転送します。
パターン2: 通常アクセス
悪意を持たないアクセスには正常に通信します。
パターン3:攻撃者、ボットなど
スクレイピングや事前に設定していた悪質なボットにどう立ち向かうのかがこちらです。
と、このように、
「“アクセス”は通す
“攻撃”は阻止する
ミドルウェアで“両方”やるというのは
そう難しいことじゃあないな」
と言えるのが「個人VPSでApacheを使う理由」と言えます。
次は、それらを可能にする仕組みについて解説します。