Nginxインストール

Nginxインストール
===============

#### ユーザ作成

uid/gidは適当。

```shell-session
groupadd -g 2001 nginx
useradd -u 2001 -g nginx -s `which nologin` -d /usr/local/nginx nginx
```

#### 必要なパッケージのインストール

CentOSの場合は`wget clang gcc make pcre pcre-devel zlib zlib-devel openssl-devel`あたりを入れておく。

```shell-session
apt-get update
apt-get -y install clang-3.8 gcc make libpcre3 libpcre3-dev libssl-dev zlib1g zlib1g-dev
```

#### ソースダウンロード

```shell-session
cd /usr/local/src
wget -c https://nginx.org/download/nginx-1.11.13.tar.gz
```

#### インストール

```shell-session
tar zxvf nginx-1.11.13.tar.gz
cd nginx-1.11.13
./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_gzip_static_module --with-http_stub_status_module
make && make install
```

#### ディレクトリ作成

vhostsと設定ファイル用のディレクトリを作成しておく。

```shell-session
mkdir /usr/local/nginx/conf/conf.d
mkdir /usr/local/nginx/vhosts
```

#### 設定ファイル

```shell-session
mv -i /usr/local/nginx/conf/nginx.conf{,.`date +%Y%m%d`}
vi /usr/local/nginx/conf/nginx.conf
```

デフォルトのindex.htmlが見たい場合はコメントアウトしている部分をアンコメントする。

```nginx:/usr/local/nginx/conf/nginx.conf
user nginx nginx;

worker_processes auto;
worker_rlimit_nofile 8192;

error_log logs/error.log notice;
pid logs/nginx.pid;

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

http {
    include       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"';
    log_format ltsv "time:$time_iso8601"
                    "\thost:$remote_addr"
                    "\txff:$http_x_forwarded_for"
                    "\tmethod:$request_method"
                    "\tpath:$request_uri"
                    "\tstatus:$status"
                    "\tua:$http_user_agent"
                    "\treq_size:$request_length"
                    "\treq_time:$request_time"
                    "\tres_size:$bytes_sent"
                    "\tbody_size:$body_bytes_sent"
                    "\tapp_time:$upstream_response_time";

    sendfile on;
    tcp_nopush on;
    gzip on;
    server_tokens off;
    keepalive_timeout 10;
    index index.html index.htm;
    error_page 500 502 503 504 /50x.html;

    open_file_cache max=1000 inactive=20s;
    open_file_cache_valid 60s;
    open_file_cache_min_uses 1;
    open_file_cache_errors on;

    #server {
    #    listen 80 default;
    #    server_name _;
    #    root html;
    #    access_log logs/access.log ltsv;

    #    location = /nginx_status {
    #        stub_status on;
    #        access_log off;
    #        allow 127.0.0.1;
    #        deny all;
    #    }
    #}

    include conf.d/*.conf;
}
```

#### 起動スクリプト

```
touch /etc/init.d/nginx
chmod 755 /etc/init.d/nginx
vi /etc/init.d/nginx
```

```bash:/etc/init.d/nginx
#!/bin/bash
 
# Nginx start stop script
#
# Debian
### BEGIN INIT INFO
# Provides:          nginx
# Required-Start:    $all
# Required-Stop:     $all
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: start and stop Nginx daemon
# Description:       start and stop Nginx daemon
### END INIT INFO
#
# CentOS
# chkconfig: 345 99 1
# description: Nginx start stop script
# processname: nginx
 
SERVER_ROOT=/usr/local/nginx
NGINX=$SERVER_ROOT/sbin/nginx
PIDFILE=$SERVER_ROOT/logs/nginx.pid
 
[ -x $NGINX ] || exit 1
 
if ! $NGINX -t > /dev/null 2>&1 ; then
    echo "Syntax error! Please confirm the config file."
    exit 1
fi
 
do_start() {
    if [ -f $PIDFILE ] ; then
        if ps -p `cat $PIDFILE` > /dev/null 2>&1 ; then
            echo "Nginx is already running..."
            exit 1
        fi
    fi
    $NGINX || echo "Failed to start Nginx."
}
 
do_stop() {
    if [ ! -f $PIDFILE ] ; then
        echo "Nginx is not running."
        exit 1
    fi
    if ps -p `cat $PIDFILE` > /dev/null 2>&1 ; then
        kill -QUIT `cat $PIDFILE` || echo "Failed to stop Nginx."
    else
        echo "Nginx is not running."
        exit 1
    fi
}
 
do_graceful() {
    if [ ! -f $PIDFILE ] ; then
        echo "Nginx is not running."
        exit 1
    fi
    if ps -p `cat $PIDFILE` > /dev/null 2>&1 ; then
        kill -HUP `cat $PIDFILE` || echo "Failed to graceful Nginx."
    else
        echo "Nginx is not running."
        exit 1
    fi
}
 
case $1 in
    start)
        do_start;;
    stop)
        do_stop;;
    restart)
        do_stop
        sleep 2
        do_start;;
    graceful)
        do_graceful;;
    *)
        echo "Usage: nginx [start|stop|restart|graceful]"
        exit 1;;
esac
 
exit 0
```

