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

TLS1.3のロゴ

nginxでは、設定ファイル(nginx.conf)でSSL/TLSに使用する暗号化スイートを指定することができますが、TLS1.3の暗号スイートを設定するのに苦労したので、手順を残しておきます。

環境

・CentOS Linux release 7.4.1708 (Core)

・nginx 1.15.6

前提知識

TLS1.3で利用できる暗号スイートは5種類

TLS1.2以前と比較して種類が減り、表記も短くなったので非常にすっきりとしています。

  • TLS_AES_256_GCM_SHA384
  • TLS_AES_128_GCM_SHA256
  • TLS_AES_128_CCM_8_SHA256
  • TLS_AES_128_CCM_SHA256
  • TLS_CHACHA20_POLY1305_SHA256

TLS1.2の表記法から、TLS1.3の暗号スイートであることを表す TLS_ が先頭に加わり、鍵交換アルゴリズムと公開鍵アルゴリズムの指定がなくなりました。

上の2つはTLS1.2でもお馴染みの、共通鍵にAESを利用した暗号スイートです。

暗号利用モードがCCMのものは、量子コンピュータによる将来的な攻撃への耐性をもつ暗号利用モードとして新たに追加された暗号スイートです。現状のところ使う意味は薄いと思われます。

TLS_CHACHA20_POLY1305_SHA256は、AESのハードウェア支援(AES-NI)が効かないモバイル機器等でのスループット向上が期待できます。Webサーバとしてこれを利用することを考えたとき、スマホからのアクセスが多くを占めるサイトであれば一考の余地があるかもしれません。

暗号スイートについて考えること

おそらく、一般的なWebサーバでは以下の2点になると思われます。

①AESの鍵長は128bitと256bitのどちらを優先するか

TLS_CHACHA20_POLY1305_SHA256とAESのどちらを優先するか

nginxの対応状況

現時点での最新バージョン(nginx 1.15.6)のnginxではTLS1.3が利用できます。利用方法は、nginxをTLS1.3に対応させるメリットと方法 [OpenSSL 1.1.1]に書いた通りですが、このままではTLS1.3の暗号スイートが設定できません。と言うより、設定しても設定内容が認識されずに既定値に置き換わってしまうようです。

既定値は、

  1. TLS_AES_256_GCM_SHA384
  2. TLS_CHACHA20_POLY1305_SHA256
  3. TLS_AES_128_GCM_SHA256

となっています。

設定のための準備

現状nginxでTLS1.3の暗号スイートを明示的に設定するには、nginxをビルドするときに使うOpenSSLにパッチを当てるという方法があります。具体的な方法を以下に示します。

必要ツールのインストール

$ yum install patch

各種ソースのダウンロード

nginx最新版のダウンロードURLは、https://nginx.org/en/download.htmlより確認してください。

#作業用ディレクトリへ移動(場所は一例)
$ cd /usr/local/src/

$ git clone https://github.com/openssl/openssl.git
$ git clone https://github.com/hakasenyang/openssl-patch.git
$ curl -O https://nginx.org/download/nginx-1.15.6.tar.gz

OpenSSLのバージョンを1.1.1へ戻す

git clone でダウンロードしたOpenSSLのソースは、その時点で開発途中の最新バージョンの開発版なので、このソースを以下のコマンドを使ってOpenSSL 1.1.1リリース時まで戻します。

$ cd openssl
$ git checkout 1708e3e85b4a86bae26860aa5d2913fc8eff6086

OpenSSLにパッチを当てる

openssl-1.1.1-tls13_nginx_config.patch には、元のOpenSSLのコードとの差分が記述されています。patch コマンドを使って、これをソースコードに適用します。

$ patch -p1 < ../openssl-patch/openssl-1.1.1-tls13_nginx_config.patch
patching file ssl/s3_lib.c
patching file ssl/ssl_ciph.c

$ cd ..
#わかりやすいように名前を変更
$ mv openssl/ openssl-1.1.1-patched

nginxのビルド

先ほどパッチを当てたOpenSSLを使ってnginxをビルドします。ここからは、nginxをTLS1.3に対応させるメリットと方法 [OpenSSL 1.1.1]とほぼ同じ手順なのでそちらを参照。

1つだけ異なる点は、nginxビルド前の configure コマンドの –with-openssl です。

--with-openssl=/usr/local/src/openssl-1.1.1-patched

設定方法

nginxが無事起動したら、SSL関連の設定を設定ファイルに記述していきます。

デフォルトでは、設定ファイルは /<nginxのインストールディレクトリ>/conf/nginx.conf です。

TLS1.2の場合と同様に、ssl_ciphers に続いて暗号スイートを設定しますが、パッチを当てている関係で指定方法が少し異なります。また、暗号利用モードがCCMのものは設定できませんでした。

暗号スイート名

指定方法

TLS_AES_256_GCM_SHA384

TLS13+AESGCM+AES256

TLS_AES_128_GCM_SHA256

TLS13+AESGCM+AES128

TLS_CHACHA20_POLY1305_SHA256

TLS13+CHACHA20

サンプル設定例(SSL関連部分のみ)

最低限の設定例です。

ssl_ciphers にはTLS1.3と1.2の暗号化スイートを混ぜて指定することができます。先に指定されたものが優先的に使用されます。

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

    ssl_protocols TLSv1.3 TLSv1.2;
    ssl_certificate <サーバー証明書のファイルパス>;
    ssl_certificate_key <サーバーの秘密鍵のファイルパス>;
    ssl_ciphers 'TLS13+AESGCM+AES128:TLS13+CHACHA20:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-CHACHA20-POLY1305';
    ssl_prefer_server_ciphers on;
}

参考

パッチについてのより詳細な情報は、https://github.com/hakasenyang/openssl-patchを参照してください。

ちなみにリンクのページでは、このほかにもOpenSSLとnginxに関する便利なパッチが色々と配布されています。例えば、nginxをドラフト版のTLS1.3にも対応させるパッチなどがあります。

その他役に立つかもしれないリンク

ChaCha20-Poly1305の実装性能調査 – CRYPTREC

量子コンピュータが共通鍵暗号の安全性に与える影響 – 日本銀行金融研究所

AES-CCM Cipher Suites for Transport Layer Security (TLS) – IETF

あわせて読みたい

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です