Chuyển đến nội dung chính

第2課:Nginxの基本設定

nginx.confの構文、コンテキスト(http/server/location)、基本ディレクティブなどNginxの設定を学びます。 バーチャルホストの作成、静的ファイルの配信、インデックスファイル、autoindex、カスタムエラーページの設定方法を解説します。 実用的な例とプロダクションのベストプラクティスを含みます。

🔒 DevSecOps — 第2課 第2課:Nginxの基本設定

Nginxの基礎から応用まで

第1部:基礎

xdev.asia

1. nginx.conf設定ファイルの構文

nginx.confファイルはNginxの中核であり、Webサーバーの動作全体を定義します。設定構文を理解することがNginxを使いこなす第一歩です。

1.1. 基本構造

# シンプルディレクティブ (simple directive)
worker_processes 4;

ブロックディレクティブ (block directive)

events { worker_connections 1024; }

ネストされたブロック (nested blocks)

http { server { location / { root /var/www/html; } } }

1.2. 構文ルール

1. ディレクティブ:

  • 各ディレクティブはセミコロン;で終わります
  • ディレクティブはシンプル(1行)またはブロック({}付き)
  • 大文字小文字の区別あり:Rootとrootは別物
# 正しい
worker_processes 2;

誤り - セミコロンなし

worker_processes 2

誤り - 大文字小文字が違う

Worker_Processes 2;

2. コメント:

# これは1行コメントです
worker_processes 4;  # 行末コメント

Nginxには複数行コメントはありません

各行に # を使用する必要があります

3. ファイルのインクルード:

# 別ファイルをインクルード
include /etc/nginx/mime.types;

ワイルドカードで複数ファイルをインクルード

include /etc/nginx/conf.d/.conf; include /etc/nginx/sites-enabled/;

4. 変数:

# Nginxには多くの組み込み変数があります

$で始まります

$remote_addr # クライアントのIP $request_uri # リクエストのURI $host # ホスト名

使用例

location / { return 200 "Your IP: $remote_addr\n"; }

5. 文字列の値:

# シンプルな値はクォート不要
root /var/www/html;

スペースや特殊文字がある場合はクォートが必要

error_log "/var/log/nginx/error.log" warn; add_header X-Custom-Header "Hello World";

シングルクォートまたはダブルクォートが使用可能

root '/var/www/html'; root "/var/www/html";

1.3. 単位とサイズ

# 時間の単位
client_body_timeout 60s;      # 秒(デフォルト)
client_body_timeout 60;       # 秒と同じ
client_body_timeout 60m;      # 分
client_body_timeout 1h;       # 時間
client_body_timeout 1d;       # 日

サイズの単位

client_max_body_size 10m; # メガバイト client_max_body_size 10M; # メガバイトと同じ client_max_body_size 1g; # ギガバイト client_max_body_size 1024k; # キロバイト client_max_body_size 1048576; # バイト(単位なし)

1.4. 測定単位

# 単位なし = バイト
client_max_body_size 1048576;  # 1MB

k/K = キロバイト

client_max_body_size 1024k;

m/M = メガバイト

client_max_body_size 1m;

g/G = ギガバイト (Nginx 0.7.0+)

client_max_body_size 1g;


2. コンテキストとディレクティブ

Nginxはコンテキストシステムを使って設定を階層的に整理します。各コンテキストは適用されるディレクティブのスコープを定義します。

2.1. 主要なコンテキスト

# MAIN CONTEXT(グローバル)
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;

EVENTS CONTEXT

events { worker_connections 1024; use epoll; }

HTTP CONTEXT

http { # すべてのHTTPトラフィックに適用

# SERVER CONTEXT
server {
    # 特定のバーチャルホストに適用
    
    # LOCATION CONTEXT
    location / {
        # 特定のURLパターンに適用
    }
}

}

STREAM CONTEXT(TCP/UDP用)

stream { server { listen 3306; } }

MAIL CONTEXT(メールプロキシ用)

mail { server { listen 25; } }

2.2. HTTPコンテキスト — グローバル設定

