Edit
nginxとは。

nginxはロシアのIgor Sysoev氏によって開発されているHTTPサーバ兼リバースProxyのソフトウェアであり、「エンジン エックス」(engine x)と発音する。apacheと違い、リクエストに対してスレッドを起動しない為、メモリやCPUのオーバーヘッドが極力まで抑えられており、大量のリクエストを幅くことができる。反面、1つのリクエストが無限ループに入ると、システム全体が停止する。そのため、主にサーバー群のフロントサーバーとして、リバースプロキシ+静的コンテンツのhttpサーバー(画像や静的なページなど)として利用するのが適切である。(要するに確実に停止しない処理で膨大なリクエストを捌く必要があるものを担当させる) 公式ページ

Edit
導入

Edit
インストール

Edit
必要とするモジュール

下記のライブラリが必要となるため、先にインストールしておく必要がある。

  1. PCREライブラリ
  2. OpenSSL(SSLを利用する場合)

Edit
ソースからのインストール手順

<初期準備>

# yum install pcre-devel zlib-devel expat-devel

<dav extを利用する場合>

# cd /usr/local/src
# git clone https://github.com/arut/nginx-dav-ext-module

※但し、nginx ではWebDavとしての機能は十分でなく参照のみ機能

<Luaを利用する場合>

# cd /usr/local/src
# git clone https://github.com/openresty/lua-nginx-module

<安定版>※オプションで不必要なものは外してください。

# wget http://nginx.org/download/nginx-1.12.2.tar.gz
# tar zxvf nginx-1.12.2.tar.gz
# cd nginx-1.12.2
# ./configure 
              --with-http_ssl_module 
              --with-openssl=/usr/local/src/openssl-1.0.2n
              --with-http_gzip_static_module
              --with-http_stub_status_module 
              --with-http_dav_module
              --with-http_v2_module
              --with-http_realip_module
              --with-http_gzip_static_module
              --with-http_stub_status_module
              --with-http_addition_module
              --with-cc-opt=-Wno-error
              --with-ld-opt=
              --add-module=/usr/local/lib/ruby/gems/2.4.0/gems/passenger-5.1.11/src/nginx_module
              --add-module=/usr/local/src/nginx-dav-ext-module
              --add-module=/usr/local/src/lua-nginx-module
# make
# make install

※1.5.10からは、Googleが提唱するHTTP速度向上プロトコルSPDYに対応している。
※opensslのパス指定はインストールフォルダではなく、ソースフォルダを指定する。
※ほかのオプションはここが参考になる。

<Passenger付き>

# gem install passenger
# passenger-install-nginx-module          <- configureはここで行われるため下の行は参考
# ./configure --prefix='/usr/local/nginx'
                    --with-http_ssl_module
                    --with-http_v2_module
                    --with-http_realip_module
                    --with-http_gzip_static_module
                    --with-http_stub_status_module
                    --with-http_addition_module
                    --with-cc-opt=-Wno-error
                    --with-ld-opt='' --add-module='/usr/local/lib/ruby/gems/2.2.0/gems/passenger-5.1.3/src/nginx_module

Edit
nginx cache purgeをモジュールとして追加

nginxのキャッシュクリア方法には、「時間経過による削除」と「全削除」の2種類しかないため、キャッシュクリアのモジュールを追加するため以下もインストールする。

# cd <nginxのフォルダ>
# mkdir srclib
# cd srclib
# wget http://labs.frickle.com/files/ngx_cache_purge-2.1.tar.gz
# tar zxvf ngx_cache_purge-2.1.tar.gz
# ./configure --with-http_ssl_module --add-module=srclib/ngx_cache_purge-2.1

Edit
ngx_pagespeedをモジュール

pagespeedは元は apache用でgoogleによって作られたものであるが、現在 nginx用にも存在する。機能としては以下のとおり。(詳細は公式サイトを参照のこと)

※インストールは、公式サイトから git や zip でダウンロードし、ngx_cache_purgeと同じ方法でモジュール追加する。
設定のサンプルページ

Edit
stub_statusモジュール

nginxの現在の接続数などを表示するモジュール。nginx をコンパイルする時に指定。

