Apache 2.4系でHTTP/2サーバを構築してみるテスト。
OpenSSL1.1.0系の暗号スイートいよいよApacheもバージョン2.4.26以降から、OpenSSL 1.1.0に対応します。 そこで、改めてOpenSSL 1.1.0のベンチマークを取って、最適な暗号スイートを検討したいと思います。 そして、CHACHA20-POLY1305と呼ばれる、OpenSSL1.1.0で新たに採用された暗号方式を説明し、これを含む暗号スイートの設定を説明します。
OpenSSL 1.1.0で追加された暗号スイートまずは、追加されたCHACHA20-POLY1305を利用する暗号スイートを確認してみます。 $ openssl ciphers -V |grep CHACHA20-POLY1305 0xCC,0xA9 - ECDHE-ECDSA-CHACHA20-POLY1305 TLSv1.2 Kx=ECDH Au=ECDSA Enc=CHACHA20/POLY1305(256) Mac=AEAD 0xCC,0xA8 - ECDHE-RSA-CHACHA20-POLY1305 TLSv1.2 Kx=ECDH Au=RSA Enc=CHACHA20/POLY1305(256) Mac=AEAD 0xCC,0xAA - DHE-RSA-CHACHA20-POLY1305 TLSv1.2 Kx=DH Au=RSA Enc=CHACHA20/POLY1305(256) Mac=AEAD 0xCC,0xAE - RSA-PSK-CHACHA20-POLY1305 TLSv1.2 Kx=RSAPSK Au=RSA Enc=CHACHA20/POLY1305(256) Mac=AEAD 0xCC,0xAD - DHE-PSK-CHACHA20-POLY1305 TLSv1.2 Kx=DHEPSK Au=PSK Enc=CHACHA20/POLY1305(256) Mac=AEAD 0xCC,0xAC - ECDHE-PSK-CHACHA20-POLY1305 TLSv1.2 Kx=ECDHEPSK Au=PSK Enc=CHACHA20/POLY1305(256) Mac=AEAD 0xCC,0xAB - PSK-CHACHA20-POLY1305 TLSv1.2 Kx=PSK Au=PSK Enc=CHACHA20/POLY1305(256) Mac=AEAD Webサイトで利用する暗号スイートは、黄色で示した3つになると思います。 さらにDHEは処理速度がかかりそうなので、実際に利用の機会がありそうなのは、楕円暗号を利用した、ECDHE-ECDSA-CHACHA20-POLY1305とECDHE-RSA-CHACHA20-POLY1305の2種類になります。 以下、ベンチマークを取っていきますが、現時点で、CHACH20-POLY1305のベンチマークは取れないようなので、それ以外の、これまでも利用できていた暗号の処理時間の比較を進めます。 大きく変化があったのは、256ビットの楕円曲線であるprime256v1と呼ばれる処理です。
OpenSSL 1.1.0のベンチマーク続いて、ベンチマークをとってみます。まずは証明書の署名・検証を見ていきます。
$ /usr/local/bin/openssl speed rsa1024 rsa2048 rsa4096 ecdsap256 ecdsap384
Doing 1024 bit private rsa's for 10s: 8591 1024 bit private RSA's in 10.00s
Doing 1024 bit public rsa's for 10s: 184207 1024 bit public RSA's in 10.00s
Doing 2048 bit private rsa's for 10s: 1313 2048 bit private RSA's in 9.99s
Doing 2048 bit public rsa's for 10s: 48633 2048 bit public RSA's in 10.00s
Doing 4096 bit private rsa's for 10s: 182 4096 bit private RSA's in 10.02s
Doing 4096 bit public rsa's for 10s: 13260 4096 bit public RSA's in 10.00s
Doing 256 bit sign ecdsa's for 10s: 56541 256 bit ECDSA signs in 9.98s
Doing 256 bit verify ecdsa's for 10s: 24701 256 bit ECDSA verify in 10.00s
Doing 384 bit sign ecdsa's for 10s: 12522 384 bit ECDSA signs in 9.99s
Doing 384 bit verify ecdsa's for 10s: 3350 384 bit ECDSA verify in 9.97s
sign verify sign/s verify/s
rsa 1024 bits 0.001164s 0.000054s 859.1 18420.7
rsa 2048 bits 0.007609s 0.000206s 131.4 4863.3
rsa 4096 bits 0.055055s 0.000754s 18.2 1326.0
sign verify sign/s verify/s
256 bit ecdsa (nistp256) 0.0002s 0.0004s 5665.4 2470.1
384 bit ecdsa (nistp384) 0.0008s 0.0030s 1253.5 336.0
以前、「暗号スイートの暗号強度と、公開鍵のビット数の設定」のベンチマークを調べた時と、比較すると、ECDSAのパフォーマンスが良くなっています。
256ビット(prime256v1)のECDSAでは、署名、検証ともに、2~3倍程度の速度となっています。384ビットのECDSAは、1割ほど速くなった感じです。 一方、RSAは、ほとんど変わらないか、署名処理が遅くなっているようにみられます。
ECDHEのベンチマークECDSAが速くなっているので、同じく楕円曲線を利用しているECDHEの鍵交換も調べてみます。 $ /usr/local/bin/openssl speed ecdhp256 ecdhp384 ecdhp521 Doing 256 bit ecdh's for 10s: 32199 256-bit ECDH ops in 10.00s Doing 384 bit ecdh's for 10s: 4022 384-bit ECDH ops in 10.00s Doing 521 bit ecdh's for 10s: 1867 521-bit ECDH ops in 10.00s op op/s 256 bit ecdh (nistp256) 0.0003s 3219.9 384 bit ecdh (nistp384) 0.0025s 402.2 521 bit ecdh (nistp521) 0.0054s 186.7 こちらも速くなっていそうです!以前の結果と比べると、
特にECDHの256bit(prime256v1)が4倍速くなっています。384ビットと521ビットのECDHも1割ほど早くなっています。 ここ1年で、楕円曲線(特にprime256v1)の処理が格段に改善されているようです。
OpenSSL1.1.0には、X25519と呼ばれるセキュリティービット数が128(実際のビット数は、253ビット)の楕円曲線も追加されていますが、こちらはベンチマークに対応していないようです。 正直、prime256v1がここまで速くなると差別化できるのか心配です。
AESのベンチマーク念のため、AESについても見てみます。 $ /usr/local/bin/openssl speed aes-128-cbc aes-256-cbc Doing aes-128 cbc for 3s on 16 size blocks: 14242159 aes-128 cbc's in 2.99s Doing aes-128 cbc for 3s on 64 size blocks: 3950008 aes-128 cbc's in 3.00s Doing aes-128 cbc for 3s on 256 size blocks: 987123 aes-128 cbc's in 3.00s Doing aes-128 cbc for 3s on 1024 size blocks: 256092 aes-128 cbc's in 3.00s Doing aes-128 cbc for 3s on 8192 size blocks: 32003 aes-128 cbc's in 3.00s Doing aes-128 cbc for 3s on 16384 size blocks: 16057 aes-128 cbc's in 3.00s Doing aes-256 cbc for 3s on 16 size blocks: 10123252 aes-256 cbc's in 3.00s Doing aes-256 cbc for 3s on 64 size blocks: 2844410 aes-256 cbc's in 3.00s Doing aes-256 cbc for 3s on 256 size blocks: 716655 aes-256 cbc's in 3.00s Doing aes-256 cbc for 3s on 1024 size blocks: 179363 aes-256 cbc's in 3.00s Doing aes-256 cbc for 3s on 8192 size blocks: 22879 aes-256 cbc's in 3.00s Doing aes-256 cbc for 3s on 16384 size blocks: 11012 aes-256 cbc's in 3.00s The 'numbers' are in 1000s of bytes per second processed. type 16 bytes 64 bytes 256 bytes 1024 bytes 8192 bytes 16384 bytes aes-128 cbc 76212.22k 84266.84k 84234.50k 87412.74k 87389.53k 87692.63k aes-256 cbc 53990.68k 60680.75k 61154.56k 61222.57k 62474.92k 60140.20k こちらはRSAと同様に、微妙にパフォーマンスが落ちていますが、誤差の範囲と要ったところでしょうか。 続いて、この数値から、Webサーバにおいて使用する暗号スイートのパフォーマンスを見てみます。
暗号スイートのパフォーマンスさて、これまでの結果をまとめると以下の表の通りとなります。
ここまでECDSAとECDHEのパフォーマンスが上がってくると、ECDSA+ECDHEの組み合わせ以外は、サーバから見ると足かせのように見えてきます。 特に、サーバ側の演算処理が、0..5msで終わるというのは、もはやTLS接続が重いという時代が終わりかけてきている印象です。
Apacheの設定方法(httpd 2.4.26以降)ということで最後に、サーバにもクライアントにも優しい、256bitのECDHE鍵交換を行い、AES128もしくは、CHACHA20による共通鍵暗号を使用する、Apacheの設定を載せます。 この設定は、Apache httpd 2.4.26以降のバージョンで利用できます。
CHACHA20は、OpenSSL1.1.0から利用可能になった新しい暗号方式になります。 CHACHA20は、スマートフォンやタブレットなど、ARMアーキテクチャのCPUにおいて、AES暗号よりも、処理速度が期待できる共通鍵暗号です。 パソコンのCPUには、AES暗号用の機能が付いているので、AES128の方が速いですが、スマートフォンに搭載されているCPUにはAES暗号用の機能が無いため、CHACHA20のほうが速くなります。 CHACHA20では、メッセージ署名には、POLY1305と呼ばれる方式を使います。 この組み合わせは、CHACHA20-POLY1305と呼ばれるています。ちょうど、AES128-GCM-SHA256といった部分に相当します。
CHACHA20-POLY1305は、鍵交換としてECDHEとDHEが利用可能です。証明書はECDSAとRSAが利用できます。 DHEは、速度的に不利になる可能性が高いため、今回の設定からは外しています。 特にスマートフォンのブラウザは、積極的にCHACHA20-POLY1305を選択するようですが、サーバ側はたいていAES暗号用の機能を持っているので、サーバ負荷を考えるとAES優先で良いと思います。
ECDSAのみを使う場合比較的古いSafari7以前、と、Chrome49以前、Android4.3以前からのアクセスを気にしなくても良い場合、証明書はECDSAだけを使います。 証明書は、Let's EncryptからECDSAの256ビットのものを取得してください。 まず、暗号スイートは、ECDHE-ECDSA-AES128-GCM-SHA256とECDHE-ECDSA-CHACHA20-POLY1305とECDHE-ECDSA-AES128-SHA256の3つにします。 /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-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-SHA256:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK …(省略)… 続いて、鍵交換に使うECDHEのビット数は256ビットのものを設定します。 /usr/local/apache2/conf/extra/httpd-ssl.confの一部
…(省略)… #SSLOpenSSLConfCmd ECDHParameters Automatic SSLOpenSSLConfCmd ECDHParameters prime256v1 SSLOpenSSLConfCmd Curves prime256v1 …(省略)… これで、256ビットのECDHE-ECDSAだけが利用されます。 この設定では、Safari7以前、と、Chrome49以前、Android4.3以前(と、ガラケー)からのアクセスができなくなります。 どうしても、Safari7以前、と、Chrome49以前、Android4.3以前を救いたい場合は、以下の様に設定してください。
ECDSAとRSAを使う場合Safari7以前、Chrome49以前、Android4.3以前を救いたい場合は、以下の様にRSAを含む暗号スイートを設定してください。 つまり、ECDHE-RSA-AES128-GCM-SHA256とECDHE-RSA-CHACHA20-POLY1305とECDHE-RSA-AES128-SHA256を追加します。 この場合、先ほどのECDSAの証明書に加えて、Let's EncryptからRSAの証明書も取得して、複数の証明書を設定してください。 /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-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-SHA256:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK …(省略)… 続いて、鍵交換に使うECDHEのビット数は、さきほどと同じく256ビットのものを設定します。 /usr/local/apache2/conf/extra/httpd-ssl.confの一部
…(省略)… #SSLOpenSSLConfCmd ECDHParameters Automatic SSLOpenSSLConfCmd ECDHParameters prime256v1 SSLOpenSSLConfCmd Curves prime256v1 …(省略)… これで、クライアント側がECDHE-ECDSAを選べばサーバ側の演算は0.5[ms]で終わりますので、非暗号のHTTPと遜色ない速度で、HTTTPS(特にHTTP/2)が繋がるようになったと思います。 実際にはクライアント側は、ECDSAが使える機種でも、クライアント側の演算負荷が低いRSAを選択してくることもあるので、必要に応じて、ECDSAのみをご検討ください。
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||