http {
# MIMEタイプ
include /etc/nginx/mime.types;
default_type application/octet-stream;

# ロギング
log_format main '$remote_addr - $remote_user [$time_local] '
                '"$request" $status $body_bytes_sent '
                '"$http_referer" "$http_user_agent"';

access_log /var/log/nginx/access.log main;
error_log /var/log/nginx/error.log warn;

# パフォーマンス
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;

# Gzip圧縮
gzip on;
gzip_vary on;
gzip_comp_level 6;
gzip_types text/plain text/css application/json application/javascript;

# セキュリティヘッダー
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;

# サーバーブロックのインクルード
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;

}

2.3. サーバーコンテキスト — バーチャルホスト

http {
# サーバーブロック1
server {
listen 80;
server_name example.com www.example.com;
root /var/www/example.com;

    access_log /var/log/nginx/example.com.access.log;
    error_log /var/log/nginx/example.com.error.log;
}

# サーバーブロック2
server {
    listen 80;
    server_name blog.example.com;
    root /var/www/blog;
}

# デフォルトサーバー(キャッチオール)
server {
    listen 80 default_server;
    server_name _;
    return 444;  # 接続を閉じる
}

}

2.4. ロケーションコンテキスト — URLマッチング

server {
listen 80;
server_name example.com;
root /var/www/html;

# 完全一致
location = /about {
    # /aboutのみにマッチ
}

# プレフィックス一致
location /images/ {
    # /images/*、/images/photo.jpgなどにマッチ
}

# 正規表現一致(大文字小文字区別あり)
location ~ \.(jpg|png|gif)$ {
    # .jpg、.png、.gifで終わるファイルにマッチ
}

# 正規表現一致(大文字小文字区別なし)
location ~* \.(jpg|png|gif)$ {
    # JPG、jpg、JpGなどにマッチ
}

# プレフィックス一致(正規表現チェックを停止)
location ^~ /api/ {
    # /api/*にマッチし、正規表現チェックを停止
}

# デフォルトロケーション
location / {
    # 他にマッチがなければすべてにマッチ
}

}

2.5. ロケーションマッチングの優先順位

Nginxはロケーションを優先順位に従って処理します:

  1. = - 完全一致(最高)
  2. ^ - プレフィックス一致(正規表現停止)
  3. または ~* - 正規表現一致(ファイルの出現順)
  4. 修飾子なし - プレフィックス一致(最低)

説明例:

server {
listen 80;
server_name example.com;

# 優先度1 - 完全一致
location = /test {
    return 200 "Exact match: /test\n";
}

# 優先度2 - プレフィックス(正規表現停止)
location ^~ /test {
    return 200 "Prefix match (^~): /test*\n";
}

# 優先度3 - 正規表現(大文字小文字区別なし)
location ~* ^/test {
    return 200 "Regex match (~*): /test*\n";
}

# 優先度4 - プレフィックス一致
location /test {
    return 200 "Prefix match: /test*\n";
}

# デフォルト
location / {
    return 200 "Default location\n";
}

}

テスト結果:

curl http://example.com/test

→ "Exact match: /test"

curl http://example.com/test123

→ "Prefix match (^~): /test*"(^~が正規表現を停止するため)

^~ロケーションを削除した場合:

curl http://example.com/test123

→ "Regex match (~): /test"


3. バーチャルホストの設定(サーバーブロック)

バーチャルホストにより、1台のNginxサーバーで複数のWebサイト・ドメインを提供できます。

3.1. 最初のバーチャルホストを作成する

ステップ1:Webサイト用ディレクトリを作成する

# ドキュメントルートを作成
sudo mkdir -p /var/www/mysite.com/html

ログ用ディレクトリを作成

sudo mkdir -p /var/www/mysite.com/logs

所有権を設定

sudo chown -R $USER:$USER /var/www/mysite.com sudo chmod -R 755 /var/www/mysite.com

ステップ2:サンプルHTMLファイルを作成する