--with-http_stub_status_module

nginx.conf 内では、locationディレクティブで指定

location /status {
    stub_status on;
}

これによって該当ページに接続情報が表示される。

Active connections: 1                                         <- 現在の接続数
server accepts handled requests
 5 5 4                                                                   <- 受け付けた接続総数, 制御した接続総数, 制御した要求総数
Reading: 0 Writing: 1 Waiting: 0                           <- リクエストヘッダー読込中, リクエストボディの処理中, keep-alive接続数

Edit
その他のモジュール

オプション名(例付き)概要
--user=nginxプロセスのユーザーを指定
--group=nginxプロセスのグループを指定
--with-http_ssl_moduleSSLモジュールを追加
--with-http_realip_module
--with-http_addition_module
--with-http_xslt_module
--with-http_image_filter_module
--with-http_geoip_module
--with-http_sub_module
--with-http_dav_module
--with-http_flv_module
--with-http_mp4_module
--with-http_gzip_static_module
--with-http_random_index_module
--with-http_secure_link_module
--with-http_degradation_module
--with-http_stub_status_module
--prefix=/usr/local/nginxnginxのインストール先を指定する
--sbin-path=bin/nginx実行ファイルのインストール先を指定する
--conf-path=conf/nginx.conf設定ファイルの指定をする
--error-log-path=log/error.logエラーログの指定をする
--pid-path=/var/run/nginx.pidpidファイルの指定をする
--lock-path=/var/lock/subsys/nginxロックファイルの指定をする
--http-log-path=log/access.logアクセスログのファイルを指定する
--add-module=srclib/ngx_cache_purge-2.1指定のフォルダから追加モジュールをconfigureする

Edit
stickey ディレクティブの追加

stickeyディレクティブは、upstream モジュールによって、接続サーバーに複数のサーバーを指定し、ロードバランシングを行う際に、ステートフルな websocket 接続などの場合に、cookieを利用して自動的に同一接続であることを判定し、同じのサーバーに再接続させるためのものである。

現状、このディレクティブは追加モジュールとなっているので下記の手順で追加が必要となる。(下記操作は nginx のソースフォルダ内で実行)

# mkdir modules
# cd modules
# wget https://bitbucket.org/nginx-goodies/nginx-sticky-module-ng/get/f2adff04b8e3.zip
# unzip f2adff04b8e3.zip
# mv nginx-goodies-nginx-sticky-module-ng-f2adff04b8e3 sticky
# rm -f f2adff04b8e3.zip

これでモジュール追加の準備ができたので、configure のオプションに下記を追加する。

--add-module=./modules/sticky

stickeyモジュールの公式ページ

Edit
Luaモジュール

解説ページ1
公式ソースページ

# mkdir modules
# cd modules
# wget https://github.com/openresty/lua-nginx-module/archive/master.zip
# unzip master.zip
# rm -f master.zip
# mv lua-nginx-module-master lua

これでモジュール追加の準備ができたので、configure のオプションに下記を追加する。

--add-module=./modules/lua

※Luaは、LuaJIT2.0.3がおすすめ。また so ファイルのライブラリパスを /etc/ld.so.conf.d/に設置して、ldconfig を実行することを忘れないこと。

Edit
Lua-resty-redisモジュール

公式ページ

これは、pure Lua のライブラリなので、Lua のライブラリパスに設置すれば利用できます。

Edit
http Redisモジュール。

Redis v.1 の公式ページ
Redis v.2 の公式ページ1 Redis v.2 の公式ページ2

Redis1

# wget http://people.freebsd.org/~osa/ngx_http_redis-0.3.7.tar.gz

Redis2

# wget https://github.com/agentzh/redis2-nginx-module/archive/v0.11.tar.gz

参考例1

参考2

location /redis {
    internal;
    set            $redis_key $host;
    redis_pass     127.0.0.1:6379;
}
location /redis2 {
    internal;
    redis2_query get testkey;
    redis2_pass localhost:6379;
}

※internal をつけると、内部からのみ呼び出し可能となる。

Edit
misc モジュール

但し misc モジュールには、ngx_devel_kit が必要になる。

devel-kit公式ページ misc公式ソースページ

