2026年6月18日
2026年6月18日
Apacheのセキュリティ強化設定10選(WordPressサーバー向け)
Apacheのセキュリティ強化は、特別なツールを入れる前に「余計な情報を出さない」「不要な機能を止める」「見せてはいけないファイルを拒否する」の3点を設定で固めるのが近道です。この記事では、WordPressを動かしているApache 2.4系サーバーで効果が大きく、副作用を把握しやすい設定を10項目に絞って、設定例・つまずきやすい点・確認方法をまとめます。
作業はVPSや専用サーバーなど、Apacheの設定ファイルを編集できる環境を想定しています。共用レンタルサーバーでは .htaccess で書ける項目だけが対象になります。
作業前の準備
設定を1つ変えるたびに構文チェックと再読み込みを行い、問題が出たらすぐ戻せる状態で進めます。まとめて10項目を入れてから動作確認すると、どれが原因で表示が崩れたのか切り分けにくくなるためです。
# 設定ファイル一式をバックアップ(Debian/Ubuntu の例。RHEL系は /etc/httpd)
sudo cp -a /etc/apache2 /etc/apache2.bak-$(date +%Y%m%d)
# 構文チェック → 問題なければ再読み込み(接続を切らない)
sudo apachectl configtest && sudo systemctl reload apache2
Syntax OK が出ない状態で再起動すると、Apacheが起動せずサイト全体が止まります。本番サーバーで試す前に、同じ構成のステージング環境で一通り確認しておくと安心です。
1. バージョン情報を隠す(ServerTokens / ServerSignature)
既定の設定では、レスポンスヘッダーの Server やエラーページの下部に、ApacheやOSのバージョンが表示されることがあります。バージョンを隠しても脆弱性そのものは消えませんが、古いバージョンを狙った機械的な探索の手がかりを減らせます。
# Debian/Ubuntu では /etc/apache2/conf-available/security.conf に記載がある
ServerTokens Prod
ServerSignature Off
確認は curl -sI https://example.com/ | grep -i server で行います。Server: Apache だけになっていれば反映済みです。PHPのバージョンを示す X-Powered-By は、php.ini の expose_php = Off で別途止めます。
2. TRACEメソッドを無効にする
TRACEは受け取ったリクエストをそのまま返すデバッグ用のメソッドで、通常のWordPress運用では使いません。
TraceEnable Off
curl -sI -X TRACE https://example.com/ を実行し、405 Method Not Allowed などが返れば無効化できています。
3. ディレクトリ一覧を表示させない
index.php や index.html が無いディレクトリにアクセスされたとき、ファイル一覧が表示される設定は避けます。プラグインのフォルダやバックアップの置き場所が丸見えになるためです。
<Directory "/var/www/example.com/public">
Options -Indexes +SymLinksIfOwnerMatch
</Directory>
WordPressのパーマリンクは mod_rewrite を使うため、FollowSymLinks か SymLinksIfOwnerMatch のどちらかが有効でないと書き換えが拒否され、403エラーになります。Options None にしてしまうのがよくあるつまずきです。
4. 使っていないモジュールを止める
読み込まれているモジュールが多いほど、設定ミスや脆弱性の影響を受ける範囲が広がります。まず一覧を確認し、用途が説明できないものを候補にします。
sudo apachectl -M # 読み込み中のモジュール一覧
sudo a2dismod autoindex cgi # Debian/Ubuntu の例(不要と判断できた場合のみ)
mod_status のように監視で使うものは、止めるより「サーバー内部からだけ見られる」ように制限するほうが実用的です。無効化したモジュールのディレクティブが他の設定ファイルに残っていると起動エラーになるので、configtest の結果を毎回確認してください。
5. .htaccessの権限を必要最小限にする
AllowOverride All は手軽ですが、.htaccess からほぼすべての設定を上書きできる状態です。サーバー全体では拒否を既定にし、WordPressの公開ディレクトリだけで必要な権限を与えます。
<Directory />
AllowOverride None
Require all denied
</Directory>
<Directory "/var/www/example.com/public">
AllowOverride FileInfo
Require all granted
</Directory>
WordPress標準の .htaccess(リライトルール)は FileInfo があれば動きます。ただし、キャッシュ系やセキュリティ系のプラグインが .htaccess に書き込むディレクティブによっては、AuthConfig や Indexes などが追加で必要になります。絞ったあとは管理画面・投稿の表示・プラグインの動作を確認し、500エラーが出たらエラーログの「not allowed here」という行で不足している権限を特定します。
6. 見せてはいけないファイルへのアクセスを拒否する
wp-config.php は通常PHPとして実行されるため中身は表示されませんが、PHPの設定不備でソースが露出する事故に備えて直接アクセスを拒否しておきます。あわせて、.git やエディタの一時ファイル、SQLのダンプなど、公開ディレクトリに紛れ込みやすいファイルも対象にします。
<Files "wp-config.php">
Require all denied
</Files>
# .ht* は多くのディストリビューションで既定で拒否済み
<FilesMatch "^\.ht">
Require all denied
</FilesMatch>
# バージョン管理・環境変数ファイル・バックアップ類
RedirectMatch 404 "/\.(?:git|svn|env)(?:/|$)"
<FilesMatch "\.(?:bak|old|orig|sql|swp|log)$">
Require all denied
</FilesMatch>
Let's Encryptの認証で使う /.well-known/ まで拒否しないよう、ドットで始まるパスを一括で拒否する書き方は避けています。XML-RPC(xmlrpc.php)を止めるかどうかは、Jetpackやスマートフォンアプリ、外部の投稿ツールを使っているかで判断が分かれるため、使っていないことを確認してから拒否してください。
7. アップロードフォルダでPHPを実行させない
改ざんの典型的な手口は、画像アップロードの仕組みなどを悪用して wp-content/uploads にPHPファイルを置き、それを実行させることです。このディレクトリでは本来PHPを動かす必要がないので、実行を拒否します。
<Directory "/var/www/example.com/public/wp-content/uploads">
<FilesMatch "\.(?:php[0-9]?|phtml|phar)$">
Require all denied
</FilesMatch>
</Directory>
SSHで中身が <?php echo 'ok'; だけのテスト用ファイル test.php をアップロードフォルダに置いてブラウザで開き、403になることを確認したら、テストファイルは削除します。
8. セキュリティ関連のレスポンスヘッダーを付ける
mod_headers を使い、ブラウザ側の防御機能を有効にするヘッダーを付けます。always を付けると、エラー応答にも同じヘッダーが付きます。
<IfModule mod_headers.c>
Header always set X-Content-Type-Options "nosniff"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Permissions-Policy "camera=(), microphone=(), geolocation=()"
</IfModule>
Content-Security-Policy は効果が大きい一方、WordPressのテーマやプラグインが読み込む外部スクリプトを止めてしまいやすいヘッダーです。いきなり強制せず、Content-Security-Policy-Report-Only で違反を観察してから段階的に絞る進め方が安全です。HSTSはサブドメインを含めた影響が大きいので、短い max-age から試してください。
9. TLSの設定を見直す
古いプロトコルのSSLv3やTLS 1.0/1.1は、主要ブラウザがすでにサポートを終えています(2026年10月現在)。TLS 1.2と1.3だけを許可するのが現在の一般的な構成です。
SSLProtocol -all +TLSv1.2 +TLSv1.3
SSLHonorCipherOrder off
暗号スイートの細かい指定は、手書きするよりMozillaの「SSL Configuration Generator」でApacheとOpenSSLのバージョンを入れて出力した値を使うほうが間違いが少なくなります。反映後は openssl s_client -connect example.com:443 -tls1_1 で接続が拒否されることを確かめ、外部の診断サービスでも結果を確認します。
10. タイムアウトとリクエストサイズに上限を設ける
接続を長時間つかんだままにする低速攻撃や、巨大なリクエストでの負荷に備えて、待ち時間とサイズの上限を設定します。
Timeout 60
# mod_reqtimeout:ヘッダー・本文の受信に時間をかけすぎる接続を切る
<IfModule mod_reqtimeout.c>
RequestReadTimeout header=20-40,MinRate=500 body=20,MinRate=500
</IfModule>
# 本文サイズの上限(例: 64MB)。PHPの upload_max_filesize より小さくしない
LimitRequestBody 67108864
LimitRequestBody を小さくしすぎると、メディアのアップロードやプラグインのインポートが413エラーで失敗します。PHP側の upload_max_filesize と post_max_size を確認し、それ以上の値にしてください。なお、Apache 2.4.54以降は既定値が1GiBに変わったとされているため、明示的に設定しておくと環境差で迷いません。
設定以外で効いてくること
設定ファイルの強化と同じくらい、運用面の対策が結果を左右します。
- 実行ユーザーと権限: Apacheは
www-dataやapacheなどの一般ユーザーで動かし、WordPressのファイルは644、ディレクトリは755、wp-config.phpは640や600を目安にします。ファイル全体をApacheユーザーの書き込み可にすると、改ざんされたときの被害が広がります。ただし自動更新との兼ね合いがあるので、更新方法とセットで決めます。 - パッケージの更新: ディストリビューションのApacheは、バージョン番号を上げずにセキュリティ修正だけを取り込む(バックポート)ことが多いので、表示上のバージョンが古くても更新が止まっているとは限りません。
aptやdnfでの定期更新を運用に組み込みます。 - ログの確認:
/var/log/apache2/error.logとアクセスログを定期的に見て、wp-login.phpへの大量アクセスや存在しないPHPファイルへの探索を把握します。fail2ban などで自動遮断する方法もあります。
さらに一段上の対策として、IPアドレスでの管理画面の制限や、ModSecurityによるWAFの導入があります。どちらも誤遮断を起こしうるため、ここまでの基本設定が安定してから取り組むと切り分けが楽になります。
まとめ
- 変更は1項目ずつ、
apachectl configtest→ reload の順で反映し、バックアップから戻せる状態で進める。 - バージョン情報の非表示、TRACE無効、ディレクトリ一覧の無効化、不要モジュールの停止で、余計な情報と機能を減らす。
AllowOverrideは必要な権限だけにし、wp-config.php・.git・バックアップ類・アップロードフォルダのPHPはアクセスを拒否する。- セキュリティヘッダーとTLS 1.2/1.3の構成で、ブラウザ側と通信路の防御を固める。CSPやHSTSは段階的に。
- タイムアウトと
LimitRequestBodyで負荷系の攻撃に備えつつ、PHPのアップロード上限との整合を取る。