Apache 2.4系でHTTP/2サーバを構築してみるテスト。
HTTP/2のチューニング[TLS応用編]基本編のチューニング、応用編のチューニングに加えて、以下の設定を行うことで、TLS負荷のチューニングを行います。 もろもろのソフトウエアのインストールは、当サイトのインストール例を基準としています。 [参考]>>mod_http2のリファレンス
共通鍵暗号にAES128しか使用しない暗号スイートとは、鍵交換、鍵認証、共通鍵暗号、メッセージ署名などの方式を規定したものです。 このうち、共通鍵暗号として最もメジャーなものはAES暗号です。 ビット数によってAES128, AES192, AES256の3種類があるが、OpenSSL(TLS)では、AES128とAES256の2つが利用できます。 前者が128ビット単位の10ラウンド、後者が256ビット単位の14ラウンドで暗号化・復号化します。
大体ですが、AES256よりも、ビット数、ラウンド数ともに少ない、AES128の方が、3~4割ほどエンコード・デコード速度が速くなります。 (ただし、AES256のほうが、セキュリティー的には強固です。) そのため、積極的にAES128を利用することで、サーバ及びクライアント側の演算負荷を減らします。 なお、AES128の安全性については、3072ビットのRSA暗号や256ビットの楕円曲線暗号と同一と言われておりますので、現時点ではAES256にこだわる必要はあまりないと思われます。 AES256にこだわる必要がある方は、コチラも参考にしてください。 [参考]>>暗号スイートの暗号強度と、公開鍵のビット数の設定
同じく、ビット数の少ない楕円曲線の方が、処理は軽くなります。 そのため、鍵交換には、384ビットの楕円曲線ではなく、256ビットの楕円曲線を指定したECDHEを利用します。 (Apacheのデフォルト設定でそうなりますが、明示してみます。) 設定はサーバ証明書がRSA暗号なのか、EC暗号(ECDSA)なのかにより、異なりますが、サーバ負荷としては、EC暗号(ECDSA)の方が軽くなります。 [参考]>>サーバ負荷をRSAとECDSAで比較
また、Let's Encryptから、ECDSAサーバ証明書を取得する方法も、取り方も当サイト内で解説しておりますので、参考にしてください
AES128にECDHE-RSAを組み合わせる場合RSA暗号のサーバ証明書と128ビットのAES暗号のみを共通鍵に利用する場合の設定は以下の通りです。
/usr/local/apache2/conf/extra/httpd-ssl.confの一部
…(省略)… SSLProtocol -All +TLSv1 +TLSv1.1 +TLSv1.2 SSLHonorCipherOrder on SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK SSLOpenSSLConfCmd ECDHParameters prime256v1 SSLOpenSSLConfCmd Curves prime256v1 …(省略)… この設定では、鍵交換のみ楕円曲線を利用します。 楕円曲線も、ビット数の短い方が、処理が軽いので、SSLConfの設定(SSLOpenSSLConfCmd)のECDHParametersとCurvesには、256ビットのprime256v1のみ設定ます。 AES128にECDHE-ECDSAを組み合わせる場合RSA暗号のサーバ証明書と128ビットのAES暗号のみを共通鍵に利用する場合の設定は以下の通りです。
/usr/local/apache2/conf/extra/httpd-ssl.confの一部
…(省略)… SSLProtocol -All +TLSv1 +TLSv1.1 +TLSv1.2 SSLHonorCipherOrder on SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK SSLOpenSSLConfCmd ECDHParameters prime256v1 SSLOpenSSLConfCmd Curves secp384r1:prime256v1 …(省略)… なお、ECDSAのサーバ証明書が、384ビットの楕円曲線を利用している可能性があるので、Curvesにsecp384r1が追加してあります。 ECDSAサーバ証明書も256ビットのprime256v1だぜ!ってわかっている方は不要です。 また、ECDSAとRSAの2つのサーバ証明書を組み合わせた、マルチアルゴリズム証明書を利用している場合は、上記2つの設定を適当に混ぜてください。
TLSのレコードサイズの調整TLSのレコードサイズとは、データの暗号化の処理単位となる長さです。 この数値は、TLS接続中に変更することができます。 Apacheからは、H2TLSWarmUpSizeとH2TLSCoolDownSecsによって、ある程度制御することができます。
TLSでは、暗号化したいメッセージをレコードと呼ばれる単位に、分割して送信します。 レコードの長さは、16ビットで表現されるため、65535以下長さです。 TLSの接続直後は、レコードサイズが、1300バイト以下になっています。 これは、TLS接続直後は、まだTCPが、フローコントロールや、ウィンドウサイズを調整しているため、この間は、パケットロスの可能性が通常より高まります。 このときの再送のロス、特に再送パケット数が大きくならないように、TLSのレコードサイズも、MTUレベルに抑えて、パケットサイズをMTU以下にしています。
しかし、このままでは、効率が悪くなります。 そこで、TLSの送信レコードサイズが1300バイト以下のときに、H2TLSWarmUpSizeだけ、データを送信すると、TCPウィンドウサイズの調整が済んでいると判断し、送信レコードサイズを16Kバイトまで拡大します。 これにより、レコード処理の単位が長くなり、効率の良いTLS暗号化処理を行うことができます。 デフォルトは、1048576です。つまり1Mバイトも転送しないと、TLSレコードサイズが増えません。これでは、ほとんどの場合、増えない気がします。 対向のOSにもよりますが、TCPの初期ウィンドウサイズの調整は、MTUレベルのパケットを50回くらい送れば、十分でしょう。 ということで、64Kバイトあたりをお試しいただくといいかもしれません。 日本の通信環境ならもっと短くても良いでしょう。
しかし、LTEや、WiFiなど無線通信などでは、通信環境が変化して、パケットの再送が必要になることがあります。 そういった状況では、16Kバイトのレコードサイズだと効率が悪くなります。 こういった状況に対応するため、TLSの送信レコードサイズが16Kバイトになっていると、今度は、H2TLSCoolDownSecsによって、TLSの送信レコードサイズを戻すことができます。 H2TLSCoolDownSecsは、TLSの送信レコードサイズを 1300バイト以下(MTUレベル)の長さの小さいものに戻すまでの秒数を指定します。 この間のTLS送信がなければ、送信レコードサイズを 1300バイト以下に戻します。 0なら、戻しません。 デフォルトは1秒です。
モバイル相手の接続が多いため、粘りたい場合は、少し増やしても良いでしょう。 大きめのファイルを送信することが多い場合も、3秒程度送信できなければ、通信状況が変化したと判断して、クールダウンするのがいいでしょう。 以上の理由から、以下の設定をお試しください。
/usr/local/apache2/conf/extra/httpd-ssl.confの一部
<IfModule http2_module> H2TLSWarmUpSize 65536 H2TLSCoolDownSecs 3 </IfModule>
|