potpro (ぽとぷろ)
Full-stuck engineer(Not Full-stack)
JS/PHP/Go/Docker/Nginxなど。技術または趣味寄りの発信ブログです。
全 85 記事HTTP/2とTLSv1.3(draft-20)をnginx+OpenSSLで対応させる
HTTP/2とTLSv1.3(draft-20)をnginx+OpenSSLで対応させる
せっかくなので、当サイトはhttp2に正式対応しました。
昔やったはずじゃ・・・と思っていたのですが、
http/2と似て非なるほぼ同じSPDYの対応でした。
SPDYはいつの間にやらchromeではhttp/2扱いされなくなり(googleが作ったのに)、chrome 51から非対応となってしまいました。
ということでこのブログもhttp1.1に戻っていたので、正式にhttp/2に対応しました。 この辺は別の話なのでこの記事が詳しいです。
EC2+nginxでhttp2対応できたとおもったらできてなかった話。(解決します)
ついでに、当サイトはTLSv1.3(draft-20)に対応しました(多分)。
なお、言っておきますが 現状のブラウザでは見れません。
新しくブラウザが出たとしても見れるかもわかりません。
正直まだstandardになってないですし、仕様は変更されるでしょうし、現状ここでの対応はほぼ無意味です。
ただ、TLSv1.3が正式対応になりOpenSSL1.1.1が正式リリースした時はこの記事は役立つと思います。多分。
OpenSSLのTLS1.3実装に関しては公式が使用方法を書いています。これがとても詳しいです。 Using TLS1.3 With OpenSSL
コネクションの方法など難しいところは置いておくとして、 実際に使用するところで気になるのは暗号化スイートがTLS1.3専用のものが用意されています。
- TLS13-AES-256-GCM-SHA384
- TLS13-CHACHA20-POLY1305-SHA256
- TLS13-AES-128-GCM-SHA256
- TLS13-AES-128-CCM-8-SHA256
- TLS13-AES-128-CCM-SHA256
OpenSSLの現在の実装でTLS1.3はこの5つしかサポートされていません。
これ以外を使用してTLSv1.3認証を行おうとすると、当然ですが認証に失敗します。
そのためTLS1.2以下と併用するためにはTLS1.3の時だけ上のスイートを優先する必要があります。
nginx+OpenSSLでのTLSv1.3対応
nginxのmailline versionの最新版1.13.0にて、"ssl_protocols" でTLSv1.3を選択できるようになりました。
*) Feature: the "TLSv1.3" parameter of the "ssl_protocols" directive.
そのため、おなじみの構成であるnginx+OpenSSLでTLSv1.3を使えるようになります(厳密にはなる予定です)。
使用するnginxは1.13.0、OpenSSLは1.1.1-dev(master)です。
OpenSSLはTLSv1.3が正式になったら1.1.1をリリースすると言っていますので、実際に正式になった時もこの設定で動くと思います。
OpenSSL1.1.1(dev)のインストール
リポジトリなどではなくgitからmasterを落としてビルドします。gccなどが必要です。
後、libssl.soが無いと怒られたりしたので/usr/local/lib64/に動的リンクを貼ったりpathを通したりして動きました。
cd /usr/local/src/
git clone https://github.com/openssl/openssl
cd openssl
./config enable-tls1_3
make
make test
make install
/usr/local/bin/openssl version
OpenSSL 1.1.1-dev xx XXX xxxx
nginx 1.13.0のインストール
こちらはリポジトリはあるのですが、OpenSSLを組み込む関係でこちらもソースコードからビルドが必要です。
このやり方だとyumなどで本体に入っているnginxは削除しました。
configureのオプションは各自吟味してください。
cd /usr/local/src/
wget http://nginx.org/download/nginx-1.13.0.tar.gz
tar zxvf nginx-1.13.0.tar.gz
cd nginx-1.13.0
./configure --prefix=/etc/nginx --sbin-path=/usr/local/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_stub_status_module --with-http_auth_request_module --with-threads --with-stream --with-stream_ssl_module --with-http_slice_module --with-mail --with-mail_ssl_module --with-file-aio --with-http_v2_module --with-openssl=../openssl/ --with-openssl-opt=enable-tls1_3
make
make install
ここで重要なのは--with-http_v2_module --with-openssl=../openssl/ --with-openssl-opt=enable-tls1_3
です。
--with-opensslは先ほどのopensslのソースコードのpathです。nginxにバンドルします。
--with-http_v2_moduleはhttp/2対応のため、--with-openssl-opt=enable-tls1_3も設定しないと動きませんでした。
なので使うだけならOpenSSL1.1.1(dev)をmake installする必要ないのですが、openssl s_clientを使用するために使います。
あとはpathを通して、nginx -V
で確認します。うまくいけば下のようになっているはずです。
nginx version: nginx/1.13.0
built by gcc <略>
built with OpenSSL 1.1.1-dev xx XXX xxxx
TLS SNI support enabled
configure arguments: <略> --with-http_v2_module --with-openssl=../openssl/ --with-openssl-opt=enable-tls1_3
nginx設定
既にSSL設定が終わっているなら、このあたりの設定を変更するとOKです。再起動も忘れずに。
ssl.conf
#TLSv1.3用設定
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers 'TLS13-AES-128-GCM-SHA256:TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:ECDHE:!COMPLEMENTOFDEFAULT';
#http2用設定
listen 443 ssl http2
SSLv1.3の接続確認
最初に言ったようにブラウザだと確認できませんでした・・・draft-18のものはchromeのchrome://flags/
でTLS1.3を指定すると見れます。
https://tls13.crypto.mozilla.org/
このサイトを見るとdraft-18対応済みのchrome/firefoxでは正常に確認でき、TLS1.3と表示されているのがわかります。
対応していないとchromeでは「サポートされていないプロトコルが使用されています」というレアな画面が出ます。
OpenSSLのSSL/TLS client機能で接続確認します。1.1.1は-tls1_3
オプションでTLSv1.3で接続しに行きます。
一部省略。
>openssl s_client -connect blog.potproject.net:443 -tls1_3
CONNECTED(00000003)
depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
verify error:num=20:unable to get local issuer certificate
---
Certificate chain
0 s:CN = potproject.net
i:C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
1 s:C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
i:O = Digital Signature Trust Co., CN = DST Root CA X3
---
Server certificate
subject=CN = potproject.net
issuer=C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
---
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: RSA-PSS
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 3026 bytes and written 270 bytes
Verification error: unable to get local issuer certificate
---
New, TLSv1.3, Cipher is TLS13-AES-128-GCM-SHA256
Server public key is 2048 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
SSL-Session:
Protocol : TLSv1.3
Cipher : TLS13-AES-128-GCM-SHA256
Session-ID:
Session-ID-ctx:
Master-Key: <master-key>
PSK identity: None
PSK identity hint: None
SRP username: None
Start Time: <StartTime>
Timeout : 7200 (sec)
Verify return code: 20 (unable to get local issuer certificate)
Extended master secret: no
---
これで正しいのかイマイチわかりませんが、TLS1.3認証は出来ていることが確認できます。
TLSv1.3の正式に決まるまでもう日は近いと思うので、その時にすぐに対応できればいいな・・・