nginxをTLS1.3に対応させるメリットと方法 [OpenSSL 1.1.1]

TLS1.3のロゴ

2018年9月11日に、OpenSSL バージョン1.1.1の正式版がリリースされました。バージョン1.1.1は、長期サポート版(LTS)となっており、5年後の2023年9月11日までサポートされることになっています。それと同時に、従来のLTSであるバージョン1.0.2のサポートが2019年いっぱいで終了します。

ようやく次期LTSの正式バージョンが出たということで、nginxでOpenSSL1.1.1を利用し、WebサイトをTLS1.3に対応させる手順を残しておこうと思います。

スポンサーリンク

TLS1.3では何が変わるのか

TLS1.3に対応するとどんないいことがあるのか、簡単にまとめてみました。

ハンドシェイクの暗号化強化と効率化

TLSのハンドシェイクとは、TLSによる暗号化通信を安全に開始するための処理です。このハンドシェイクで用いる通信のほとんどが暗号化されるようになりました。

また、ハンドシェイクの通信が1往復減り、効率が上がりました。

暗号化スイートの安全化

TLS1.3で利用できる暗号化アルゴリズムは、現時点ではすべて安全です。

古い暗号化スイートは削除されました。

その他知っておきたい変更点

  • 暗号化スイートとして、TLS_CHACHA20_POLY1305_SHA256 が利用可能に

CHACHA20 は、TLSのデータ部分の暗号化のアルゴリズムです。256セキュリティービットを提供します。

従来はAESが使われていましたが、AESのハードウェア支援がないモバイル向けのCPUでは、PCと比較するとパフォーマンス的にかなり不利でした。CHACHA20はその弱点をいくらか克服しています。

(実はOpenSSL1.1.0以降から、TLS1.2でもCHACHA20とPOLY1305は利用可能でしたが…)

  • DSA証明書が利用不可に

ECDSA証明書は大丈夫です。

TLS1.3 に対応したnginxのインストール方法

nginxをソースからビルドする場合、SSL/TLSの処理に使用するライブラリを静的コンパイルすることができます。ここでOpenSSL1.1.1をビルドすることで、nginxでTLS1.3を利用することができるようになります。

システムにあらかじめインストールされているOpenSSLはそのままに、nginxで使うOpenSSLのみを変更するという感じです。

環境

CentOS Linux release 7.5.1804 (Core)

前準備

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

nginxをデフォルト設定でビルドするのに最低限必要なパッケージをインストールします。

$ sudo yum install gcc pcre-devel zlib-devel

nginx実行ユーザーの追加

nginxをパッケージからインストールする場合は自動でやってくれますが、ソースから新規インストールする場合は自分で追加します。

$ sudo useradd -M -s /sbin/nologin nginx

OpenSSLのダウンロード

$ cd /usr/local/src/
$ sudo curl -O https://www.openssl.org/source/openssl-1.1.1.tar.gz
$ sudo tar fxz openssl-1.1.1.tar.gz

nginxのダウンロード&インストール

https://nginx.org/en/download.html より、Mainline version 最新版のURLを確認。

#ダウンロード&展開
$ sudo curl -O https://nginx.org/download/nginx-1.15.5.tar.gz
$ sudo tar fxz nginx-1.15.5.tar.gz

$ cd nginx-1.15.5

#インストール場所等の設定(configureのパラメータが分かる方はお好みで)
$ sudo ./configure --prefix=/opt/nginx \
--user=nginx --group=nginx \
--with-threads --with-http_ssl_module --with-http_v2_module \
--with-openssl=/usr/local/src/openssl-1.1.1

#ビルド
$ sudo make
#インストール
$ sudo make install

インストールの確認

この記事の手順に従ってインストールすると、/opt/nginxにインストールされます。

$ /opt/nginx/sbin/nginx -V
nginx version: nginx/1.15.5
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-28) (GCC)
built with OpenSSL 1.1.1  11 Sep 2018 #OpenSSL 1.1.1 でビルドされている
TLS SNI support enabled
configure arguments: --prefix=/opt/nginx --user=nginx --group=nginx --with-threads --with-http_ssl_module --with-http_v2_module --with-openssl=/usr/local/src/openssl-1.1.1