# wget https://github.com/simpl/ngx_devel_kit/archive/v0.2.19.tar.gz
# wget https://github.com/openresty/set-misc-nginx-module/archive/v0.26.tar.gz

Edit
コンパイル時のオプション等の表示

# nginx -V

Edit
定義ファイルの設定

ソースから導入した場合/usr/local/nginx/conf/nginx.conf
パッケージから導入した場合/etc/nginx/nginx.conf

Edit
nginx.confの設定

設定ファイルは、apache に比べてば非常にシンプルとなっている。

参考ページ

Edit
基本設定

設定項目名初期値概要
usernobodynginxが起動されるユーザー名
worker_processes1実際に処理されるworkerの数を指定。通常は cpu の数以下を指定
error_loglogs/error.log noticeエラーログの出力先を指定。例のようにエラーレベル(noticeなど)を指定すれば対象ログ毎にファイルを分けることが可能。(複数行指定可能)
pidlogs/nginx.pidpidを保存するファイルを指定

Edit
イベント設定

events { } で囲われた部分がイベントに関する設定を行う。

設定項目名初期値概要
worker_connections10241つのworkerが接続できるクライアント数の上限を設定する

Edit
httpサーバー設定

http { } (以下、httpブロックと呼ぶ)で囲われた部分がhttpサーバーに関する設定を行う。

設定項目名初期値概要
includemime.types他のファイルを読み込む
default_typeapplication/octet-stream
log_formatmain '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'
access_loglogs/access.log main
sendfileon
tcp_nopushon
keepalive_timeout0
gzipon

Edit
バーチャルサーバーブロック

httpの中で、server{} と、複数のバーチャルサーバーの設定を行うことができる。通常ここは別ファイルにしておくとわかりやすい。

設定項目名初期値概要
listen80
server_namelocalhost
charsetkoi8-r
access_loglogs/host.access.log main
error_page500 502 503 504 /50x.htmlエラーページの設定。エラー番号別に記載可能(複数行指定可能)
sslon【HTTPS用】ssl対応のon/off(SSL時必須)
sslcertificate cert.pem【HTTPS用】証明書ファイルの指定(SSL時必須)
ssl_certificate_keycert.key【HTTPS用】キーファイルの設定(SSL時必須)
ssl_session_timeout5m【HTTPS用】セッションタイムアウトの時間
ssl_protocolsSSLv2 SSLv3 TLSv1【HTTPS用】対応するプロトコルの種類を設定
ssl_ciphersHIGH:!aNULL:!MD5【HTTPS用】暗号化強度
ssl_prefer_server_cipherson【HTTPS用】

※sslのサーバーブロックで指定するサーバー名は、SSLのサーバ証明書で指定したCN(Common Name)と同じサーバ名を指定する事。

またサーバーブロックでは、それぞれの location 設定を下記のような指定で行うことができる。

location / {
    root   html;
    index  index.html index.htm;
}
location = /50x.html {
    root   html;
}
location ~ \.php$ {
    proxy_pass   http://127.0.0.1;
}
location ~ /\.ht {
    deny  all;
}

Edit
sslの設定サンプル

ssl_prefer_server_ciphers  on;
ssl_protocols                      SSLv3 TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers                          AESGCM:RC4:HIGH:!MD5:!aNULL;

Edit
location構文

location構文はサーバーに到着したURIを解析し処理を振り分ける為の構文で、locaton の中に location を記述することもできる。

番号記述例チェック方法処理後概要
1location = /path完全一致終了この場合は、/path と完全合致する場合を意味し、合致した場合、その後の検索も終了するため、例えばルートをよく参照するようなサイトの場合に location = / のように、指定することで他の条件検索が無い分、処理が早くなる
2location ^~ /path前方一致終了これは /path* のような前方一致する場合を意味する。文字列として判断するため、フォルダの区切りも文字として判定される。これも上記と同じで他の検索をせず、その後の検索を行わない
3location /path前方一致継続終了しても他を検索する以外2番と同じ
4location ~ ^/path/(.*\.php)$正規表現継続"~" は大文字・小文字を区別する事を意味する。これが "~*" というようにアスタリスクが付くと、大文字・小文字を区別しないで正規表現での判定を行う