cat > /var/www/mysite.com/html/index.html << 'EOF'
<!DOCTYPE html>
<html>
<head>
<title>Welcome to mysite.com</title>
<style>
body { font-family: Arial, sans-serif; margin: 50px; }
h1 { color: #00539C; }
</style>
</head>
<body>
<h1>Welcome to mysite.com!</h1>
<p>This is my first Nginx virtual host.</p>
</body>
</html>
EOF

ステップ3:バーチャルホストの設定ファイルを作成する

# Ubuntu/Debian
sudo nano /etc/nginx/sites-available/mysite.com

CentOS/RHEL

sudo nano /etc/nginx/conf.d/mysite.com.conf

設定ファイルの内容:

server {
# ポートとサーバー名
listen 80;
listen [::]:80;
server_name mysite.com www.mysite.com;

# ドキュメントルート
root /var/www/mysite.com/html;
index index.html index.htm;

# ログ
access_log /var/www/mysite.com/logs/access.log;
error_log /var/www/mysite.com/logs/error.log;

# メインロケーション
location / {
    try_files $uri $uri/ =404;
}

# エラーページ
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;

location = /404.html {
    internal;
}

location = /50x.html {
    internal;
}

# 隠しファイルへのアクセスを拒否
location ~ /\. {
    deny all;
    access_log off;
    log_not_found off;
}

}

ステップ4:バーチャルホストを有効化する(Ubuntu/Debian)

# シンボリックリンクを作成
sudo ln -s /etc/nginx/sites-available/mysite.com /etc/nginx/sites-enabled/

設定を確認

sudo nginx -t

Nginxをリロード

sudo systemctl reload nginx

ステップ5:DNSまたはhostsファイルを設定する

# /etc/hostsに追加(ローカルテスト用)
sudo nano /etc/hosts

以下の行を追加:

127.0.0.1 mysite.com www.mysite.com

ステップ6:テスト

curl http://mysite.com

またはブラウザで: http://mysite.com

3.2. 複数ドメインのバーチャルホスト

# 設定1:同じコンテンツに複数ドメイン
server {
listen 80;
server_name mysite.com www.mysite.com example.com www.example.com;
root /var/www/mysite.com/html;
index index.html;
}

設定2:サブドメイン

server { listen 80; server_name blog.mysite.com; root /var/www/blog; index index.html; }

server { listen 80; server_name shop.mysite.com; root /var/www/shop; index index.html; }

設定3:ワイルドカードサブドメイン

server { listen 80; server_name *.mysite.com; root /var/www/subdomains/$host;

# $hostにはsubdomain.mysite.comが入ります

}

設定4:正規表現サーバー名

server { listen 80; server_name ~^(www.)?(?<domain>.+)$; root /var/www/$domain; }

3.3. デフォルトサーバー(キャッチオール)

# マッチしないリクエストを処理するデフォルトサーバー
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;  # アンダースコア = サーバー名を問わない

# オプション1:444を返す(接続を閉じる)
return 444;

# オプション2:403 Forbiddenを返す
# return 403;

# オプション3:メインサイトにリダイレクト
# return 301 https://mainsite.com$request_uri;

# オプション4:メンテナンスページを表示
# root /var/www/default;
# index maintenance.html;

}

3.4. 高度なListenディレクティブ

server {
# IPv4
listen 80;

# IPv6
listen [::]:80;

# 特定のIP
listen 192.168.1.100:80;

# 別のポート
listen 8080;

# デフォルトサーバー
listen 80 default_server;

# SSL
listen 443 ssl;
listen [::]:443 ssl;

# HTTP/2
listen 443 ssl http2;

# 複数オプション
listen 80 default_server reuseport;

}


4. 静的ファイルの配信

Nginxは静的コンテンツ(HTML、CSS、JS、画像)の配信に優れています。

4.1. 基本設定

server {
listen 80;
server_name static.example.com;

# ドキュメントルート
root /var/www/static;

# インデックスファイル
index index.html index.htm;

# メインロケーション
location / {
    try_files $uri $uri/ =404;
}

}

ディレクトリ構造:

