nginx
CentOS
SSL
http2
letsencrypt

NginxをHTTP/2対応にする話

More than 1 year has passed since last update.


NginxをHTTP/2対応にした話

ここの方法でHTTP/2に対応させるとFirefox 47系ではうまく表示されないという不具合が生じた.

修正案はこちら


環境


  • さくらVPS


  • ここここの初期設定が終わってる状態.

  • CentOS 6.7

  • Nginx 1.9.12


現状のnginx.conf


nginx.conf

~省略~

server {
listen 80;
server_name www.{自分の契約しているドメイン};
location / {
root /var/www; #公開したいドキュメントのルート
index index.html;
}
~省略~
}
~省略~


TLSに対応させる


証明書を取得する

Let's Encryptを使って無料で証明書を取得する.

ホームディレクトリで

$ cd /usr/local/

$ git clone https://github.com/letsencrypt/letsencrypt
$ cd letsencrypt
$ ./letsencrypt-auto --help
$ ./letsencrypt-auto certonly --webroot -d www.{自分の契約しているドメイン} --webroot-path {公開したいドキュメントのルートここでは/var/www}

するとEnter email addressという画面が表示されるので、メールアドレスを入力.

筆者はwhoisで登録されてるアドレスにしました.

Agree を選択.

うまくいくとこんな感じの表示が出る

IMPORTANT NOTES:

- Congratulations! Your certificate and chain have been saved at
/etc/letsencrypt/live/itochan.jp/fullchain.pem. Your cert
will expire on 2016-03-08. To obtain a new version of the
certificate in the future, simply run Lets Encrypt again.
- If like Lets Encrypt, please consider supporting our work by:

Donating to ISRG / Lets Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le


証明書取得を自動化する

Let's encryptは証明書の期限が3ヶ月と短いので,自動更新する.

$ su -

$ crontab -e

以下を記載.

00 05 01 * * /usr/local/letsencrypt/letsencrypt-auto certonly --webroot -d www.{自分の契約しているドメイン} --webroot-path {公開したいドキュメントのルートここでは/var/www} --renew-by-default && nginx -s reload


TLSに対応させる

nginx.conf をいじる.

http接続をhttps接続にリダイレクトさせる内容を


listen 80server タグ内に書く.


listen 443server タグのコメントを外してドキュメントルート等書く.


Let's Encryptで取得した証明書は /etc/letsencrypt/live/www.{自分の契約しているドメイン}/ 以下にあるのでそれを参照する旨を書く.


nginx.conf

~省略~

server {
listen 80;
server_name www.{自分の契約しているドメイン};
return 301 https://www.{自分の契約しているドメイン}$request_uri;
}

server {
listen 443 ssl;
server_name www.{自分の契約しているドメイン};
~省略~
ssl_certificate /etc/letsencrypt/live/www.{自分の契約しているドメイン}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.{自分の契約しているドメイン}/privkey.pem;

location / {
root /var/www;
index index.html;
}
}
~省略~


nginx.conf の文法チェック

$  sudo nginx -t

okが出たらNginxをリロードする.

$ sudo nginx -s reload

一応アクセスできるか確認.


できたらSSLLabのテストもやってみる.


(BかCが出る)


http2に対応させる

nginx.conf をいじる.


nginx.conf

~省略~

server {
listen 443 ssl http2;
server_name www.{自分の契約しているドメイン};
~省略~
ssl_certificate /etc/letsencrypt/live/www.{自分の契約しているドメイン}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.{自分の契約しているドメイン}/privkey.pem;

ssl_ciphers ECDHE+AESGCM:DHE+AESGCM:HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
root /var/www;
index index.html;
}
}
~省略~


文法チェック,リロードの流れをもう一度.


SSLLabでA+をとる

HTTP/2がTLSに求める制限


  • TLSのバージョンは1.2以上

  • プロトコル選択にALPN(RFC7301)を使う

  • サーバ認証を共有できる接続は接続共有が可能

  • SNI(Server Name Indicator)拡張必須

  • SNI(Server Name Indicator)拡張必須

  • TLS Compression禁止

  • Renegotiation禁止

  • 鍵長 (DHE 2048bit以上、ECDHE 224bit以上)サポート必須 • PFS必須 (DHE,
    ECDHE)

  • AEAD(GCM/CCM)以外の暗号方式をブラックリストとして利用禁止

そんなことはいいからやり方はよ


DHEの鍵長増加

2048bitのDHパラメータファイルを生成.


nginx.conf があるフォルダで以下を実行.

$ openssl dhparam -out dhparam.pem 2048

$ openssl dhparam -text -in dhparam.pem -noout

nginx.conf のsslサーバの部分にDHパラメータのファイルを加える.


nginx.conf をいじる.


nginx.conf

~省略~

server {
listen 443 ssl http2;
server_name www.{自分の契約しているドメイン};
~省略~
ssl_certificate /etc/letsencrypt/live/www.{自分の契約しているドメイン}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.{自分の契約しているドメイン}/privkey.pem;
ssl_dhparam dhparam.pem;

ssl_ciphers ECDHE+AESGCM:DHE+AESGCM:HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
root /var/www;
index index.html;
}
}
~省略~


文法チェック,リロードの流れをもう一度.


SSLLabのテストもやってみる.


(AかA-が出る)


HSTSヘッダ

nginx.conf のsslサーバの部分にHSTSヘッダを返すように以下の設定を追加.

(max-ageは半年に設定)


nginx.conf

~省略~

server {
listen 443 ssl http2;
server_name www.{自分の契約しているドメイン};
add_header Strict-Transport-Security "max-age=15768000; includeSubdomains";

ssl_certificate /etc/letsencrypt/live/www.{自分の契約しているドメイン}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.{自分の契約しているドメイン}/privkey.pem;
ssl_dhparam dhparam.pem;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;

ssl_ciphers ECDHE+AESGCM:DHE+AESGCM:HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
root /var/www;
index index.html;
}
}
~省略~


文法チェック,リロードの流れをもう一度.


SSLLabのテストもやってみる.


(A+が出る(2016-03-03))