This page shows a beginner-friendly, low-risk way to add baseline security headers in Nginx, including how to find your active config file, where to put the directives, and how to verify the results with nginx -t and curl -I.
「セキュリティヘッダを入れたいけど、サイトが壊れるのが怖い」——この不安はとても自然です。ヘッダの中には入れ方を間違えると動作に影響するものがありますが、逆に“ほぼ壊れない”基本セットもあります。
このページでは、まず事故りにくい基本セットを入れて、テスト→反映→確認までを手順化します。個人情報になりやすい部分(ドメイン名など)は example.com で例示します。
sakura.conf のようなファイル)がどこにあるか分からないときの探し方nginx -t → reload → curl -I で確認する方法Content-Security-Policy(CSP):強力ですが壊しやすいので、別ページで段階導入が安全です/etc/nginx/nginx.conf の include 行を確認する/etc/nginx/conf.d/ などにある “仮想ホスト設定” を探すsudo nginx -T で「実際に読まれている設定」から確定するserver { ... } に基本ヘッダを追加ヘッダはHTTPS側(listen 443 ssl ...)の server ブロックに入れるのが基本です。
sudo nginx -t(文法チェック)sudo systemctl reload nginx(反映)curl -I https://example.com/(ヘッダ確認)「設定を変えたいけど、どのファイルを編集すればいいか分からない」問題は、入口→include→実体の順で辿ると解決します。
sudo ls -l /etc/nginx/nginx.conf
sudo grep -n 'include' /etc/nginx/nginx.conf
よくある例:
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/default.d/*.conf;
sudo ls -la /etc/nginx/conf.d
sudo ls -la /etc/nginx/default.d
example.conf のようなファイルが並んでいれば、その中に目的のサイト設定(仮想ホスト設定)が入っていることが多いです。
「ファイルはあるけど読み込まれていない」を避けるため、最後はこれが確実です。
sudo nginx -T 2>/tmp/nginx_full_dump.txt
grep -n 'example\.conf' /tmp/nginx_full_dump.txt
ファイル名が分からない場合は、サイトのドメインや root のパスで探すと早いです。
grep -n 'server_name' /tmp/nginx_full_dump.txt
grep -n 'root ' /tmp/nginx_full_dump.txt
sudo find /etc/nginx -type f -name 'sakura.conf' -print
listen 443 ssl http2; は問題?多くの環境で、HTTPSの待ち受けは次のどちらかです。
listen 443 ssl;
listen 443 ssl http2;
http2 が付いていても基本的に問題ありません。HTTPSに加えてHTTP/2も使えるようにする指定です。sudo nginx -t を実行します。sudo nginx -t
nginx -v
ここからが本題です。まずはアプリを壊しにくい基本セットを入れます(CSPはまだ入れません)。
HTTPS側の server { ... } の中で、location より上(root より上だと分かりやすい)に置くのが安全です。
# --- Security Headers (baseline / low-risk) ---
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;
# HSTS: HTTPSを強制(常時HTTPS運用が前提)
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
X-Content-Type-Options: nosniffX-Frame-Options: SAMEORIGINReferrer-PolicyPermissions-PolicyStrict-Transport-Security(HSTS)# 例:/etc/nginx/conf.d/example.conf を編集
sudo nano /etc/nginx/conf.d/example.conf
# 文法チェック(ここが最重要)
sudo nginx -t
# 反映(切り替えではなく“再読み込み”)
sudo systemctl reload nginx
curl -I https://example.com/
期待する例(抜粋):
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
referrer-policy: strict-origin-when-cross-origin
permissions-policy: geolocation=(), microphone=(), camera=()
strict-transport-security: max-age=31536000; includeSubDomains
sudo nginx -t が通らないなら、reloadしない.bak を残すのは良い習慣です(Nginxは通常 *.conf だけを読み込みます)。Strict-Transport-Security)は「常時HTTPS」が前提max-age を短め(例:1日)から始めてもOKです。/etc/nginx/nginx.conf の include を確認/etc/nginx/conf.d などの *.conf を確認cp example.conf example.conf.bakserver にヘッダを追加(baseline)sudo nginx -t(成功するまで次へ進まない)sudo systemctl reload nginxcurl -I でヘッダが出ているか確認sudo nginx -T で「実際に読み込まれている設定」を出し、ドメイン名(server_name)で検索するのが一番確実です。listen 443 ssl http2; は消した方がいいですか?sudo nginx -t に警告が出ていないかを確認してください。curl -I で確認します。