/var/www/static/
├── index.html
├── css/
│   ├── style.css
│   └── bootstrap.css
├── js/
│   ├── app.js
│   └── jquery.js
└── images/
├── logo.png
└── background.jpg

処理されるリクエスト:

http://static.example.com/              → /var/www/static/index.html
http://static.example.com/css/style.css → /var/www/static/css/style.css
http://static.example.com/images/logo.png → /var/www/static/images/logo.png

4.2. Root と Alias

Rootディレクティブ:

location /images/ {
root /var/www/static;
}

リクエスト: /images/photo.jpg

ファイルパス: /var/www/static/images/photo.jpg

(root + ロケーションパス)

Aliasディレクティブ:

location /images/ {
alias /var/www/photos/;
}

リクエスト: /images/photo.jpg

ファイルパス: /var/www/photos/photo.jpg

(aliasがロケーションパスを置き換える)

詳細な例:

server {
listen 80;
server_name example.com;

# rootを使用
location /static/ {
    root /var/www;
}
# /static/style.css → /var/www/static/style.css

# aliasを使用
location /assets/ {
    alias /var/www/static/;
}
# /assets/style.css → /var/www/static/style.css

# 完全パスのalias
location = /favicon.ico {
    alias /var/www/icons/favicon.ico;
}

}

注意: aliasを使う場合、aliasが/で終わるならロケーションパスも/で終わる必要があります。

4.3. Try_filesディレクティブ

# 構文
try_files file ... uri;
try_files file ... =code;

例1:ファイル、フォルダの順にチェックし、なければ404

location / { try_files $uri $uri/ =404; }

例2:index.htmlにフォールバック(SPA向け)

location / { try_files $uri $uri/ /index.html; }

例3:複数ファイルをチェック

location / { try_files $uri $uri/index.html $uri.html =404; }

例4:バックエンドにフォールバック

location / { try_files $uri $uri/ @backend; }