ユニットファイル作成

systemctl から起動や停止ができるように、ユニットファイルを作成します。

$ sudo vi /usr/lib/systemd/system/nginx.service

ユニットファイルには下記のように記述します。インストール場所を変更した場合はそれに合わせて変更のこと。

[Unit]
Description=nginx - high performance web server
Documentation=http://nginx.org/en/docs/
After=network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target

[Service]
Type=forking
PIDFile=/opt/nginx/logs/nginx.pid
ExecStart=/opt/nginx/sbin/nginx -c /opt/nginx/conf/nginx.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID
PrivateTmp=true

[Install]
WantedBy=multi-user.target

nginxの設定

設定ファイルは、/opt/nginx/conf/nginx.conf です。ファイル末尾の } の前に以下のように追記します。

server {
    listen 443 http2 ssl;
    server_name <サーバーのURL>;

    ssl_protocols TLSv1.3 TLSv1.2;
    ssl_certificate <サーバー証明書のファイルパス>;
    ssl_certificate_key <サーバーの秘密鍵のファイルパス>;

    ssl_prefer_server_ciphers on;

    location / {
        root   html;
        index  index.html index.htm;
    }
}

起動

$ sudo systemctl start nginx
$ sudo systemctl enable nginx

ファイアウォール等、アクセス許可の設定を忘れずに!

起動の確認

TLS1.3に対応できたかどうかは、以下のサイトから自分のサイトURLを入力することで確認することができます。

https://dev.ssllabs.com/ssltest/index.html

SSL Labs のテスト結果

TLS1.3がYesになれば対応できている

既知の問題など

注意:2018年10月現在の情報です。

主要ブラウザの対応状況

Firefox はバージョン63以降、Chrome はバージョン70以降から、正式版のTLS1.3に対応しました。それ以前のバージョンでは、正式版になる前のドラフト版のみの対応となっています。

今回の手法だけだとサーバー側はドラフト版のTLS1.3を利用できないので、最新でないブラウザからのアクセスは従来通りのTLS1.2で接続されます。

ドラフト版のTLS1.3にも対応させる手法も一応あります。詳しくは解決策(自己責任)を参照。

暗号化スイートの問題

OpenSSL1.1.1 を組み込んだnginxは、TLS1.3の暗号化スイートが手動で設定できないようです。自動で以下の順番で設定されます。

TLS_AES_256_GCM_SHA384
TLS_CHACHA20_POLY1305_SHA256
TLS_AES_128_GCM_SHA256

これでは、AESの鍵長は128bitを優先したい場合や、CHACHA20_POLY1305を優先的に利用したい場合でも、AES256bitが最優先となってしまいます。

TLS1.2の暗号化スイートは従来どおりに設定可能です。

今後のアップデートで修正されるとは思いますが…

2018.11.23 更新:具体的な修正方法を記事にしました。

nginxでTLS1.3の暗号スイートを設定する方法

解決策(自己責任)

以上2つの問題点を解決できる方法として、OpenSSLの非公式パッチを当てるという手段があります。

使用法は GitHub - hakasenyang/openssl-patch: OpenSSL & NginX Patch を参照。

openssl-equal-1.1.1_ciphers.patchを当てると、TLS1.3正式版のほかにドラフト版も利用可能となり、nginxで暗号化スイートの設定も可能になります。

Firefox通常版からアクセス

パッチを適用すると、ドラフト版のTLS1.3と、暗号化スイートの手動設定が利用できる。

どちらの問題もそのうち対応されると思うので、非公式パッチを当ててまで解決するべき問題かどうかは微妙ですが…

参考

TLS1.3 – OpenSSLWiki

RFC 7539 – ChaCha20 and Poly1305 for IETF Protocols

Building nginx from Sources

tls13.gby – iijlab-seminar-20170110.pdf

スポンサーリンク

あわせて読みたい

コメントを残す

質問・感想などお気軽にどうぞ。
*が付いている項目は入力必須です。メールアドレス以外の項目が公開されます。
スパム防止のため、コメント反映まで少々時間がかかります。