#### vhosts作成

ssl.crt/ssl.keyはhttps利用時のみ。

```shell-session
mkdir -p /usr/local/nginx/vhosts/example.com/{html,logs,ssl.crt,ssl.key}
vi /usr/local/nginx/conf/conf.d/example.com.conf
```

自己署名証明書を利用する場合は`ssl_certificate`に指定するファイル名を`server.crt`にしておく。

```nginx:/usr/local/nginx/conf/conf.d/example.com.conf
server {
  listen 80;
  server_name example.com;
  root /usr/local/nginx/vhosts/example.com/html;

  access_log /usr/local/nginx/vhosts/example.com/logs/access.log ltsv;
  error_log /usr/local/nginx/vhosts/example.com/logs/error.log info;

  location / {
    try_files $uri @proxy;
  }

  location @proxy {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto https;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    proxy_pass http://backend-unicorn;
  }
}

server {
  listen 443 ssl;
  server_name example.com;
  root /usr/local/nginx/vhosts/example.com/html;

  access_log /usr/local/nginx/vhosts/example.com/logs/ssl_access.log ltsv;
  error_log /usr/local/nginx/vhosts/example.com/logs/ssl_error.log info;

  ssl_certificate /usr/local/nginx/vhosts/example.com/ssl.crt/server.crt;
  ssl_certificate_key /usr/local/nginx/vhosts/example.com/ssl.key/server.key;

  ssl_session_timeout 1d;
  #ssl_session_cache shared:SSL:50m;
  #ssl_session_tickets off;

  #ssl_dhparam /path/to/dhparam.pem;

  ssl_protocols TLSv1.2;
  ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
  ssl_prefer_server_ciphers on;
}
```

自己署名証明書の作成(必要な場合のみ)。

```shell-session
openssl genrsa -des3 -out server.key 1024
openssl rsa -in server.key -out server.key
openssl req -new -x509 -out server.crt -key server.key -days 365
```

証明書の配置。

```shell-session
mv server.crt /usr/local/nginx/vhosts/example.com/ssl.crt/.
mv server.key /usr/local/nginx/vhosts/example.com/ssl.key/.
```

起動

```shell-session
/usr/local/nginx/sbin/nginx -t
/etc/init.d/nginx start
```

※このままアクセスしてもindex.html作っていないので403

#### Rails/Unicornのvhosts.confサンプル

```nginx:/usr/local/nginx/conf/conf.d/example.com.conf
upstream backend-unicorn {
  server unix:/usr/local/rails/example/tmp/unicorn.sock;
}

server {
  listen 80;
  server_name example.com;
  access_log /usr/local/nginx/vhosts/example.com/logs/access.log ltsv;
  error_log /usr/local/nginx/vhosts/example.com/logs/error.log info;

  rewrite ^(.*) https://example.com$1 permanent;
}

server {
  listen 443 ssl;
  server_name example.com;
  root /usr/local/rails/example.com/public;
  index index.html index.htm;
  access_log /usr/local/nginx/vhosts/example.com/logs/ssl_access.log ltsv;
  error_log /usr/local/nginx/vhosts/example.com/logs/ssl_error.log info;

  ssl on;
  ssl_certificate /usr/local/nginx/vhosts/example.com/ssl.crt/server.crt;
  ssl_certificate_key /usr/local/nginx/vhosts/example.com/ssl.key/server.key;
  ssl_session_timeout 5m;
  ssl_protocols SSLv2 SSLv3 TLSv1;
  ssl_ciphers HIGH:!aNULL:!MD5;
  ssl_prefer_server_ciphers on;

  location / {
    try_files $uri @proxy;
  }

  location @proxy {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_set_header X-Forwarded-Proto https;
    proxy_redirect off;
    proxy_pass http://backend-unicorn;
  }
}
```