サイトを公開すると、意識しないうちに「使っているソフトのバージョン」が外部から丸見えになっていることがあります。攻撃者はまずこの情報を集め、そのバージョンに効く既知の脆弱性を狙ってきます。
この記事は次の方向けです。
- レスポンスヘッダやHTMLに「nginx/1.24.0」「PHP/8.1.2」のような表示が出ていて気になっているWeb担当者
- 制作したサイトを納品する前に、余計な情報露出を減らしておきたい制作会社
- WordPressサイトの「見えている情報」を減らして狙われにくくしたい運営者
対応環境は nginx / Apache / PHP / WordPress です。すべてコピペで使える設定にしています。
なぜバージョン情報を隠すのか
バージョンを隠すこと自体は、脆弱性そのものを直すわけではありません。あくまで「多層防御の1枚」です。攻撃者に対して次のような効果があります。
- 自動スキャンツールが「このバージョンは既知の穴がある」と機械的に判定する材料を減らせる
- 標的リスト化(古いバージョンだけを狙って一斉に攻撃するタイプ)から外れやすくなる
- 攻撃者に「調査に手間がかかるサイト」という印象を与え、より簡単な標的へ移らせる
重要な前提として、バージョン非表示は更新(パッチ適用)の代わりにはなりません。古いソフトを隠して使い続けても、脆弱性は残ったままです。あくまで「きちんと更新したうえで、余計な情報も出さない」という順番で考えてください。
どこからバージョンが漏れているか確認する
まずは現状を確認します。ターミナルから curl でレスポンスヘッダを見ます。
# レスポンスヘッダを確認(Server / X-Powered-By に注目)
curl -sI https://example.com | grep -iE 'server|x-powered-by|x-generator'
WordPressの場合は、HTMLソースやファイルにもバージョンが出ます。
# HTML内のgeneratorメタタグを確認
curl -s https://example.com | grep -i 'name="generator"'
# readme.html にはWordPressのバージョンが載っている
curl -sI https://example.com/readme.html | head -n 1
代表的な漏れ口は次の4つです。
-
Server:ヘッダ(nginx/Apacheのバージョン) -
X-Powered-By:ヘッダ(PHPのバージョン) - HTMLの
<meta name="generator" content="WordPress 6.x"> -
readme.html/license.txtなどの同梱ファイル
順番に塞いでいきます。
nginx の設定
server_tokens off; で、エラーページや Server ヘッダからバージョン番号を消せます。http ブロック(全体)に入れるのが基本です。
http {
# Server: nginx/1.24.0 → Server: nginx にする(番号を消す)
server_tokens off;
}
Server: nginx という製品名まで完全に消したい場合は、標準モジュールだけではできません。ngx_http_headers_more モジュール(headers-more-nginx-module)を導入すると、ヘッダ自体を差し替え・削除できます。
# headers-more モジュール導入時のみ有効
# Server ヘッダを空にする(または任意の文字列に差し替え)
more_clear_headers Server;
# PHP-FPM 連携時に付く X-Powered-By も消す
more_clear_headers 'X-Powered-By';
設定変更後は必ず構文チェックしてから反映します。
sudo nginx -t && sudo systemctl reload nginx
Apache の設定
Apacheは ServerTokens と ServerSignature の2つで制御します。httpd.conf(または conf.d 配下の設定ファイル)に記述します。.htaccess では変更できないディレクティブなので、サーバー設定側に書きます。
# Server: Apache/2.4.58 (Ubuntu) → Server: Apache だけにする
ServerTokens Prod
# エラーページ下部のバージョン署名を消す
ServerSignature Off
PHPが付ける X-Powered-By ヘッダは、mod_headers で削除できます(次のPHP側設定と併用すると確実です)。
# mod_headers が有効な前提
Header unset X-Powered-By
Header always unset X-Powered-By
反映前に構文チェックします。
sudo apachectl configtest && sudo systemctl reload apache2
PHP の設定
PHPは expose_php を Off にすると、X-Powered-By: PHP/8.1.2 のようなヘッダを出さなくなります。php.ini を編集します。
; php.ini
; X-Powered-By ヘッダを出さない
expose_php = Off
編集後、使用中のPHPを再起動します(PHP-FPMの場合)。
# バージョン部分は環境に合わせて読み替え
sudo systemctl restart php8.1-fpm
反映されたか確認します。X-Powered-By が消えていれば成功です。
curl -sI https://example.com | grep -i 'x-powered-by'
WordPress の設定
WordPressは複数の場所にバージョンを出すため、テーマの functions.php(子テーマ推奨)にまとめて追記します。
// functions.php — WordPressのバージョン露出を減らす
// 1. <head> の generator メタタグを消す
remove_action('wp_head', 'wp_generator');
// 2. RSS/Atomフィードの generator も消す
add_filter('the_generator', '__return_empty_string');
// 3. CSS/JS の ?ver=6.x クエリを削除(バージョン推測の材料を減らす)
function jiis_remove_version_query($src) {
if (strpos($src, 'ver=')) {
$src = remove_query_arg('ver', $src);
}
return $src;
}
add_filter('style_loader_src', 'jiis_remove_version_query', 9999);
add_filter('script_loader_src', 'jiis_remove_version_query', 9999);
なお ?ver= を消すとブラウザキャッシュの更新目印もなくなるため、CSS/JSを更新した際は明示的にキャッシュをクリアするか、この3番目のブロックだけ外す運用でも構いません。安全側に倒すなら、まずは1と2だけでも十分効果があります。
さらに、バージョンが直接書かれた同梱ファイルへのアクセスを塞ぎます。nginxの場合は次のように書きます。
# readme.html / license.txt などへのアクセスを拒否
location ~* ^/(readme\.html|license\.txt|wp-config-sample\.php)$ {
deny all;
}
Apache(.htaccess)の場合は次の通りです。
# readme.html / license.txt へのアクセスを拒否
<FilesMatch "^(readme\.html|license\.txt|wp-config-sample\.php)$">
Require all denied
</FilesMatch>
設定後の確認
最後に、最初と同じコマンドでバージョン情報が消えたか確認します。
# Server にバージョン番号、X-Powered-By 行、generator が出なければOK
curl -sI https://example.com | grep -iE 'server|x-powered-by'
curl -s https://example.com | grep -i 'name="generator"'
Server: が製品名のみ(または空)、X-Powered-By が消え、generatorメタタグが出なくなっていれば設定は反映されています。
まとめ
- バージョン情報の露出は、攻撃者に「狙いどころ」を教える材料になります
- nginx=
server_tokens off、Apache=ServerTokens Prod+ServerSignature Off、PHP=expose_php Offが基本の3点セット - WordPressは generatorメタ・フィード・同梱ファイルの3方向を塞ぐ
- ただしこれは補助的な対策であり、本体・プラグイン・PHPの更新が最優先です
関連記事
本記事の設定は、Webサイトを9つの守りでまるごと守る「サイトドック」の月次の定期健診でまとめて確認できます → https://sitedock.jp