※4番の正規表現解説:^を指定することで行の先頭からチェックを行う宣言をし、/path/ という文字が行の先頭から合致し、「 .* 」 の組み合わせで、改行を除く任意の1文字(ピリオド)を、0回以上の繰り返し(アスタリスク)チェック。その後ろに エスケープにピリオド 「 \. 」 でピリオドの文字として認識したうえで、php と文字をいれているので、要するに「 .php 」という拡張子を指定しており、最後のドルマークが行の最後であることから、「 .php 」で最後終わる文字列であることが指定されている。また丸括弧で囲った/path/以降の文字列と拡張子の部分は、後で $1 として参照できる。

例:http://www.mydomain.com/path/login_form/passcheck/key_check.php

上記4番とこの例は合致し、下記の変数に値が入る

Edit
nginxでの正規表現

ここではよく利用させる規則のみ説明する。注意:~ マークの行は正規表現扱いとなるため、ピリオドなどは振る舞いが下記の形にかわる。

記号役割
^行の先頭を意味する。通常 http://server.name.com の部分は含まれないためドキュメント先頭の / から始まる事を意味させることになる。
$行の終端を意味する。
.ピリオド。改行を除く任意の1文字(漢字も含む)を意味する。よって拡張子などに使われる文字としてピリオドを使いたい場合は、\. のようにエスケープ記号をピリオドの前にいれ、文字であることを認識させる必要がある
( )丸括弧。パターン合致結果の変数化。クラスと違い、文字ごとに判定されるのではなく、文字列全体とマッチ判定する。また合致した文字列は、後方で $1 として参照できる。(括弧が複数あれば、$2, $3 と参照できる
[ ]角括弧。キャラクタのクラス化。例、[0-9] これは数字列の場合に合致する。[^0-9] この場合は、数字列以外を指す。
縦棒(本当は半角)。論理和を意味する。よく利用されるのは gif|png|jpg のように、拡張子判定をする場合に使われる
*アスタリスク。直前のパターンの0回以上の繰り返し。注意するべきは0回以上であるということ。
+プラス。直前のパターンの1回以上の繰り返し。アスタリスクと違い1文字は存在しないと合致しない。
?クエスチョン。直前のパターンが0回または1回現われる

Edit
upstream設定

upstreamは、リバースプロキシーやロードバランサなどに利用するサーバーセットを記述するディレクティブであり、upstream 名を、location ディレクティブの中の、 proxy_pass に指定することで作動する。基本は、httpブロックの中に以下のように設定する。公式解説

upstream load_balancer {                          <- upstream 名はなんでもOK。
     ip_hash;                                              <- IPをhashして、接続元IPが同じ場合、接続するサーバーを同じにする。
     least_conn;                                          <- 一番少ない接続サーバーへの接続優先
     server 127.0.0.3:8000 down;
     server 127.0.0.3:8001 weight=5;          <- weight は複数サーバーの時のバランス確率。
     server 192.168.0.1:8000 max_fails=3  fail_timeout=30s;
     server 192.168.0.1:8001 backup;
}
server {
     listen                80;
     server_name     big.server.com;
     access_log       logs/access.log;
     location / {
       proxy_pass      http://load_balancer;
     }
}
serverオプション概要
weight=5 (初期値=1)全サーバーのweight値の合計を分母(但しbackupサーバは除く)にし、ここで分子を指定することで、この比率がサーバー群の中の対応サーバーの分散比率とする
max_fails=3接続失敗時の最大チャレンジ回数
fail_timeout=30s接続失敗を判断するタイムアウト時間。 但し proxy_connect_timeout と proxy_read_timeout によっても関係する。
down常にダウンしているサーバーに指定。但しip_hash指定があればハッシュは作成される
backupbackup指定がない通常サーバーがすべてダウンした時にこのサーバーに接続する

Edit
rewrite構文

rewtite文はよく使われると思うが、正規表現の関係で意味不明な文になりやすく、説明もすでに正規表現を理解している前提が多いのでここでは簡単にわかるように説明したい。

例) rewrite ^$ http://$host/chnge/$1;

