Nginx (Proxy)

高性能リバースプロキシサーバー。HTTP/2、HTTP/3対応、SSL終端、キャッシング機能。イベント駆動アーキテクチャで低メモリ使用量。

Webサーバーリバースプロキシロードバランサー高性能軽量非同期HTTPHTTPS

NGINX

NGINXは、高性能でスケーラブルなWebサーバー、リバースプロキシ、ロードバランサーです。非同期イベント駆動アーキテクチャにより、少ないメモリで多数の同時接続を処理でき、静的コンテンツの配信、動的アプリケーションの処理、ロードバランシングに優れています。

主な特徴

高性能アーキテクチャ

  • 非同期イベント駆動型処理
  • 少ないメモリ使用量で高い同時接続数
  • C10K問題の解決
  • マルチプロセス・マルチワーカー構成

多機能プロキシ

  • HTTPリバースプロキシ
  • TCP/UDPプロキシ(stream module)
  • 高度なロードバランシング
  • SSL/TLS終端とオフロード

柔軟な設定システム

  • 直感的な設定ファイル構文
  • モジュールベースのアーキテクチャ
  • 動的設定リロード
  • 豊富な内蔵変数とディレクティブ

インストール

Ubuntu/Debian

# 公式リポジトリの追加
curl -fsSL https://nginx.org/keys/nginx_signing.key | sudo gpg --dearmor -o /usr/share/keyrings/nginx-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/ubuntu $(lsb_release -cs) nginx" | sudo tee /etc/apt/sources.list.d/nginx.list

# インストール
sudo apt update
sudo apt install nginx

# サービス有効化・開始
sudo systemctl enable nginx
sudo systemctl start nginx

CentOS/RHEL

# 公式リポジトリの追加
cat <<EOF | sudo tee /etc/yum.repos.d/nginx.repo
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/\$releasever/\$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
EOF

# インストール
sudo yum install nginx

# サービス有効化・開始
sudo systemctl enable nginx
sudo systemctl start nginx

ソースからのビルド

# 依存関係のインストール
sudo apt install build-essential libpcre3-dev libssl-dev zlib1g-dev

# NGINXソースのダウンロード
wget http://nginx.org/download/nginx-1.24.0.tar.gz
tar -xzf nginx-1.24.0.tar.gz
cd nginx-1.24.0

# コンパイル設定
./configure \
    --prefix=/etc/nginx \
    --sbin-path=/usr/sbin/nginx \
    --modules-path=/usr/lib/nginx/modules \
    --conf-path=/etc/nginx/nginx.conf \
    --error-log-path=/var/log/nginx/error.log \
    --access-log-path=/var/log/nginx/access.log \
    --pid-path=/var/run/nginx.pid \
    --lock-path=/var/run/nginx.lock \
    --with-http_ssl_module \
    --with-http_realip_module \
    --with-http_gzip_static_module \
    --with-http_secure_link_module \
    --with-http_stub_status_module \
    --with-stream \
    --with-stream_ssl_module

# ビルド・インストール
make
sudo make install

Docker

# 基本起動
docker run --name my-nginx -p 80:80 -d nginx

# カスタム設定とコンテンツ
docker run --name my-nginx \
  -p 80:80 \
  -v /path/to/nginx.conf:/etc/nginx/nginx.conf:ro \
  -v /path/to/html:/usr/share/nginx/html:ro \
  -d nginx

# SSL対応
docker run --name my-nginx \
  -p 80:80 \
  -p 443:443 \
  -v /path/to/ssl:/etc/nginx/ssl:ro \
  -v /path/to/nginx.conf:/etc/nginx/nginx.conf:ro \
  -d nginx

基本設定

メイン設定(nginx.conf)

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;

events {
    worker_connections 1024;
    use epoll;
    multi_accept on;
}

