Nginxの設定で押さえておきたいポイント

Nginxを使う上で、押さえておきたいと思ったポイントを紹介します。基本的な設定、TLS/SSLの利用、PHP-FPMとの連携などについて取り上げています。

インストール・起動

CentOS7.2上にNginxをインストールします。

yum install epel-release
yum install nginx

バージョンを確認します。

611-web-server-nginx_0.png
  • 1.9.5
    • HTTP/2がサポートされ始める
  • 1.9.11
    • 動的モジュールがサポートされ始める

よく使うコマンドを示します。

# 起動
systemctl start nginx.service
   
# 停止
systemctl stop nginx.service
 
# 設定ファイル再読み込み
nginx -s reload
 
# 設定ファイル構文チェック
nginx -t
 
# バージョン確認
nginx -v

デフォルトの設定

設定ファイルは「/etc/nginx」に格納されています。

611-web-server-nginx_1.png

この中の nginx.conf がベースとなる設定ファイルです。nginx.conf 内で他の設定ファイルをincludeしています。

$ grep include nginx.conf
include /usr/share/nginx/modules/*.conf;
    include             /etc/nginx/mime.types;
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    include /etc/nginx/conf.d/*.conf;
        include /etc/nginx/default.d/*.conf;
#        include /etc/nginx/default.d/*.conf;

/usr/share/nginx/modules 配下にも設定ファイルがあるようです。動的モジュールの設定ファイルになります。

611-web-server-nginx_2.png
動的モジュール
nginx/1.9.11で動的モジュールがサポートされました。以前は静的モジュールのみしか対応してなかったため、モジュールの追加を行うたびにnginxバイナリをビルドし直す必要がありました。

nginx.conf のデフォルトの記述は以下のようになっていました。

# For more information on configuration, see:
#   * Official English Documentation: http://nginx.org/en/docs/
#   * Official Russian Documentation: http://nginx.org/ru/docs/
 
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
 
# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
 
events {
    worker_connections 1024;
}
 
http {
    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 2048;
 
    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;
 
    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;
 
    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  _;
        root         /usr/share/nginx/html;
 
        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;
 
        location / {
        }
 
        error_page 404 /404.html;
            location = /40x.html {
        }
 
        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }
 
# Settings for a TLS enabled server.
#
#    server {
#        listen       443 ssl http2 default_server;
#        listen       [::]:443 ssl http2 default_server;
#        server_name  _;
#        root         /usr/share/nginx/html;
#
#        ssl_certificate "/etc/pki/nginx/server.crt";
#        ssl_certificate_key "/etc/pki/nginx/private/server.key";
#        ssl_session_cache shared:SSL:1m;
#        ssl_session_timeout  10m;
#        ssl_ciphers HIGH:!aNULL:!MD5;
#        ssl_prefer_server_ciphers on;
#
#        # Load configuration files for the default server block.
#        include /etc/nginx/default.d/*.conf;
#
#        location / {
#        }
#
#        error_page 404 /404.html;
#            location = /40x.html {
#        }
#
#        error_page 500 502 503 504 /50x.html;
#            location = /50x.html {
#        }
#    }
 
}

設定の構成

設定の階層構造

nginx.conf に記述する設定は、以下のような階層構造になっています。

# mainコンテキスト
 
events {
    # eventsコンテキスト
}
 
http {
    # httpコンテキスト
 
    server {
        # serverコンテキスト
        listen       80 default_server;
        server_name  _;
         
        location / {
            # locationコンテキスト
        }
    }
 
    server {
        # serverコンテキスト
        listen       443 ssl http2 default_server;
        server_name  _;
 
        location / {
            # locationコンテキスト
        }
    }
}
コンテキスト 概要
main Nginx動作全般の設定
events Eventsモジュールの設定(最大コネクションなど)
http HTTP_XXXモジュールの設定(Webサーバとしての設定)
server バーチャルホストの設定
location URIに応じた設定

バーチャルホスト

1台で複数のWebサイトを動作させるためのものです。Nginxでは、1台で1つのWebサイトを動作させるときにもバーチャルホストを利用します。

バーチャルホストを区別するには、2種類の方法があります。

  • 名前ベース
    • ドメイン名で区別
  • IPベース
    • IPやポートで区別

IPベース名前ベース を組み合わせて区別する場合、 IPベース の条件が先に判断されます。

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

serverディレクティブはhttpコンテキスト内にある といった形で言います。

ディレクティブごとに、指定できるコンテキストは決まっています。

https://nginx.org/en/docs/ 内の Modules reference から各ディレクティブが利用できるコンテキストを確認できます。例えば、indexディレクティブは以下のように記述されています。

Syntax: index file ...; 
Default: index index.html;
Context: http, server, location

indexディレクティブhttpコンテキスト serverコンテキスト locationコンテキスト 内で使用できるようです。

ファイル分割

下記のように、バーチャルホストごとに設定ファイルを分割すると管理しやすくなります。

# mainコンテキスト
 
events {
    # eventsコンテキスト
}
 
http {
    # httpコンテキスト
 
    include /etc/nginx/conf.d/*.conf;
}
server {
    # serverコンテキスト
    listen       80 default_server;
    server_name  _;
     
    location / {
        # locationコンテキスト
    }
}
server {
    # serverコンテキスト
    listen       443 ssl http2 default_server;
    server_name  _;
 
    location / {
        # locationコンテキスト
    }
}

変数

設定パラメータとして変数を利用できます。ログを残すときなどに便利です。

変数 概要
$hostname ホスト名
$remote_addr クライアントアドレス
$request_method リクエストHTTPメソッド
$time_local 現在時刻
$uri 正規化済みURI

そのほかの変数は、https://nginx.org/en/docs/varindex.html で確認できます。

単位

設定パラメータとして利用できる単位は、以下の通りです。

サイズ

単位
k キロバイト
m メガバイト

時間

単位
ms ミリ秒
s
m
h
d
w
M
y

主なディレクティブ

基本設定

下記設定ファイルのディレクティブについてみてみます。

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
 
# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
 
events {
    worker_connections 1024;
}
 
http {
    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;
    keepalive_timeout   65;
    server_tokens       off;
 
    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;
     
    charset              utf-8;
    client_max_body_size 32m;
 
    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;
 
    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  _;
        root         /usr/share/nginx/html;
 
        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;
 
        location / {
        }
 
        error_page 404 /404.html;
            location = /40x.html {
        }
 
        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }
}
ディレクティブ 概要 デフォルト コンテキスト
user nginxの実行ユーザを設定。 user nobody nobody; main
worker_processes nginxのworkerプロセスの数を設定。通常はCPUコア数以下。autoにすると自動でコア数を検出し同じ数にする。 worker_processes 1; main
error_log エラーログの出力先を設定。 error_log logs/error.log error; main, http, mail, stream, server, location
pid PIDファイルの出力先を設定。 pid nginx.pid; main
worker_connections 1つのworkerプロセスが同時に処理できる最大コネクション数を設定。 worker_connections 512; events
use コネクションの処理方式を設定。デフォルトでシステムに最適なメソッドを選択するため指定する必要はない。 - events
log_format アクセスログの書式を設定。 log_format combined "..."; http
access_log アクセスログの出力先とログフォーマットを設定。 access_log logs/access.log combined; http, server, location, if in location, limit_except
sendfile ONにするとパフォーマンス向上。vagrantの場合はOFFにしないと不具合が発生する場合がある。 sendfile off; http, server, location, if in location
tcp_nopush ONにするとパフォーマンス向上。sendfileがONである必要あり。 tcp_nopush off; http, server, location
keepalive_timeout タイムアウト時間を設定。 keepalive_timeout 75s; http, server, location
server_tokens nginxバージョン情報の表示設定。 server_tokens on; http, server, location
default_type レスポンスのデフォルトのMIMEタイプを設定。 default_type text/plain; http, server, location
charset デフォルト文字コードを設定。 charset off; http, server, location, if in location
client_max_body_size 受信可能なリクエストボディの最大サイズを設定。デフォルトの1mだと小さいため、ファイルアップロードなどできなくなる可能性あり。 client_max_body_size 1m; http, server, location
listen IPアドレスやポートを設定。 listen *:80 | *:8000; server
server_name ホスト名を設定。 server_name ""; server
root ドキュメントルートを設定。 root html; http, server, location, if in location
error_page レスポンスコードに対応するエラーページを設定。 - http, server, location, if in location

TLS/SSL

下記バーチャルホストの設定では、HTTPでアクセスがきたとき、HTTPSのURLにリダイレクトするようにしています。

server {
    listen       80 default_server;
    return       301 https://$host$request_uri;
}
 
server {
    listen       443 ssl http2 default_server;
    listen       [::]:443 ssl http2 default_server;
    server_name  _;
    root         /usr/share/nginx/html;
 
    ssl_certificate     "/etc/pki/nginx/server.crt";
    ssl_certificate_key "/etc/pki/nginx/private/server.key";
 
    ssl_protocols             TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    ssl_ciphers               ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS;
 
    ssl_session_cache    shared:SSL:10m;
    ssl_session_timeout  10m;
 
    # Load configuration files for the default server block.
    include /etc/nginx/default.d/*.conf;
 
    location / {
    }
 
    error_page 404 /404.html;
        location = /40x.html {
    }
 
    error_page 500 502 503 504 /50x.html;
        location = /50x.html {
    }
}
ディレクティブ 概要 デフォルト コンテキスト
return 処理を停止して、クライアントに返すコードを設定。 - server, location, if
ssl_certificate 証明書のファイルパスを設定。 - http, server
ssl_certificate_key 秘密鍵のファイルパスを設定。 - http, server
ssl_session_cache SSLセッションをキャッシュするか設定。キャッシュすることでサーバ負荷軽減。 ssl_session_cache none; http, server
ssl_session_timeout キャッシュのタイムアウトを設定。 ssl_session_timeout 5m; http, server
ssl_prefer_server_ciphers ONにするとサーバ側が示した暗号化スイートを優先。OFFにするとクライアント優先。 ssl_prefer_server_ciphers off; http, server
ssl_ciphers HTTPSで利用する暗号化スイートのリストを設定。「https://wiki.mozilla.org/Security/Server_Side_TLS」で最新のリストを確認して設定する。 ssl_ciphers HIGH:!aNULL:!MD5; http, server
ssl_protocols HTTPSで利用するプロトコルを設定。 ssl_protocols TLSv1 TLSv1.1 TLSv1.2; http, server

PHP-FPMと連携

PHP-FPMと連携するには、FastCGIプロトコル を利用します。

server {
    listen       80 default_server;
    listen       [::]:80 default_server;
    server_name  _;
    root         /usr/share/nginx/html;
 
    # Load configuration files for the default server block.
    include /etc/nginx/default.d/*.conf;
 
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }
 
    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_index           index.php;
        include fastcgi_params;
        fastcgi_param           SCRIPT_FILENAME $document_root$fastcgi_script_name;
 
        fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
 
        fastcgi_buffer_size     16k;
        fastcgi_buffers         4 16k;
        fastcgi_connect_timeout 75s;
        fastcgi_send_timeout    75s;
        fastcgi_read_timeout    75s;
    }
}

10〜12行目

このバーチャルサーバの設定では、まず、phpファイルが指定されたリクエストは14〜27行目のlocationで処理されます。そのほかのリクエストは10〜12行目で処理されます。

LaravelWordPress では、index.phpが全てのリクエストを受け付けるフロントコントローラとして機能し、ここからコアとなる処理が始まります。そのため、try_files を利用して、ファイルパスが存在しないURIを index.php のパラメータとして渡されるようにしています。

  • 判定順序
    • 1 .phpファイル が指定されたリクエストは14〜27行目で処理。
    • 2 .php以外 のリクエストは10〜12行目で処理。
      • 2-1 存在するファイルパスであればその内容を返す。
      • 2-2 存在しないファイルパスであればリダイレクト。リダイレクト先は /index.php?$query_string

15行目

(.+\.php) の部分が $fastcgi_script_name の値になります。
(/.+) の部分が $fastcgi_path_info の値になります。

20行目

PHP-FPMとの接続方法は2通りあります。

# TCP接続(同一サーバ上でデフォルト設定でPHP-FPMを起動している場合)
fastcgi_pass   127.0.0.1:9000;
 
# UNIXドメインソケットによる接続
fastcgi_pass   unix:/var/run/php-fpm/php-fpm.sock;

UNIXドメインソケットを利用する方が、TCP接続より負荷が低いです。しかし、NgnixとPHP-FPMが同一サーバ内で起動している時しか利用できません。TCP接続ですと、NginxとPHP-FPMが異なるサーバで起動していても利用できます。

ディレクティブ 概要 デフォルト コンテキスト
fastcgi_split_path_info リクエストURIを分割して、$fastcgi_script_nameと$fastcgi_path_infoに値を設定するための正規表現を設定。 - location
fastcgi_index $fastcgi_script_nameの値を設定。 - http, server, location
fastcgi_param リクエストに付与するパラメータを設定。 - http, server, location
fastcgi_pass 転送先を設定。 - location, if in location
fastcgi_buffer_size FastCGIの応答の最初の部分を読み取るために使用されるバッファサイズを設定。 fastcgi_buffer_size 4k|8k; http, server, location
fastcgi_buffers FastCGIの応答を読み取るために使用されるバッファ数とサイズを設定。 fastcgi_buffers 8 4k|8k; http, server, location
fastcgi_connect_timeout FastCGIと接続を確立するためのタイムアウトを設定。 fastcgi_connect_timeout 60s; http, server, location
fastcgi_send_timeout FastCGIに要求を送信するためのタイムアウトを設定。 fastcgi_send_timeout 60s; http, server, location
fastcgi_read_timeout FastCGIからの応答を受信するためのタイムアウトを設定。 fastcgi_read_timeout 60s; http, server, location
try_files 指定したファイルパスが存在しない場合、最後に指定したURIにリダイレクトする。 - server, location