nginxをhttp/2+TLSv1.3に対応させるためにトライしたこと
2020/03/22
最近暑い日が続いています。ってサラっと言えないくらいエグい暑さ。
さて、これまで本ブログのWebサーバnginxはhttp/1.1プロトコルで動作していたのですが、この度https/2.0プロトコルにて動作できるようになったので、設定するまでの手順を記録していきます。
http/2+TLSv1.3対応って何をどこまで?
nginxでhttp/2で通信するためには以下の構成が必要らしいです。
・nginx version: 1.9.5以上
・OpenSSL version: 1.0.2以上
厳密にはOpenSSLはCentOSにデフォルトで内包されているのバージョンでもhttp/2が使えるのですが、Chromeブラウザではhttp/2通信をするのにALPN ( Application Layer Protocol Negotiation ) 仕様でネゴシエーションします。デフォのOpenSSLではこれに対応できず、OpenSSL 1.0.2以上でないと対応しないので、今回はOpenSSLもアップグレードします。
参考:Supporting HTTP/2 for Website Visitors via nginx.com
【2018/11/18追記】
nginxでTLSv1.3(RFC8446版)で通信するためには OpenSSL version : 1.1.1が必要らしいです。
そのため、本記事はOpenSSL version : 1.1.1にアップグレードする内容に変更しています。
触る前の構成
・Linux 4.14.3-1.el6.elrepo.x86_64
・CentOS 6.9 (Final)
・nginx version:
# nginx -V
nginx/1.10.2
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-17) (GCC)
built with OpenSSL 1.0.1e-fips 11 Feb 2013
TLS SNI support enabled
configure arguments: --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/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-ipv6 --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module=dynamic --with-http_image_filter_module=dynamic --with-http_geoip_module=dynamic --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_degradation_module --with-http_slice_module --with-http_stub_status_module --with-http_perl_module=dynamic --with-mail=dynamic --with-mail_ssl_module --with-pcre --with-pcre-jit --with-stream=dynamic --with-stream_ssl_module --with-debug --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'
OpenSSL
# cd /usr/local/src
# wget https://www.openssl.org/source/openssl-1.1.1.tar.gz
# tar -zxf openssl-1.1.1.tar.gz
ここで解凍されたopensslのバージョンを確認します。あとで使うので。
nginx
作業に先立ちnginxは停止させます。心配ならここで事前バックアップをして下さい。
# /etc/rc.d/init.d/nginx stop
# cd /usr/local/src
# wget http://nginx.org/download/nginx-1.14.1.tar.gz
# tar -zxf nginx-1.14.1.tar.gz
この後、nginxをコンパイルするのだけれど、
これまで使用していたnginxのコンパイルオプションをそのまま使用します。
その際に、先ほど準備したOpenSSLのフルパスを追記して下さい。
# ./configure --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/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-ipv6 --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module=dynamic --with-http_image_filter_module=dynamic --with-http_geoip_module=dynamic --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_degradation_module --with-http_slice_module --with-http_stub_status_module --with-http_perl_module=dynamic --with-mail=dynamic --with-mail_ssl_module --with-pcre --with-pcre-jit --with-stream=dynamic --with-stream_ssl_module --with-debug --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' --with-openssl=/usr/local/src/openssl-1.1.1 --with-openssl-opt=enable-tls1_3
コンパイルエラーとなった場合、必要なライブラリがインストールされていない場合がほとんどだと思うので、エラー出力を確認して必要なライブラリをyumでインストールします。うちの環境では以下のライブラリが不足していたのでyumでインストールしました。
# yum install pcre-devel
# yum install libxslt-devel
# yum install gd-devel
# yum install GeoIP-devel
コンパイルが進みプロンプトが返ってきた次に進む。
# make
# make install
Webサーバ側
http/2に対応させるためにWebサーバ毎のlistenディレクティブに http2 を追記します。
listen 443 ssl http2;
TLSv1.3に対応させるため以下の設定を入れます。また旧来のプロトコル( TLSv1.1、TLSv1 )をサポートする必要はありませんので削除しました。
ssl_protocols TLSv1.3 TLSv1.2;
ssl_ciphers 'TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256:TLS13-AES-128-GCM-SHA256:TLS13-AES-128-CCM-8-SHA256:TLS13-AES-128-CCM-SHA256:ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256';
ssl_prefer_server_ciphers on;
ssl_ecdh_curve X25519:prime256v1;
またDHグループも更新しておいた方が良いとの記述が散見されたので、新規作成しておきました。
# cd /etc/nginx
# openssl dhparam -out dhparams-4096.pem 4096
# chown root:nginx dhparams-4096.pem
これをnginx側の ssl_dhparm ディレクティブで指定します。
ssl_dhparam /etc/nginx/dhparams-4096.pem;
ここまで完了したらnginxを起動させます。
# /etc/rc.d/init.d/nginx start
yumでnginxをインストールしている場合はnginx.repoの無効化をお忘れなく。
yum updateの時にnginxがアップデートされると、どうなってしまうかわかりません。
対応できたかな確認
以下のWebサービスで ALPN対応を含めた http/2 確認テストができるみたいなのでやってみました。
Online HTTP/2 test via keycdn.com
http/2もALPNも有効になっているみたいで良かったです。
【2018/08/19 追記】
TLSv1.3に対応しているかどうか確認テストもやってみました。ちゃんとTLS v1.3に対応できているみたいです。
SSL Server Test via ssllabs.com