Edit
initスクリプト

サンプルサイト

Edit
PHPの利用

nginxでは、apacheでいう、mod_php のようなものが存在しません。そのためphpの展開処理は、php-fpm というプロセスを起動し、nginx側からはポートを利用してアクセスする形になります。そのため、php の処理部分だけを、他のサーバーに処理させることも容易です。

Edit
pnp-fpm のインストール

# yum install php-fpm
# chkconfig php-fpm on

※phpをソースからインストールする場合は、configur 設定で、php-fpm を enable にすると一緒にインストールされる。

Edit
php-fpm の設定

修正箇所の例(すでに初期値が設定されているので設定の必要はないが参考までに)

# vi /etc/php-fpm.d/www.conf
  user = nginx
  group = nginx
  pm.max_children = 5
  pm.start_servers = 1
  pm.min_spare_servers = 1
  pm.max_spare_servers = 2
  pm.max_requests = 200

※php-fpmの標準ポートは9000番です。また最初は127.0.0.1 (自分)にだけ、アクセス許可されています。

Edit
nginx側の設定

nginx.conf のサーバー設定の中に、以下のlocationディレクティブを追加する。

Edit
ポートによる接続

 location ~ \.php$ {
      root           /usr/local/nginx/html;
      fastcgi_pass   127.0.0.1:9000;
      fastcgi_index  index.php;
      fastcgi_param  SCRIPT_FILENAME  $request_filename;
      include        fastcgi_params;
   }

※またサーバ設定の index 設定にも、index.php を追加しておくこと。

Edit
socketによる接続。

 location ~ \.php$ {
      root           /usr/local/nginx/html;
      fastcgipass    unix:/var/run/php-fpm/www.sock;
      fastcgi_index  index.php;
      fastcgi_param  SCRIPT_FILENAME  $request_filename;
      include        fastcgi_params;
   }

また /etc/php-fm.conf もそれに合わせて修正する。

; listen = 127.0.0.1:9000
listen = /var/run/php-fpm/www.sock

Edit
php-fpmの起動

yumで、php-fpmをインストールしている場合は、servceコマンドで起動できる。

# service php-fpm start

その後、nginxも再起動させる。

# service nginx restart

Edit
nginxの起動

再起動

# nginx -s reload

Edit
nginx.confの文法チェック

# nginx -t -c ./nginx.conf

Edit
nginx のセキュリティ設定

なぜか location ディレクティブ内でしか認識されない。バグ?

設定意味
server_tokens off;nginxのバージョンを表示させない。
etag off;エンティティタグを利用しない。
add_header X-Frame-Options SAMEORIGIN;クリックジャッキング対応として、自身と生成元が同じフレーム内に限りページを表示する設定
add_header X-XSS-Protection "1; mode=block";クロスサイトスクリプティング(XSS)に対するフィルタ機能を強制的に有効
add_header X-Content-Type-Options nosniff;X-Content-Type-Options レスポンスヘッダーの値に nosniff を設定して送信すると、Internet Explorer が MIME Sniffing 機能で content-type 宣言を回避するのを防止
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://ssl.google-analytics.com; img-src 'self' https://ssl.google-analytics.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; object-src 'none'";Content Security Policy (CSP) は、クロスサイトスクリプティング (XSS) やデータインジェクション攻撃を含む、よく知られた種類の攻撃を検出して軽減。左記は特定サイトは除外
add_header Strict-Transport-Security 'strict-transport-security: max-age=31536000; includeSubDomains';SSL利用を推奨

※autoindex off;は初期値だが、むやみに on にしない。

Edit
ヘッダーチェックのサイト

Edit
plugins

Edit
Tips&トラブルシューティング

Edit
Request Entity Too Largeというエラーが表示される。

nginxの通信 body サイズの初期値が1MB であるため、ファイル転送などで これを超えるファイルサイズを転送しようとすると発生する。

# vi nginx.conf
 server {
     client_max_body_size 20M;
 }

上記のようにサーバーディレクティブにbodyサイズの上限を変更する。

Edit
リンク切れをチェックする。

Edit
参考リンク

nginx連載3回目: nginxの設定