Nginxセキュリティ強化ガイド
TLS・レート制限・セキュリティヘッダー設定
NginxでWebサイトを公開する際、リバースプロキシの設定だけでは不十分です。
TLSの暗号化設定、レート制限によるDoS対策、セキュリティヘッダーによるブラウザ防御まで、Nginxで実施すべきセキュリティ強化を解説します。
こんな人向けの記事です
- NginxでWebサイトを公開している
- SSL/TLS証明書は設定したが暗号化の強度が不安
- DoS攻撃やボットからの防御を強化したい
- セキュリティヘッダーの設定方法を知りたい
TLS設定の強化
Let's EncryptでSSL証明書を取得しただけでは、古い暗号化プロトコルが有効なままの場合があります。
TLSv1.0/1.1を無効化する
TLSv1.0とTLSv1.1には既知の脆弱性があり、現在は非推奨です。
# /etc/nginx/nginx.conf(httpブロック内)
# 安全な設定(TLSv1.2以上のみ)
ssl_protocols TLSv1.2 TLSv1.3;
暗号スイートを制限する
ssl_prefer_server_ciphers on;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
SSLセッションキャッシュを設定する
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
ssl_session_tickets off はPerfect Forward Secrecy(PFS)を確保するために重要です。
レート制限の設定
ゾーンの定義
# /etc/nginx/nginx.conf(httpブロック内)
limit_req_zone $binary_remote_addr zone=general:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=login:10m rate=3r/s;
limit_conn_zone $binary_remote_addr zone=addr:10m;
サイト設定で適用
server {
# 一般的なレート制限
limit_req zone=general burst=20 nodelay;
limit_conn addr 20;
# ログインページに厳しい制限
location /admin/ {
limit_req zone=login burst=5 nodelay;
proxy_pass http://127.0.0.1:8080;
}
}
Fail2BanでNginxを防御する
# /etc/fail2ban/jail.d/nginx.local
[nginx-limit-req]
enabled = true
port = http,https
filter = nginx-limit-req
logpath = /var/log/nginx/error.log
maxretry = 10
findtime = 600
bantime = 3600
[nginx-botsearch]
enabled = true
port = http,https
filter = nginx-botsearch
logpath = /var/log/nginx/access.log
maxretry = 5
findtime = 600
bantime = 86400
[nginx-bad-request]
enabled = true
port = http,https
filter = nginx-bad-request
logpath = /var/log/nginx/access.log
maxretry = 5
findtime = 600
bantime = 3600
| jail名 | 検知対象 | BAN時間 |
|---|---|---|
nginx-limit-req |
レート制限超過 | 1時間 |
nginx-botsearch |
存在しないURLへのスキャン | 24時間 |
nginx-bad-request |
不正なリクエスト | 1時間 |
セキュリティヘッダーの設定
# 各serverブロックに追加
add_header X-Content-Type-Options nosniff always;
add_header X-Frame-Options DENY always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=(), payment=()" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://cdn.jsdelivr.net; style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net; img-src 'self' data:; font-src 'self' https://fonts.gstatic.com;" always;
各ヘッダーの解説
| ヘッダー | 効果 |
|---|---|
X-Content-Type-Options |
MIMEタイプ推測を防止(XSS対策) |
X-Frame-Options |
iframe埋め込みを禁止(クリックジャッキング対策) |
Strict-Transport-Security |
HTTPS接続を強制(中間者攻撃対策) |
Referrer-Policy |
リファラー情報の送信範囲を制限 |
Permissions-Policy |
カメラ・マイク等のブラウザAPIを無効化 |
Content-Security-Policy |
リソースの提供元を制限(XSS対策) |
CSPの注意点
Content-Security-Policyは厳しすぎるとサイトが正常に表示されなくなります。ブラウザの開発者ツールでCSPエラーがないか確認しながら調整しましょう。
サーバー情報の秘匿
# /etc/nginx/nginx.conf(httpブロック内)
server_tokens off;
不明なホスト名でのアクセスを遮断するデフォルトサーバーも設定します。
server {
listen 80 default_server;
server_name _;
return 444; # 接続を即座に閉じる
}
完成した設定ファイル
nginx.conf(抜粋)
http {
server_tokens off;
# Rate limiting
limit_req_zone $binary_remote_addr zone=general:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=login:10m rate=3r/s;
limit_conn_zone $binary_remote_addr zone=addr:10m;
# SSL
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:...;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
}
動作確認
# TLSv1.1で接続を試みる(拒否されるべき)
curl --tlsv1.1 --tls-max 1.1 https://example.com
# セキュリティヘッダーの確認
curl -sI https://example.com | grep -iE "(security|policy|frame)"
# Fail2Ban jailの確認
sudo fail2ban-client status
まとめ
| 対策 | 防御対象 | 設定場所 |
|---|---|---|
| TLSv1.2以上に限定 | 暗号化の脆弱性 | nginx.conf |
| レート制限 | DoS攻撃 | nginx.conf + serverブロック |
| Fail2Ban(Nginx jail) | 繰り返しの不正アクセス | jail.d/nginx.local |
| セキュリティヘッダー | XSS・クリックジャッキング | serverブロック |
| server_tokens off | バージョン情報の漏洩 | nginx.conf |
設定変更後は必ず
sudo nginx -t で構文チェックを行い、問題がなければ sudo systemctl reload nginx で反映しましょう。