web-dev-qa-db-ja.com

NginxでのSSLパフォーマンスのテスト

CentOS 6x86_64でストックOpenSSLを使用してnginx1.0.0を実行しています。以下は、opensslベンチマークの結果です。

sh# openssl speed aes-256-cbc
OpenSSL 1.0.0-fips 29 Mar 2010
built on: Sat Jun 25 04:58:15 BST 2011
options:bn(64,64) md2(int) rc4(1x,char) des(idx,cisc,16,int) aes(partial) blowfish(idx) 
compiler: gcc -fPIC -DOPENSSL_PIC -DZLIB -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN 
-DHAVE_DLFCN_H -DKRB5_MIT -m64 -DL_ENDIAN -DTERMIO -Wall -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 
-fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic -Wa,--noexecstack 
-DMD32_REG_T=int -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM 
-DMD5_ASM -DAES_ASM -DWHIRLPOOL_ASM
type             16 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
aes-256 cbc      51869.80k    54173.06k    54835.11k    54890.84k    55206.96k

AES-NIエンジンが有効になっています(Xeon E5620 @ 2.40GHz x 2を使用しています):

sh# openssl engine -t
(aesni) Intel AES-NI engine
     [ available ]

また、openssl speed -engine aesni aes-256-cbcを使用しても同じ結果が得られます

しかし、EVPを使用する場合:

sh# openssl speed -evp aes-256-cbc
type             16 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
aes-256-cbc     403447.23k   420048.47k   424418.65k   425523.88k   426726.49k

したがって、パフォーマンスの向上は重要です。 outmoded openssl Assembly に関する記事を見つけました。ここで、SimonはAES用のASMなしでopensslをテストしました。

[openssl-1.0.0d]# OPENSSL_CONF=apps/openssl.cnf util/opensslwrap.sh speed aes-256-cbc
OpenSSL 1.0.0d 8 Feb 2011
options:bn(64,64) rc4(1x,char) des(idx,cisc,16,int) aes(partial) idea(int) blowfish(idx) 
compiler: gcc -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H 
-m64 -DL_ENDIAN -DTERMIO -O3 -Wall -DMD32_REG_T=int -DOPENSSL_IA32_SSE2 
-DOPENSSL_BN_ASM_MONT -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DWHIRLPOOL_ASM
type             16 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
aes-256 cbc     107854.91k   111229.18k   112361.56k   112501.08k   112536.23k

違いを確認するために、1.0.0dでaesniエンジンを構築することはまだできていません。そして IntelのIPPを使用 opensslにパッチを適用するためのスキルが必要です。

だから私の質問は:

NginxがAES-256のEVPを使用しているかどうかをテストする適切な方法は何ですか、またはAESのasmなしでopensslに対してnginxをコンパイルする価値がありますか?

新しい接続ごとに秘密鍵を交換するためにRSA復号化が必要になることを知っているので、考慮すべきボトルネックですが、どれだけssl_session_cacheが共有されますか SSLセッションの再利用に影響し、ab、siegeなどのツールで実際のトラフィックsslトラフィックをシミュレートできますか?

2
bas

私が調査したことはあなたに役立つかもしれません。インテルからの記事があります: https://software.intel.com/sites/default/files/open-ssl-performance-paper.pdf

彼らはApacheを使用してテストし、Apacheの構成を調整しなかったと述べました。 Nginxについても同じだと思います。

私はgdbを使用してトレースバックし、これが私の結果です:

(gdb) bt
#0  0x00000000004dcd50 in aesni_init_key ()
#1  0x00000000004d8dff in EVP_CipherInit_ex ()
#2  0x0000000000494c5a in ssl3_send_newsession_ticket ()
#3  0x00000000004997e8 in ssl3_accept ()
#4  0x00000000004281af in ngx_ssl_handshake (c=0x7ffff7fad1c0) at src/event/ngx_event_openssl.c:996
#5  0x0000000000428571 in ngx_ssl_handshake_handler (ev=0x8c3770) at src/event/ngx_event_openssl.c:1144
#6  0x0000000000424467 in ngx_epoll_process_events (cycle=0x89b9d0, timer=<value optimized out>, flags=<value optimized out>)
    at src/event/modules/ngx_epoll_module.c:691
#7  0x000000000041bd43 in ngx_process_events_and_timers (cycle=0x89b9d0) at src/event/ngx_event.c:248
#8  0x0000000000421de8 in ngx_single_process_cycle (cycle=0x89b9d0) at src/os/unix/ngx_process_cycle.c:315
#9  0x000000000040519c in main (argc=<value optimized out>, argv=<value optimized out>) at src/core/nginx.c:404

EVP_CipherInit_exは、ctx-> cipher-> init(ctx、key、iv、enc)を使用してaesni_init_key()を開始します。 openssl/crypto/evp /e_aes.cで定義されている詳細

 #define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \
static const EVP_CIPHER aesni_##keylen##_##mode = { \
    nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \
    flags|EVP_CIPH_##MODE##_MODE,   \
    aesni_init_key,         \
    aesni_##mode##_cipher,      \
    NULL,               \
    sizeof(EVP_AES_KEY),        \
    NULL,NULL,NULL,NULL }; \
static const EVP_CIPHER aes_##keylen##_##mode = { \
    nid##_##keylen##_##nmode,blocksize, \
    keylen/8,ivlen, \
    flags|EVP_CIPH_##MODE##_MODE,   \
    aes_init_key,           \
    aes_##mode##_cipher,        \
    NULL,               \
    sizeof(EVP_AES_KEY),        \
    NULL,NULL,NULL,NULL }; \
const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
{ return AESNI_CAPABLE?&aesni_##keylen##_##mode:&aes_##keylen##_##mode; }

AESNI_CAPABLEは、aes_init_keyまたはaes_init_keyのどの関数を有効にするかを決定します。これはコンパイル時に完了します。あなたが見つけることができるさらなる詳細 ここ

Openssl evpインターフェースでAESNIが有効になっている場合、Nginxもそれを使用します。したがって、あなたの場合、nginxはデフォルトでAESNIを使用していると思います。

1
Saberin Lin

あなたのEVPの質問に対する答えはありませんが、SSLセッションのキャッシュに関する限り、答えは「かなり役に立ちます」です。最近、memcachedを使用してクラスター間でSSLセッションキャッシングを実装するためのnginxのパッチを作成しましたが、SSLセッションキャッシングにはかなりの利点があることがわかりました。これにより、数回のラウンドトリップを節約できます(これは、ユーザーの視点では、ページが高速になるため)、CPU使用率が適度に向上します(ただし、最近のサーバーがCPUにバインドされていることはまれであるため、通常は問題になりません)。

SSLセッションキャッシュを使用していることのテストは簡単です。

gnutls-cli -V -r HOSTNAME |grep 'Session ID'

ただし、「実際のトラフィック」が非常に複雑であるという理由だけで、「実際のトラフィック」にどの程度の影響があるかをテストすることは非常に困難です。構成変更のリスクがいかに低いかを考えると、(改善したいものに基づいて)いくつかの適切な統計を収集し、本番環境でオンにして、メトリックが改善するかどうかを再度測定することをお勧めします。

2
womble