在 Nginx 上測試 SSL 性能
我正在使用庫存 OpenSSL 在 CentOS 6 x86_64 上執行 nginx 1.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
所以性能提升是顯著的。我發現關於過時的 openssl 程序集的文章,Simon 在沒有 ASM 的情況下測試了用於 AES 的 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 引擎來查看差異。並且使用英特爾的 IPP需要修補 openssl 的技能。
所以我的問題是:
測試 nginx 是否對 AES-256 使用 EVP 或者是否值得在沒有 asm 的情況下針對 openssl 編譯 nginx 的正確方法是什麼?
我知道每個新連接都需要 RSA 解密來交換密鑰,所以這是應該考慮的瓶頸,但是ssl_session_cache 共享多少會影響 SSL 會話重用,並且像 ab、siege 或類似的工具可以模擬真實流量 ssl 流量?
我調查的內容可能對您有所幫助。英特爾有一篇文章: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。