2026年9月30日
2026年9月30日
WordPressのWebサーバーのセキュリティ設定(Apache)
はじめに
Apacheのデフォルト設定はWordPress向けに最適化されておらず、サーバーバージョン情報の公開・ディレクトリ一覧表示・不要なモジュールが有効になっているなど、攻撃者にとって有利な情報を提供してしまいます。適切なセキュリティ設定でリスクを大幅に低減できます。
症状・原因
- Apacheのバージョン情報がエラーページやレスポンスヘッダーに表示されている
- ディレクトリにindex.phpがない場合にファイル一覧が表示される
- .htaccessファイルに設定を追加してもWordPressに反映されない
- 不正なHTTPメソッド(TRACE・DELETE等)が許可されている
解決手順
ステップ1:現在のApache設定を診断する
# Apache のバージョン確認
apache2 -v
# 現在の設定を確認
apache2ctl -M | grep -E "rewrite|headers|ssl"
# サーバー情報がレスポンスヘッダーに含まれているか確認
curl -sI https://example.com/ | grep -i "server\|x-powered"
# エラーレスポンスにサーバー情報が含まれているか確認
curl -s https://example.com/nonexistent | grep -i "apache"
# 有効なモジュールを確認
apache2ctl -M 2>/dev/null | sort
ステップ2:Apache のセキュリティ設定を強化する
# /etc/apache2/conf-available/security.conf を編集
sudo nano /etc/apache2/conf-available/security.conf
# /etc/apache2/conf-available/security.conf
# サーバーバージョン情報を非表示
ServerTokens Prod
ServerSignature Off
# ディレクトリリストを無効化
Options -Indexes
# シンボリックリンクを禁止
Options -FollowSymLinks
# .htaccess ファイルの上書きを許可(WordPress に必要)
AllowOverride All
# 不要な HTTP メソッドを無効化
<LimitExcept GET POST HEAD>
Order Deny,Allow
Deny from all
</LimitExcept>
# ヘッダーインジェクション対策
Header always unset X-Powered-By
Header always unset Server
# ETag を無効化(inode 情報の漏洩防止)
FileETag None
Header unset ETag
# 設定を有効化
sudo a2enconf security
# 必要なモジュールを有効化
sudo a2enmod headers
sudo a2enmod rewrite
sudo a2enmod ssl
# 設定を検証
sudo apache2ctl configtest
# Apache を再起動
sudo systemctl reload apache2
ステップ3:WordPress 用 VirtualHost を設定する
# /etc/apache2/sites-available/wordpress.conf
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
# HTTP → HTTPS リダイレクト
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</VirtualHost>
<VirtualHost *:443>
ServerName example.com
DocumentRoot /var/www/html
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
# TLS 1.2 以上のみ許可
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256
<Directory /var/www/html>
Options -Indexes -FollowSymLinks
AllowOverride All
Require all granted
</Directory>
# wp-config.php へのアクセスを禁止
<Files wp-config.php>
Require all denied
</Files>
# xmlrpc.php をブロック
<Files xmlrpc.php>
Require all denied
</Files>
# .htaccess・.htpasswd を保護
<FilesMatch "^\.ht">
Require all denied
</FilesMatch>
# バックアップファイルを保護
<FilesMatch "\.(sql|bak|log|sh)$">
Require all denied
</FilesMatch>
</VirtualHost>
ステップ4:.htaccess でセキュリティを強化する
# /var/www/html/.htaccess: WordPress セキュリティ設定
# WordPress リライトルール
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
# セキュリティヘッダーを追加
<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 "geolocation=(), microphone=(), camera=()"
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
</IfModule>
# PHP の実行を uploads ディレクトリで禁止
<IfModule mod_rewrite.c>
RewriteRule ^wp-content/uploads/.*\.(php|phtml|php5|phar)$ - [F,L]
</IfModule>
# スクリプトインジェクション対策
<IfModule mod_rewrite.c>
RewriteCond %{QUERY_STRING} (\<|%3C).*script.*(\>|%3E) [NC,OR]
RewriteCond %{QUERY_STRING} GLOBALS(=|\[|\%[0-9A-Z]{0,2}) [OR]
RewriteCond %{QUERY_STRING} _REQUEST(=|\[|\%[0-9A-Z]{0,2})
RewriteRule ^ index.php [F,L]
</IfModule>
ステップ5:mod_security を有効化する
# mod_security をインストール
sudo apt install libapache2-mod-security2 -y
# OWASP CRS をインストール
sudo apt install modsecurity-crs -y
# モジュールを有効化
sudo a2enmod security2
# 設定ファイルをコピー
sudo cp /etc/modsecurity/modsecurity.conf-recommended \
/etc/modsecurity/modsecurity.conf
# 検出モードを有効化(まず DetectionOnly で様子を見る)
sudo sed -i 's/SecRuleEngine DetectionOnly/SecRuleEngine On/' \
/etc/modsecurity/modsecurity.conf
# WordPress に必要なルールの例外を設定
sudo nano /etc/modsecurity/wordpress-exclusions.conf
# /etc/modsecurity/wordpress-exclusions.conf
# WordPress 管理画面の誤検知を除外
<LocationMatch "^/wp-admin/">
SecRuleRemoveById 981173
SecRuleRemoveById 960017
</LocationMatch>
# REST API の誤検知を除外
<LocationMatch "^/wp-json/">
SecRuleRemoveById 200003
</LocationMatch>
注意事項
AllowOverride Allを設定すると.htaccessが有効になりますが、パフォーマンスに影響します。必要なディレクトリのみに限定することを検討してください- mod_securityを
SecRuleEngine On(ブロックモード)にする前に、必ずDetectionOnlyで誤検知を確認してください。WordPressの管理画面が誤ってブロックされる場合があります - SSL/TLS設定後は
ssl-labs.comなどでA+評価になっているか確認してください
まとめ
Apacheのセキュリティ設定は①ServerTokens Prod・ServerSignature Offでバージョン情報を非表示、②Options -Indexes -FollowSymLinksでディレクトリリストとシンボリックリンクを禁止、③VirtualHostでSSLProtocol all -TLSv1 -TLSv1.1・wp-config.php・xmlrpc.phpへのアクセスを拒否、④.htaccessにセキュリティヘッダー・uploads内PHP実行禁止・SQLインジェクション対策RewriteRuleを追加、⑤mod_securityをDetectionOnlyで試験後にOnに切り替えてWordPress管理画面の誤検知ルールを除外します。