http {
    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" "$http_x_forwarded_for"';

    access_log /var/log/nginx/access.log main;

    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 4096;

    # Gzip設定
    gzip on;
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_types
        text/plain
        text/css
        text/xml
        text/javascript
        application/json
        application/javascript
        application/xml+rss
        application/atom+xml
        image/svg+xml;

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

    include /etc/nginx/conf.d/*.conf;
}

仮想ホスト設定

# /etc/nginx/conf.d/default.conf
server {
    listen 80;
    server_name example.com www.example.com;
    root /usr/share/nginx/html;
    index index.html index.htm;

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

    location ~ \.php$ {
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }

    location = /favicon.ico {
        log_not_found off;
        access_log off;
    }

    location = /robots.txt {
        log_not_found off;
        access_log off;
    }
}

ロードバランシング

HTTP ロードバランサー

# upstream定義
upstream backend {
    # ラウンドロビン(デフォルト)
    server backend1.example.com;
    server backend2.example.com;
    server backend3.example.com backup;
}

upstream api_servers {
    # 最小接続数
    least_conn;
    server api1.example.com:8080 weight=3;
    server api2.example.com:8080 weight=2;
    server api3.example.com:8080 weight=1;
}

upstream hash_backend {
    # ハッシュ分散(一貫性ハッシュ)
    hash $request_uri consistent;
    server cache1.example.com:8080;
    server cache2.example.com:8080;
    server cache3.example.com:8080;
}

# サーバー設定
server {
    listen 80;
    server_name load-balancer.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;

        # ヘルスチェック
        proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
        proxy_connect_timeout 5s;
        proxy_read_timeout 10s;
    }

    location /api/ {
        proxy_pass http://api_servers/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    location /cache/ {
        proxy_pass http://hash_backend/;
        proxy_set_header Host $host;
        proxy_cache_bypass $http_pragma $http_authorization;
    }
}

高度なロードバランシング設定

upstream app_servers {
    # 最小時間(NGINX Plus)
    least_time header;
    
    # サーバー設定オプション
    server app1.example.com:8080 max_fails=3 fail_timeout=30s weight=5;
    server app2.example.com:8080 max_fails=3 fail_timeout=30s weight=3;
    server app3.example.com:8080 max_fails=3 fail_timeout=30s weight=2;
    server app4.example.com:8080 max_conns=100;
    
    # バックアップサーバー
    server backup.example.com:8080 backup;
    
    # ゾーン設定(NGINX Plus)
    zone app_servers 64k;
    
    # セッション持続性(NGINX Plus)
    sticky cookie srv_id expires=1h domain=.example.com path=/;
}

# ランダム分散
upstream random_backend {
    random two least_time=last_byte;
    server srv1.example.com;
    server srv2.example.com;
    server srv3.example.com;
    server srv4.example.com;
}

TCP/UDP ロードバランシング

# streamコンテキスト
stream {
    upstream mysql_servers {
        least_conn;
        server mysql1.example.com:3306 max_fails=2 fail_timeout=30s;
        server mysql2.example.com:3306 max_fails=2 fail_timeout=30s;
        server mysql3.example.com:3306 backup;
    }

    upstream redis_servers {
        hash $remote_addr consistent;
        server redis1.example.com:6379;
        server redis2.example.com:6379;
        server redis3.example.com:6379;
    }

    upstream dns_servers {
        server 8.8.8.8:53;
        server 8.8.4.4:53;
        server 1.1.1.1:53;
    }

    # MySQL プロキシ
    server {
        listen 3306;
        proxy_pass mysql_servers;
        proxy_timeout 3s;
        proxy_connect_timeout 1s;
    }

    # Redis プロキシ
    server {
        listen 6379;
        proxy_pass redis_servers;
        proxy_timeout 5s;
        proxy_responses 1;
    }

    # DNS プロキシ(UDP)
    server {
        listen 53 udp;
        proxy_pass dns_servers;
        proxy_timeout 1s;
        proxy_responses 1;
    }
}

SSL/TLS設定

基本SSL設定

server {
    listen 443 ssl http2;
    server_name secure.example.com;

    # SSL証明書
    ssl_certificate /etc/nginx/ssl/example.com.crt;
    ssl_certificate_key /etc/nginx/ssl/example.com.key;

    # SSL設定
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-CHACHA20-POLY1305;
    ssl_prefer_server_ciphers off;

    # HSTS
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

    # OCSP ステープリング
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate /etc/nginx/ssl/chain.crt;

    # セッション設定
    ssl_session_cache shared:SSL:50m;
    ssl_session_timeout 1d;
    ssl_session_tickets off;

    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;
    }
}

# HTTPからHTTPSへのリダイレクト
server {
    listen 80;
    server_name secure.example.com;
    return 301 https://$server_name$request_uri;
}

Let's Encrypt証明書の取得

# Certbotのインストール
sudo apt install certbot python3-certbot-nginx

# 証明書の取得と設定
sudo certbot --nginx -d example.com -d www.example.com

# 証明書の自動更新設定
sudo crontab -e
# 以下を追加
0 12 * * * /usr/bin/certbot renew --quiet

キャッシュ設定

プロキシキャッシュ

# キャッシュパスの定義
proxy_cache_path /var/cache/nginx/proxy 
    levels=1:2 
    keys_zone=proxy_cache:10m 
    max_size=1g 
    inactive=60m 
    use_temp_path=off;

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

    location / {
        proxy_pass http://backend;
        proxy_cache proxy_cache;
        proxy_cache_valid 200 302 10m;
        proxy_cache_valid 404 1m;
        proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
        proxy_cache_lock on;
        proxy_cache_background_update on;

        # キャッシュヘッダー
        add_header X-Cache-Status $upstream_cache_status;
        
        # キャッシュキー
        proxy_cache_key "$scheme$request_method$host$request_uri";
        
        # 条件付きキャッシュ
        proxy_cache_bypass $http_pragma $http_authorization;
        proxy_no_cache $http_pragma $http_authorization;
    }

    # キャッシュパージ(NGINX Plus)
    location ~ /purge(/.*) {
        allow 127.0.0.1;
        deny all;
        proxy_cache_purge proxy_cache "$scheme$request_method$host$1";
    }
}

FastCGIキャッシュ

# FastCGIキャッシュパス
fastcgi_cache_path /var/cache/nginx/fastcgi 
    levels=1:2 
    keys_zone=fastcgi_cache:10m 
    max_size=500m 
    inactive=60m;

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

    location ~ \.php$ {
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;

        # FastCGIキャッシュ
        fastcgi_cache fastcgi_cache;
        fastcgi_cache_valid 200 60m;
        fastcgi_cache_valid 404 10m;
        fastcgi_cache_methods GET HEAD;
        fastcgi_cache_key "$scheme$request_method$host$request_uri";
        
        # キャッシュバイパス条件
        fastcgi_cache_bypass $http_pragma $http_authorization $cookie_nocache $arg_nocache;
        fastcgi_no_cache $http_pragma $http_authorization $cookie_nocache $arg_nocache;
        
        add_header X-FastCGI-Cache $upstream_cache_status;
    }
}

セキュリティ設定

レート制限

# レート制限ゾーンの定義
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=login_limit:10m rate=1r/s;
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;

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

    # 接続数制限
    limit_conn conn_limit 20;

    location /api/ {
        # API レート制限
        limit_req zone=api_limit burst=20 nodelay;
        proxy_pass http://api_backend;
    }

    location /login {
        # ログイン レート制限
        limit_req zone=login_limit burst=5;
        proxy_pass http://auth_backend;
    }
}

アクセス制御

# GeoIPによる制御
geo $allowed_country {
    default 0;
    JP 1;
    US 1;
    DE 1;
}

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

    # 国別アクセス制御
    if ($allowed_country = 0) {
        return 403;
    }

    # IP制限
    location /admin/ {
        allow 192.168.1.0/24;
        allow 10.0.0.0/8;
        deny all;
        proxy_pass http://admin_backend;
    }

    # Basic認証
    location /private/ {
        auth_basic "Restricted Area";
        auth_basic_user_file /etc/nginx/htpasswd;
        proxy_pass http://private_backend;
    }
}

セキュリティヘッダー

# セキュリティ設定マップ
map $sent_http_content_type $nosniff_header {
    ~^text/html "nosniff";
}

server {
    listen 443 ssl http2;
    server_name secure.example.com;

    # セキュリティヘッダー
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options $nosniff_header always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
    add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'" always;

    # HSTS
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

    # サーバー情報の隠蔽
    server_tokens off;
    more_clear_headers Server;

    location / {
        proxy_pass http://backend;
        proxy_hide_header X-Powered-By;
    }
}

監視とログ

詳細ログ設定

# カスタムログフォーマット
log_format detailed '$remote_addr - $remote_user [$time_local] '
                   '"$request" $status $body_bytes_sent '
                   '"$http_referer" "$http_user_agent" '
                   '$request_time $upstream_response_time '
                   '$upstream_addr $upstream_status';

log_format json escape=json '{'
    '"timestamp": "$time_iso8601",'
    '"remote_addr": "$remote_addr",'
    '"request": "$request",'
    '"status": $status,'
    '"body_bytes_sent": $body_bytes_sent,'
    '"request_time": $request_time,'
    '"upstream_response_time": "$upstream_response_time",'
    '"upstream_addr": "$upstream_addr"'
'}';

server {
    listen 80;
    server_name example.com;

    # 複数のアクセスログ
    access_log /var/log/nginx/access.log detailed;
    access_log /var/log/nginx/access.json json;

    # エラーログレベル
    error_log /var/log/nginx/error.log warn;

    location / {
        proxy_pass http://backend;
    }
}

ステータス・監視エンドポイント

# ステータスモジュール設定
server {
    listen 80;
    server_name status.example.com;

    location /nginx_status {
        stub_status;
        allow 127.0.0.1;
        allow 192.168.1.0/24;
        deny all;
    }

    location /health {
        access_log off;
        return 200 "healthy\n";
        add_header Content-Type text/plain;
    }

    # Plus API(NGINX Plus)
    location /api {
        api write=on;
        allow 127.0.0.1;
        deny all;
    }

    # Plus ダッシュボード(NGINX Plus)
    location = /dashboard.html {
        root /usr/share/nginx/html;
    }
}

ログローテーション

# /etc/logrotate.d/nginx
/var/log/nginx/*.log {
    daily
    missingok
    rotate 52
    compress
    delaycompress
    notifempty
    create 644 nginx nginx
    postrotate
        if [ -f /var/run/nginx.pid ]; then
            kill -USR1 `cat /var/run/nginx.pid`
        fi
    endscript
}

パフォーマンス最適化

ワーカープロセス最適化

# メインコンテキスト
user nginx;
worker_processes auto;
worker_cpu_affinity auto;
worker_priority -10;
worker_rlimit_nofile 65535;

events {
    worker_connections 4096;
    use epoll;
    multi_accept on;
    accept_mutex off;
}

http {
    # バッファサイズ調整
    client_body_buffer_size 128k;
    client_max_body_size 10m;
    client_header_buffer_size 1k;
    large_client_header_buffers 4 4k;
    output_buffers 1 32k;
    postpone_output 1460;

    # タイムアウト設定
    client_header_timeout 3m;
    client_body_timeout 3m;
    send_timeout 3m;

    # TCP最適化
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;

    # Keepalive設定
    keepalive_timeout 65;
    keepalive_requests 1000;

    # ファイルキャッシュ
    open_file_cache max=1000 inactive=20s;
    open_file_cache_valid 30s;
    open_file_cache_min_uses 2;
    open_file_cache_errors on;
}

圧縮設定

http {
    # Gzip圧縮
    gzip on;
    gzip_vary on;
    gzip_min_length 1024;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_types
        text/plain
        text/css
        text/xml
        text/javascript
        application/json
        application/javascript
        application/xml+rss
        application/atom+xml
        image/svg+xml
        application/x-font-ttf
        application/vnd.ms-fontobject
        font/opentype;

    # Brotli圧縮(モジュール必要)
    brotli on;
    brotli_comp_level 6;
    brotli_types
        text/plain
        text/css
        application/json
        application/javascript
        text/xml
        application/xml
        application/xml+rss
        text/javascript;
}

トラブルシューティング

設定テストと再起動

# 設定ファイルのテスト
nginx -t

# 設定のリロード
nginx -s reload

# プロセス停止
nginx -s stop

# プロセス再起動(graceful)
nginx -s quit

# サービス管理
systemctl status nginx
systemctl restart nginx
systemctl reload nginx

デバッグとログ分析

# エラーログの確認
tail -f /var/log/nginx/error.log

# アクセスログの分析
tail -f /var/log/nginx/access.log | grep "GET"

# リアルタイム統計(NGINX Plus)
curl http://localhost/api/8/nginx

# プロセス情報
ps aux | grep nginx

よくある問題と解決法

# 504 Gateway Timeout対策
proxy_read_timeout 300s;
proxy_connect_timeout 75s;
proxy_send_timeout 300s;

# 413 Request Entity Too Large対策
client_max_body_size 100M;

# 502 Bad Gateway対策
upstream backend {
    server 127.0.0.1:8080 max_fails=3 fail_timeout=30s;
    keepalive 32;
}

# WebSocket対応
location /ws/ {
    proxy_pass http://websocket_backend;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;
}

NGINXは、その高性能と柔軟性により、Webサーバー、リバースプロキシ、ロードバランサーとして世界中で広く採用されています。適切な設定と運用により、高可用性で拡張性の高いWebインフラストラクチャを構築できます。