nginx設定完全マニュアル:セキュリティ対策、パフォーマンス向上
nginx(エンジンエックス)は、高性能なWebサーバ、リバースプロキシ、ロードバランサ、そしてHTTPキャッシュとして広く利用されています。その柔軟性と拡張性の高さから、小規模な個人ウェブサイトから大規模なエンタープライズシステムまで、様々な環境で活用されています。本記事では、nginxの設定を深く掘り下げ、セキュリティ対策、パフォーマンス向上に焦点を当て、具体的な設定例と詳細な解説を提供します。
目次
-
nginxの基礎
- 1.1 nginxとは何か
- 1.2 アーキテクチャの概要
- 1.3 設定ファイルの構造
- 1.4 基本的な設定ディレクティブ
-
セキュリティ対策
- 2.1 バージョン情報の秘匿
- 2.2 不要なHTTPメソッドの禁止
- 2.3 HTTP Strict Transport Security (HSTS) の設定
- 2.4 SSL/TLS暗号スイートの設定
- 2.5 DDoS攻撃対策
- 2.5.1 リクエストレート制限 (Limit Request)
- 2.5.2 コネクション数制限 (Limit Connection)
- 2.5.3 IPアドレスによるアクセス制限
- 2.6 Web Application Firewall (WAF) の導入
- 2.7 クライアント証明書の利用
- 2.8 Content Security Policy (CSP) の設定
-
パフォーマンス向上
- 3.1 Keep-Alive接続の設定
- 3.2 Gzip圧縮の設定
- 3.3 静的コンテンツのキャッシュ
- 3.4 Dynamic Moduleの利用
- 3.5 worker_processesとworker_connectionsの設定
- 3.6 イベントモデルの設定
- 3.7 TCP_NODELAYとTCP_NOPUSHの設定
- 3.8 オープンファイル数の上限設定
- 3.9 HTTP/2 & HTTP/3 の有効化
-
リバースプロキシとロードバランサの設定
- 4.1 リバースプロキシの設定
- 4.2 ロードバランシングの設定
- 4.2.1 ラウンドロビン
- 4.2.2 リーストコネクション
- 4.2.3 IPハッシュ
- 4.2.4 ヘルスチェック
- 4.2.5 セッション維持 (Sticky Sessions)
- 4.3 キャッシュによる負荷軽減
-
応用的な設定
- 5.1 URLリライトとリダイレクト
- 5.2 カスタムエラーページの設定
- 5.3 Basic認証の設定
- 5.4 GeoIPモジュールの利用
- 5.5 Luaモジュールの利用
-
トラブルシューティング
- 6.1 ログの確認
- 6.2 設定ファイルの検証
- 6.3 一般的なエラーとその解決策
1. nginxの基礎
1.1 nginxとは何か
nginxは、イゴール・シソエフによって開発された、高性能なWebサーバ、リバースプロキシ、ロードバランサ、そしてHTTPキャッシュとして利用できるソフトウェアです。Apache HTTP Serverと比較して、少ないリソースでより多くの同時接続を処理できることが特徴です。C言語で記述されており、高速で効率的な動作を実現します。
1.2 アーキテクチャの概要
nginxのアーキテクチャは、イベント駆動型、非同期、ノンブロッキングI/Oモデルに基づいています。
- Master Process: 設定ファイルの読み込み、ワーカプロセス管理を担当します。
- Worker Processes: 実際のHTTPリクエストの処理を担当します。複数のワーカプロセスが並列で動作することで、高い同時接続性とスループットを実現します。
- Cache Manager Process (Optional): キャッシュの管理を行います。
1.3 設定ファイルの構造
nginxの設定ファイルは、テキスト形式で記述され、通常/etc/nginx/nginx.confに保存されています。設定ファイルは、ディレクティブと呼ばれる命令の集合で構成されます。ディレクティブは、ブロックと呼ばれる構造の中にグループ化されます。
- main: nginx全体の動作を制御するディレクティブが含まれます。
- http: HTTPに関する設定を行います。
- server: 仮想ホスト(ウェブサイト)の設定を行います。
- location: 特定のURLパスに対する設定を行います。
- upstream: バックエンドサーバグループの設定を行います (ロードバランシングで使用)。
1.4 基本的な設定ディレクティブ
listen: 待ち受けるポート番号とアドレスを指定します。例:listen 80;server_name: 仮想ホストのドメイン名を指定します。例:server_name example.com;root: ドキュメントルート(ウェブサイトのファイルが置かれているディレクトリ)を指定します。例:root /var/www/example.com;index: ディレクトリへのアクセス時に表示するファイル名を指定します。例:index index.html index.htm;location: 特定のURLパスに対する設定を定義します。例:
nginx
location / {
try_files $uri $uri/ =404;
}
error_page: エラー発生時に表示するページを指定します。例:error_page 404 /404.html;access_log: アクセスログの保存先を指定します。例:access_log /var/log/nginx/access.log main;error_log: エラーログの保存先を指定します。例:error_log /var/log/nginx/error.log;
2. セキュリティ対策
2.1 バージョン情報の秘匿
nginxのバージョン情報は、セキュリティ上の脆弱性情報として悪用される可能性があるため、非表示にすることが推奨されます。httpブロックに以下のディレクティブを追加します。
nginx
http {
server_tokens off;
...
}
2.2 不要なHTTPメソッドの禁止
GET、POST以外のHTTPメソッド(PUT、DELETE、OPTIONSなど)は、必要がない場合は禁止することで、攻撃のリスクを低減できます。
nginx
server {
...
if ($request_method !~ ^(GET|HEAD|POST)$) {
return 405;
}
...
}
2.3 HTTP Strict Transport Security (HSTS) の設定
HSTSは、ブラウザに対してHTTPS接続のみを強制する仕組みです。中間者攻撃を防ぐ効果があります。
nginx
server {
listen 443 ssl;
...
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
...
}
max-age: ブラウザがHTTPSのみを強制する期間(秒)を指定します。includeSubDomains: サブドメインにもHSTSを適用します。preload: HSTSプリロードリストに登録することで、初回アクセス時からHTTPSを強制できます(任意)。
2.4 SSL/TLS暗号スイートの設定
強力な暗号スイートのみを許可し、脆弱な暗号スイートを禁止することで、SSL/TLS通信のセキュリティを強化できます。
nginx
server {
listen 443 ssl;
...
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers EECDH+AESGCM:!DHE+AESGCM:ECDH+CHACHA20:!DHE+CHACHA20:!MD5:!aNULL;
ssl_prefer_server_ciphers on;
...
}
ssl_protocols: 使用するTLSプロトコルを指定します。TLSv1.2およびTLSv1.3を推奨します。ssl_ciphers: 使用する暗号スイートを指定します。脆弱な暗号スイート(MD5など)は除外します。ssl_prefer_server_ciphers: サーバ側の暗号スイートを優先するように設定します。
2.5 DDoS攻撃対策
DDoS攻撃(分散型サービス妨害攻撃)は、大量のリクエストを送りつけることでサーバを過負荷状態にし、サービスを停止させる攻撃です。nginxは、いくつかの方法でDDoS攻撃を緩和することができます。
2.5.1 リクエストレート制限 (Limit Request)
特定のIPアドレスからのリクエストレートを制限します。
nginx
http {
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=1r/s;
...
server {
...
location / {
limit_req zone=mylimit burst=5 nodelay;
...
}
}
}
limit_req_zone: リクエストレート制限の設定を定義します。$binary_remote_addr: クライアントのIPアドレスを使用します。zone=mylimit:10m: 制限情報を保存するゾーンの名前とサイズを指定します。rate=1r/s: 1秒あたり1リクエストまで許可します。
limit_req: リクエストレート制限を適用します。zone=mylimit: 使用する制限ゾーンを指定します。burst=5: 制限を超えたリクエストを一時的にキューに入れる数(バーストサイズ)を指定します。nodelay: バーストサイズを超えたリクエストを即座に破棄します。
2.5.2 コネクション数制限 (Limit Connection)
特定のIPアドレスからの同時接続数を制限します。
nginx
http {
limit_conn_zone $binary_remote_addr zone=myconnlimit:10m;
...
server {
...
location / {
limit_conn myconnlimit 10;
...
}
}
}
limit_conn_zone: コネクション数制限の設定を定義します。$binary_remote_addr: クライアントのIPアドレスを使用します。zone=myconnlimit:10m: 制限情報を保存するゾーンの名前とサイズを指定します。
limit_conn: コネクション数制限を適用します。myconnlimit: 使用する制限ゾーンを指定します。10: 1つのIPアドレスからの同時接続数を10に制限します。
2.5.3 IPアドレスによるアクセス制限
特定のIPアドレスまたはネットワークからのアクセスを許可/拒否します。
nginx
location / {
allow 192.168.1.0/24; # 192.168.1.0/24 ネットワークからのアクセスを許可
deny all; # 他のすべてのアクセスを拒否
...
}
2.6 Web Application Firewall (WAF) の導入
WAFは、SQLインジェクションやクロスサイトスクリプティング(XSS)などのWebアプリケーションに対する攻撃を検知・防御するセキュリティ対策です。nginxには、ModSecurityなどのWAFモジュールを導入できます。ModSecurityは、ルールベースのWAFであり、OWASP ModSecurity Core Rule Set (CRS) などのオープンソースのルールセットを利用することで、一般的なWebアプリケーションの脆弱性に対応できます。
2.7 クライアント証明書の利用
クライアント証明書を利用することで、特定のクライアントのみにアクセスを許可できます。
nginx
server {
listen 443 ssl;
ssl_client_certificate /path/to/ca.crt;
ssl_verify_client on;
...
}
ssl_client_certificate: クライアント証明書の検証に使用するCA証明書を指定します。ssl_verify_client: クライアント証明書の検証を有効にします。onに設定すると、クライアント証明書が必須になります。
2.8 Content Security Policy (CSP) の設定
CSPは、ブラウザに対して、許可されたリソース(スクリプト、スタイルシート、画像など)のソースを指定することで、XSS攻撃のリスクを軽減するセキュリティ対策です。
nginx
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'";
default-src: すべてのリソースタイプに対するデフォルトのポリシーを指定します。'self'は、同じオリジンからのリソースのみを許可します。script-src: スクリプトのソースを指定します。'unsafe-inline'は、インラインスクリプトを許可します(非推奨)。style-src: スタイルシートのソースを指定します。'unsafe-inline'は、インラインスタイルを許可します(非推奨)。
3. パフォーマンス向上
3.1 Keep-Alive接続の設定
Keep-Alive接続を使用することで、複数のHTTPリクエストを1つのTCP接続で処理でき、TCP接続の確立と切断のオーバーヘッドを削減できます。
nginx
http {
keepalive_timeout 65;
...
}
keepalive_timeout: Keep-Alive接続を維持する時間を秒単位で指定します。
3.2 Gzip圧縮の設定
Gzip圧縮を使用することで、HTTPレスポンスのサイズを削減し、ネットワーク帯域幅の使用量を削減できます。
nginx
http {
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss image/svg+xml;
...
}
gzip on: Gzip圧縮を有効にします。gzip_disable: 特定のブラウザに対するGzip圧縮を無効にします。gzip_vary:Vary: Accept-Encodingヘッダーを追加し、プロキシサーバがGzip圧縮されたコンテンツと非圧縮コンテンツを区別できるようにします。gzip_proxied: プロキシサーバ経由のリクエストに対するGzip圧縮を有効にします。gzip_comp_level: Gzip圧縮レベルを指定します(1〜9)。9が最も高い圧縮率ですが、CPU負荷も高くなります。gzip_buffers: Gzip圧縮に使用するバッファの数とサイズを指定します。gzip_http_version: Gzip圧縮を適用するHTTPバージョンを指定します。gzip_types: Gzip圧縮を適用するMIMEタイプを指定します。
3.3 静的コンテンツのキャッシュ
静的コンテンツ(画像、CSS、JavaScriptなど)をキャッシュすることで、クライアントが再度同じリソースを要求した際に、サーバから再取得する必要がなくなり、レスポンス時間を短縮できます。
nginx
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 30d;
add_header Cache-Control "public, max-age=2592000";
}
expires: キャッシュの有効期限を指定します。add_header Cache-Control:Cache-Controlヘッダーを追加し、ブラウザやプロキシサーバに対するキャッシュ制御を指示します。
3.4 Dynamic Moduleの利用
nginxは、モジュールと呼ばれる拡張機能を追加することで、様々な機能を追加できます。Dynamic Moduleを利用することで、必要なモジュールのみをロードし、メモリ使用量を削減できます。
3.5 worker_processesとworker_connectionsの設定
worker_processesとworker_connectionsは、nginxのパフォーマンスに大きく影響を与える重要な設定です。
nginx
worker_processes auto;
events {
worker_connections 1024;
}
worker_processes: ワーカプロセスの数を指定します。autoに設定すると、CPUコア数に合わせて自動的に調整されます。worker_connections: 各ワーカプロセスが同時に処理できる接続数を指定します。
3.6 イベントモデルの設定
nginxは、複数のイベントモデル(epoll、kqueueなど)をサポートしています。最適なイベントモデルを選択することで、パフォーマンスを向上させることができます。Linux環境では、epollが推奨されます。
nginx
events {
use epoll;
...
}
3.7 TCP_NODELAYとTCP_NOPUSHの設定
TCP_NODELAYを有効にすると、Nagleアルゴリズムが無効になり、小さなパケットでも即座に送信されます。TCP_NOPUSHを有効にすると、nginxはデータをすぐに送信せず、より多くのデータがバッファリングされるまで待機します。TCP_NODELAYは、リアルタイム性の高いアプリケーションに適しており、TCP_NOPUSHは、スループットを重視するアプリケーションに適しています。
nginx
http {
tcp_nodelay on;
tcp_nopush on;
...
}
3.8 オープンファイル数の上限設定
nginxが処理できるファイル数の上限を設定します。
nginx
worker_rlimit_nofile 65535;
worker_rlimit_nofile: ワーカプロセスがオープンできるファイル数の上限を指定します。
3.9 HTTP/2 & HTTP/3 の有効化
HTTP/2は、HTTP/1.1と比較して、多重化、ヘッダー圧縮などの機能により、パフォーマンスを向上させます。HTTP/3は、QUICプロトコルを使用し、TCPのボトルネックを解消します。
“`nginx
server {
listen 443 ssl http2;
# または、HTTP/3を有効にする場合
# listen 443 quic reuseport;
ssl_certificate /path/to/certificate.pem;
ssl_certificate_key /path/to/private.key;
...
}
HTTP/3に必要な設定 (nginx 1.25.0 以降)
http {
…
quic_retry on;
add_header Alt-Svc ‘h3=”:443″; ma=86400’;
}
“`
4. リバースプロキシとロードバランサの設定
4.1 リバースプロキシの設定
リバースプロキシは、クライアントからのリクエストを受け付け、バックエンドサーバに転送する役割を果たします。
“`nginx
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend_server;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
“`
proxy_pass: バックエンドサーバのアドレスを指定します。proxy_set_header: バックエンドサーバに転送するHTTPヘッダーを設定します。
4.2 ロードバランシングの設定
ロードバランサは、複数のバックエンドサーバにリクエストを分散させることで、負荷分散と可用性を向上させます。
“`nginx
upstream backend {
server backend1.example.com;
server backend2.example.com;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
“`
upstream: バックエンドサーバグループを定義します。
4.2.1 ラウンドロビン
デフォルトのロードバランシングアルゴリズムであり、順番にリクエストをバックエンドサーバに分散させます。
4.2.2 リーストコネクション
現在接続数が最も少ないバックエンドサーバにリクエストを分散させます。
nginx
upstream backend {
least_conn;
server backend1.example.com;
server backend2.example.com;
}
4.2.3 IPハッシュ
クライアントのIPアドレスをハッシュ化し、同じIPアドレスからのリクエストを常に同じバックエンドサーバに分散させます。セッション維持が必要な場合に有効です。
nginx
upstream backend {
ip_hash;
server backend1.example.com;
server backend2.example.com;
}
4.2.4 ヘルスチェック
バックエンドサーバの状態を監視し、ダウンしているサーバへのリクエストを停止します。
nginx
upstream backend {
server backend1.example.com max_fails=3 fail_timeout=30s;
server backend2.example.com max_fails=3 fail_timeout=30s;
}
max_fails: ヘルスチェックに失敗する回数を指定します。fail_timeout: ヘルスチェックに失敗した場合、サーバをダウンとみなすまでの時間を指定します。
4.2.5 セッション維持 (Sticky Sessions)
特定のクライアントからのリクエストを常に同じバックエンドサーバに分散させる機能です。ip_hash以外にも、CookieやURLパラメータを利用する方法があります。
4.3 キャッシュによる負荷軽減
リバースプロキシとしてnginxを使用する場合、キャッシュ機能を有効にすることで、バックエンドサーバへの負荷を軽減できます。
nginx
http {
proxy_cache_path /tmp/nginx_cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off;
proxy_cache_key "$scheme$request_method$host$request_uri";
...
server {
...
location / {
proxy_cache my_cache;
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
proxy_cache_use_stale error timeout invalid_header updating;
proxy_pass http://backend;
...
}
}
}
proxy_cache_path: キャッシュファイルの保存先ディレクトリを指定します。keys_zone: キャッシュキーを保存するゾーンの名前とサイズを指定します。max_size: キャッシュの最大サイズを指定します。inactive: キャッシュがアクセスされなかった場合に削除されるまでの時間を指定します。use_temp_path: キャッシュファイルを一時ディレクトリに保存するかどうかを指定します。proxy_cache: 使用するキャッシュゾーンを指定します。proxy_cache_valid: HTTPステータスコードごとにキャッシュの有効期限を指定します。proxy_cache_use_stale: バックエンドサーバがダウンしている場合やタイムアウトした場合に、古いキャッシュを使用するかどうかを指定します。
5. 応用的な設定
5.1 URLリライトとリダイレクト
URLリライトは、URLを書き換える機能です。URLリダイレクトは、クライアントを別のURLに転送する機能です。
“`nginx
location /old-page {
rewrite ^/old-page$ /new-page permanent;
}
location / {
try_files $uri $uri/ /index.php?$args;
}
“`
rewrite: URLを書き換えるルールを指定します。redirect: クライアントを別のURLに転送します。try_files: ファイルが存在するかどうかを確認し、存在しない場合は別の処理を実行します。
5.2 カスタムエラーページの設定
エラー発生時に表示するカスタムエラーページを設定できます。
“`nginx
error_page 404 /404.html;
location = /404.html {
root /var/www/example.com;
internal;
}
“`
5.3 Basic認証の設定
Basic認証を使用して、特定のディレクトリへのアクセスを制限できます。
nginx
location /private {
auth_basic "Restricted Area";
auth_basic_user_file /etc/nginx/.htpasswd;
}
auth_basic: 認証メッセージを指定します。auth_basic_user_file: ユーザー名とパスワードを保存するファイルを指定します。
5.4 GeoIPモジュールの利用
GeoIPモジュールを使用することで、クライアントのIPアドレスから国や地域などの情報を取得できます。
5.5 Luaモジュールの利用
Luaモジュールを使用することで、nginxの動作をカスタマイズできます。
6. トラブルシューティング
6.1 ログの確認
nginxのアクセスログとエラーログは、トラブルシューティングに役立ちます。
- アクセスログ:
/var/log/nginx/access.log - エラーログ:
/var/log/nginx/error.log
6.2 設定ファイルの検証
設定ファイルの構文エラーを検証するには、以下のコマンドを実行します。
bash
nginx -t
6.3 一般的なエラーとその解決策
403 Forbidden: アクセス権限がない場合に発生します。- 解決策: ファイルのアクセス権を確認するか、nginxの設定でアクセスを許可します。
502 Bad Gateway: バックエンドサーバが応答しない場合に発生します。- 解決策: バックエンドサーバが起動しているか、ネットワーク接続を確認します。
504 Gateway Timeout: バックエンドサーバからの応答がタイムアウトした場合に発生します。- 解決策: バックエンドサーバの処理時間を確認するか、nginxの設定でタイムアウト時間を延長します。
まとめ
本記事では、nginxの設定を深く掘り下げ、セキュリティ対策、パフォーマンス向上に焦点を当て、具体的な設定例と詳細な解説を提供しました。nginxは、柔軟性と拡張性の高いWebサーバであり、様々な設定を組み合わせることで、高度なセキュリティとパフォーマンスを実現できます。本記事が、nginxの設定を理解し、効果的に活用するための一助となれば幸いです。