location @backend { proxy_pass http://localhost:3000; }

4.4. ファイルタイプ別設定

server {
listen 80;
server_name cdn.example.com;
root /var/www/cdn;

# HTMLファイル
location ~ \.html$ {
    add_header Cache-Control "public, max-age=3600";
}

# CSSとJavaScript
location ~ \.(css|js)$ {
    add_header Cache-Control "public, max-age=31536000";
    access_log off;
}

# 画像
location ~ \.(jpg|jpeg|png|gif|ico|svg|webp)$ {
    add_header Cache-Control "public, max-age=31536000";
    access_log off;
    expires 1y;
}

# フォント
location ~ \.(woff|woff2|ttf|otf|eot)$ {
    add_header Cache-Control "public, max-age=31536000";
    add_header Access-Control-Allow-Origin "*";
    access_log off;
}

# 動画
location ~ \.(mp4|webm|ogg)$ {
    add_header Cache-Control "public, max-age=31536000";
    mp4;  # MP4ストリーミングを有効化
    access_log off;
}

# ダウンロード
location /downloads/ {
    add_header Content-Disposition "attachment";
}

}

4.5. 静的ファイルのセキュリティ

server {
listen 80;
root /var/www/html;

# 隠しファイルへのアクセスを拒否
location ~ /\. {
    deny all;
    access_log off;
    log_not_found off;
}

# バックアップファイルへのアクセスを拒否
location ~ ~$ {
    deny all;
    access_log off;
    log_not_found off;
}

# 設定ファイルへのアクセスを拒否
location ~ \.(conf|config|yml|yaml|ini)$ {
    deny all;
}

# 機密ディレクトリを保護
location ~ ^/(\.git|\.svn|\.env) {
    deny all;
}

}


5. インデックスファイルとAutoindexの設定

5.1. Indexディレクティブ

# 構文
index file ...;

例1:デフォルトインデックス

server { listen 80; root /var/www/html; index index.html index.htm; }

例2:複数のインデックスファイル(順番通り)

server { listen 80; root /var/www/html; index index.php index.html index.htm default.html; }

例3:ロケーション別に異なるインデックスファイル

server { listen 80; root /var/www/html;

location / {
    index index.html;
}

location /blog/ {
    index index.php;
}

location /docs/ {
    index readme.md index.html;
}

}

5.2. Autoindex(ディレクトリ一覧)

# autoindexを有効化
server {
listen 80;
server_name files.example.com;
root /var/www/files;

location / {
    autoindex on;
}

}

autoindexの詳細設定

location /downloads/ { autoindex on; # ディレクトリ一覧を有効化 autoindex_exact_size off; # サイズをバイトではなくKB、MBで表示 autoindex_localtime on; # GMTではなくローカル時刻を表示 autoindex_format html; # フォーマット: html、xml、json、jsonp }

JSON形式の例

location /api/files/ { autoindex on; autoindex_format json; }

Autoindexの出力:

Index of /downloads/

../ file1.pdf 23-Nov-2024 10:30 2.5M file2.zip 22-Nov-2024 15:45 15M folder/ 20-Nov-2024 09:00 -

5.3. カスタムAutoindexのスタイリング

server {
listen 80;
root /var/www/files;

location / {
    autoindex on;
    autoindex_exact_size off;
    autoindex_localtime on;
    
    # カスタムヘッダー/フッターを追加
    add_before_body /autoindex/header.html;
    add_after_body /autoindex/footer.html;
}

location /autoindex/ {
    internal;
    alias /var/www/autoindex/;
}

}

header.htmlファイル:

<!DOCTYPE html>
<html>
<head>
<title>File Directory</title>
<style>
body { font-family: Arial; margin: 20px; }
h1 { color: #333; }
a { color: #0066cc; text-decoration: none; }
a:hover { text-decoration: underline; }
</style>
</head>
<body>
<h1>File Directory</h1>
<hr>

footer.htmlファイル:

    <hr>
<p>© 2024 My Company</p>
</body>
</html>

6. カスタムエラーページ

6.1. 基本設定

server {
listen 80;
server_name example.com;
root /var/www/html;

# カスタムエラーページ
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;

# エラーページのロケーション
location = /404.html {
    internal;  # 内部からのみアクセス可能
}

location = /50x.html {
    internal;
}

}

6.2. 詳細なエラーページ

404.htmlファイルの作成:

cat > /var/www/html/404.html << 'EOF'
<!DOCTYPE html>
<html>
<head>
<title>404 - Page Not Found</title>
<style>
body {
font-family: Arial, sans-serif;
text-align: center;
padding: 50px;
background: #f5f5f5;
}
h1 { font-size: 72px; color: #e74c3c; }
p { font-size: 24px; color: #555; }
a { color: #3498db; text-decoration: none; }
</style>
</head>
<body>
<h1>404</h1>
<p>Oops! Page not found.</p>
<p><a href="/">← Go back home</a></p>
</body>
</html>
EOF

50x.htmlファイルの作成:

cat > /var/www/html/50x.html << 'EOF'
<!DOCTYPE html>
<html>
<head>
<title>500 - Server Error</title>
<style>
body {
font-family: Arial, sans-serif;
text-align: center;
padding: 50px;
background: #f5f5f5;
}
h1 { font-size: 72px; color: #e67e22; }
p { font-size: 24px; color: #555; }
</style>
</head>
<body>
<h1>500</h1>
<p>Internal Server Error</p>
<p>We're working on it!</p>
</body>
</html>
EOF

6.3. 高度なエラーページ

server {
listen 80;
server_name example.com;
root /var/www/html;

# ロケーション別エラーページ
location / {
    error_page 404 /errors/404.html;
}

location /api/ {
    error_page 404 /errors/api-404.json;
    error_page 500 /errors/api-500.json;
}

# カスタムメッセージ付きエラーページ
location /special/ {
    error_page 404 =200 /custom-404.html;
    # =200 でステータスコードを上書き
}

# 外部エラーページへリダイレクト
location /old-site/ {
    error_page 404 = @external_error;
}

location @external_error {
    return 302 https://example.com/error-handler;
}

# 変数付きエラーページ
location /dynamic/ {
    error_page 404 /404.html?page=$uri;
}

# エラー用の名前付きロケーション
error_page 404 = @notfound;

location @notfound {
    return 404 "Custom 404 message\n";
}

}

6.4. フォーマット付きエラーログ

http {
# カスタムエラーログフォーマットを定義
log_format error_log '[$time_local] $status $request '
'Client: $remote_addr '
'Server: $server_name';

server {
    listen 80;
    server_name example.com;
    
    # カスタムフォーマットを使用
    error_log /var/log/nginx/example.error.log error_log;
    
    # 異なるログレベル
    error_log /var/log/nginx/debug.log debug;
}

}


7. 実践演習

演習1:バーチャルホストを作成する

  1. mysite.localのバーチャルホストを作成する
  2. ドキュメントルート:/var/www/mysite
  3. 任意の内容でindex.htmlを作成する
  4. /etc/hostsに追加してテストする

演習2:静的ファイルサーバー

  1. ディレクトリ構造を作成する:
/var/www/static/
├── index.html
├── css/style.css
├── js/app.js
└── images/logo.png
  1. これらのファイルを配信するようNginxを設定する
  2. ファイルタイプ別に異なるキャッシュヘッダーを設定する

演習3:ディレクトリ一覧

  1. files.localのバーチャルホストを作成する
  2. autoindexを有効化する
  3. フォーマットとスタイルをカスタマイズする
  4. 複数のファイルでテストする

演習4:カスタムエラーページ

  1. カスタムの404ページと500ページを作成する
  2. バーチャルホストに適用する
  3. 存在しないURLにアクセスしてテストする
  4. 500エラーをテストする(return 500でシミュレート可能)

演習5:複数のバーチャルホスト

  1. 3つのバーチャルホストを作成する:
    • site1.local → /var/www/site1
    • site2.local → /var/www/site2
    • blog.site1.local → /var/www/blog
  2. 各サイトのコンテンツを異なるものにする
  3. すべてを設定してテストする

8. よくあるトラブルシューティング

エラー1:403 Forbidden

# 原因: パーミッション
ls -la /var/www/html

修正: 正しい所有権を設定

sudo chown -R www-data:www-data /var/www/html sudo chmod -R 755 /var/www/html

原因: SELinux(CentOS)

sudo setenforce 0

エラー2:404 Not Found

# rootディレクティブを確認
location / {
root /var/www/html;  # このパスは正しいですか?
index index.html;    # このファイルは存在しますか?
}

curlで確認

curl -I http://example.com

エラー3:設定がリロードされない

# まず設定をテスト
sudo nginx -t

OKであればリロード

sudo systemctl reload nginx

エラーログを確認

sudo tail -f /var/log/nginx/error.log

エラー4:サーバー名が機能しない

# DNS/hostsを確認
cat /etc/hosts

server_nameディレクティブを確認

grep server_name /etc/nginx/sites-available/*

ブラウザキャッシュをクリア

またはcurlでテスト

curl -H "Host: mysite.com" http://localhost


9. ベストプラクティス

  1. 設定ファイルを整理する:
/etc/nginx/
├── nginx.conf(メイン設定)
├── conf.d/(グローバル設定)
└── sites-available/(個別サイト)
  1. コメントを明確にする:
# スパムボットをブロック
if ($http_user_agent ~* (bot|crawler|spider)) {
return 403;
}
  1. インクルードを使用する:
http {
include /etc/nginx/mime.types;
include /etc/nginx/conf.d/*.conf;
}
  1. リロード前にテストする:
sudo nginx -t && sudo systemctl reload nginx
  1. 設定をバックアップする:
sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.backup

まとめ

この課では以下を学びました:

  • ✅ nginx.confの構文と構造
  • ✅ Nginxのコンテキストとディレクティブ
  • ✅ バーチャルホストの作成と管理
  • ✅ 静的ファイルの効率的な配信
  • ✅ インデックスファイルとautoindexの設定
  • ✅ エラーページのカスタマイズ

次の課: ロギングとモニタリングについて学びます——Nginxサーバーのトラフィックを追跡・分析する方法です。