Nginx 1.6 にバージョンアップしてやったことまとめ


## Nginxを1.4.7から1.6にバージョンアップした際にやったこと
2014/04/24にNginx 1.6 がリリースされたので、Buildしてインストールした。
SPDY, PageSpeed(ngx_pagespeed)の導入、既存設定の見直し、Configure/Buildのメモ


## 環境

- Nginx 1.6.0
- AWS Amazon Linux


## SPDY

Googleが開発しているHTTP/1.xに変わる新しいプロトコル。HTTP/2のドラフトになっている。読み方はSPDY(スピーディ)。

[httpbis interim@チューリッヒ レポート](http://www.slideshare.net/shigeki_ohtsu/http2study3)

対応ブラウザはChrome, Firefox, Opera, IE 11など。
ちょうど本日のWWDC 2014で、OS X 10.10のSafariからSPDY対応が発表された。

### 設定

Nginx 1.6からSPDY 3.1に対応。
OpenSSLのバージョン1.0.1がインストールされていて通常のSSL設定をしていれば、listenに設定を追加するだけ。

```
server {
  listen 443 ssl spdy default_server;
...
}
```

### 対応ブラウザ

2014/06/03現在

- Google Chrome 10以降
- Firefox 11以降、SPDY3.1は27より対応
- Opera 12.10以降
- Internet Explorer 11にてSPDY 3（ただしWindows 8.1のみ。Windows7では未対応）
- Safari OS X 10.10でSPDY対応 new!

ブラウザが未対応の場合でも、SPDYを使わない通信を行う。

### 確認

Chrome extention のSPDY indicatorで確認する。
SPDY対応サイトだと、URLバーの右端に緑の稲妻が表示される。

![Screen Shot 2014-06-03 at 6.42.33 AM.png](https://qiita-image-store.s3.amazonaws.com/0/32750/cd6dd811-d060-3901-4f2d-5cd26935e60a.png "Screen Shot 2014-06-03 at 6.42.33 AM.png")


### SPDYについて調べたメモ

>Chromeでワイルドカード証明書でSPDYを利用していると、DNSレコード情報が一致しているサイトへのSPDYセッションは1つにまとめられるのです。

画像ファイルを外部CDNサービスにおいているサイトではあまり効果がないのかな。

[FacebookがSPDYを始めました！ - ぼちぼち日記](http://d.hatena.ne.jp/jovi0608/20130123/1358895995)


### 参考サイト

SPDYについて勉強になるブログ。
[SPDYとLinuxの間でGoogleマップがハマった落とし穴 - ぼちぼち日記](http://d.hatena.ne.jp/jovi0608/20140207/1391732796)


## ngx_pagespeed

ngx_pagespeedは、HTMLのレンダリングを高速化するためのフィルタを提供するモジュール。Googleが開発している。フィルタは何種類か用意されている。
例: 空白を削除するフィルタ、コメントを削除するフィルタなど

### 設定

Githubからモジュールをダウンロードして、configureで追加してNginxをビルドする。

https://github.com/pagespeed/ngx_pagespeed

手順はREADMEに書いてあるので、その通りに実行。

```
cd /opt/nginx-modules
wget https://github.com/pagespeed/ngx_pagespeed/archive/v1.8.31.2-beta.zip
unzip v1.8.31.2-beta.zip
cd ngx_pagespeed-1.8.31.2-beta/
wget https://dl.google.com/dl/page-speed/psol/1.8.31.2.tar.gz
tar -xzvf 1.8.31.2.tar.gz

cd /opt/nginx-1.6.0
./configure --prefix=/opt/nginx \
...
--add-module=/opt/nginx-modules/ngx_pagespeed-1.8.31.2-beta
```

設定ファイル

```
server {
    listen       443 ssl spdy default_server;
    server_name  kitchhike.com;
...
    pagespeed on;
    pagespeed RewriteLevel CoreFilters;
    pagespeed FileCachePath /var/cache/ngx_pagespeed_cache;
    pagespeed EnableFilterscollapse_whitespace,trim_urls,remove_comments;
}
```


### 確認

PageSpeedが有効になっていればレスポンスヘッダーにX-Page-Speed
が追加されている。

```
$ curl -I https://kitchhike.com | grep X-Page-Speed
X-Page-Speed: 1.8.31.2-3973
```

### 参考サイト

[Nginx + PageSpeed(ngx_pagespeed)を導入して WEBサイトを高速化する方法 | ブログ | 株式会社イー・エージェンシー](http://www.e-agency.co.jp/column/20130621.html)


## SSLの設定を見直す


- 暗号化スイートの整理
- OCSP Staplingの追加
- ssl_prefer_server_ciphersをon
- ssl_session_ticket_keyを追加
- ssl_session_cacheを追加

```
ssl on;
ssl_certificate     /etc/nginx/ssl/ssl.pem;
ssl_certificate_key /etc/nginx/ssl/ssl.key;
ssl_prefer_server_ciphers on;
ssl_protocols  SSLv3 TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:AES128:AES256:RC4-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK';
ssl_dhparam /etc/nginx/ssl/dhparam.pem;
ssl_session_tickets on;
ssl_session_ticket_key /etc/nginx/ssl/ticket.key;
ssl_session_cache    shared:SSL:10m;
ssl_session_timeout  10m;

resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
ssl_stapling on;
ssl_trusted_certificate /etc/nginx/ssl/ssl.pem;
```

### 確認

ChromeからはTLS 1.2接続と暗号化スイートを確認できる。

![Screen Shot 2014-06-03 at 11.05.28 AM.png](https://qiita-image-store.s3.amazonaws.com/0/32750/d8e83f3c-a825-149a-7c3a-de669cb978ab.png "Screen Shot 2014-06-03 at 11.05.28 AM.png")

### 外部サービスで確認

SSL Labsでチェック
[Qualys SSL Labs - Projects / SSL Server Test](https://www.ssllabs.com/ssltest/)

![kobito.1401762410.810913.png](https://qiita-image-store.s3.amazonaws.com/0/32750/75353cba-6531-82ff-0ffa-9ebd6d8a598a.png "kobito.1401762410.810913.png")


### 参考サイト
[nginx - 我々はどのようにして安全なHTTPS通信を提供すれば良いか - Qiita](http://qiita.com/harukasan/items/fe37f3bab8a5ca3f4f92)


## rewriteの修正

httpをhttpsへリダイレクトさせるための設定。
1.4.7まで、

```
rewrite ^(.*) https://$http_host$1;
```

と書いていたが、この書き方だと1.6ではrewriteが効かなくなっていた。下記のように修正。


```
server {
    listen       80;
    server_name  kitchhike.com;
    location / {
      # rewrite ^(.*) https://$http_host$1;    ## 修正前
      rewrite ^ https://$host$request_uri permanent; ## 修正後
      break;
    }
```


## Vary: User-Agentを追加

PC向けとスマホ向けで表示を分けている場合は、Varyを追加することがGoogleの推奨とのこと。

### 設定

```
location / {
    add_header Vary 'User-Agent';
...
}
```

### 確認

```
$ curl -I https://kitchhike.com | grep Vary
Vary: Accept-Encoding
Vary: User-Agent
```

Varyヘッダが重複していたら問題があるかどうか簡単に調べたところ、上手く足してくれるか、上書きされるらしい。

### 参考サイト

[スマホ向け表示を分けているときはVary HTTPヘッダーを使うこと など10+4記事（海外&国内SEO情報） | Web担当者Forum](http://web-tan.forum.impressrd.jp/e/2013/05/17/15269)


## レスポンスをGzip圧縮する

### 設定

```
server {
...
  gzip on;
  gzip_min_length  1100;
  gzip_buffers  4 32k;
  gzip_types   text/plain text/xml text/css text/javascript application/x-javascript application/xhtml+xml application/xml; 
  gzip_vary on;
  gzip_proxied any;
}
```

### 確認

curlのオプションでリクエストヘッダに"accept-encoding: gzip"を追加して確認。

```
$ curl -IL -H "accept-encoding: gzip" https://kitchhike.com/ |grep Content-Encoding
Content-Encoding: gzip
```

## キャッシュするコンテンツにはETagをつけない

HTTPステータスコードが200で返るようになる。
ETagがあると304が返る。
Rails Guidesを参考に変更。

```
location ~ ^/static_images/ {
    ...
    expires    1y;
    add_header Cache-Control public;
    etag off;
    #もしくは add_header ETag "";
}
```

### 確認

curlでヘッダーにETagが無いことを確認する。

### 参考

http://guides.rubyonrails.org/asset_pipeline.html#precompiling-assets


## バージョンを非表示に

```
server_tokens off;
```

### 確認

```
$ curl -I https://kitchhike.com | grep Server
Server: nginx
```

## Build

### Build準備

```
# yum install -y gcc-c++ pcre-dev pcre-devel zlib-devel openssl openssl-devel make gd-devel
# cd /opt
# wget http://nginx.org/download/nginx-1.6.0.tar.gz
# tar zxfv nginx-1.6.0.tar.gz
```

### configure

```
# cd nginx-1.6.0
# ./configure --prefix=/opt/nginx-1.6.0 \
--sbin-path=/opt/nginx-1.6.0/usr/sbin/nginx \
--conf-path=/opt/nginx-1.6.0/etc/nginx/nginx.conf \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--http-client-body-temp-path=/var/lib/nginx/tmp/client_body \
--http-proxy-temp-path=/var/lib/nginx/tmp/proxy \
--http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi \
--http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi \
--http-scgi-temp-path=/var/lib/nginx/tmp/scgi \
--pid-path=/var/run/nginx.pid \
--lock-path=/var/lock/subsys/nginx \
--user=nginx \
--group=nginx \
--with-file-aio \
--with-http_ssl_module \
--with-http_spdy_module \
--with-http_realip_module \
--with-http_addition_module \
--with-http_xslt_module \
--with-http_image_filter_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 \
--with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic' \
--with-ld-opt=' -Wl,-E' \
--add-module=/opt/nginx-modules/ngx_pagespeed-1.8.31.2-beta

# make
```

<code>nginx-1.6.0/objs/nginx</code>が作成される。

## アップグレード

バイナリファイルを入れ替えるだけで大丈夫だった。

新しいバイナリファイルで設定ファイルの確認

```
# /opt/nginx-1.6.0/objs/nginx -t -c /etc/nginx/nginx.conf
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
```

バイナリファイルの入れ替え

```
# cp /usr/sbin/nginx /usr/sbin/nginx_147 ## Nginx 1.4.7を退避
# cp /opt/nginx-1.6.0/objs/nginx /usr/sbin/nginx

```