我在CentOS 6 x86_64上运行带有OpenSSL的nginx 1.0.0。 以下是openssl基准testing的结果。
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
所以性能增益是显着的。 我find了关于过时的openssl程序集的文章,Simon在没有ASM的情况下testing了openssl for AES,数字是:
[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上build立aesni引擎来查看差异。 使用英特尔的IPP需要修补openssl的技能。
所以我的问题是:
什么是testingnginx是否使用EVP for AES-256的正确方法,或者是否值得将nginx编译为openssl而不使用asm for AES?
我知道每一个新的连接都需要RSA解密来交换密钥,这就是应该考虑的瓶颈,但是多lessssl_session_cache共享会影响SSL会话的重用,并且可能会使用ab,siege或者类似的工具来模拟真正的stream量。 ?
我所研究的内容可能对您有所帮助。 有一篇来自intel的文章: https : //software.intel.com/sites/default/files/open-ssl-performance-paper.pdf
他们使用Apache来testing,他们说他们没有调整任何configuration的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。 编译完成。 更多细节你可以在这里find。
如果你的openssl evp接口启用了AESNI,Nginx也使用它。 所以对于你的情况,我认为nginx默认使用AESNI。
对于您的EVP问题,我没有任何答案,但就SSL会话caching而言,答案是“它有相当大的帮助”。 我最近为nginx写了一个补丁,使用memcached在集群中实现SSL会话caching,我发现SSL会话caching有相当多的好处 – 你可以节省多次往返(这是来自用户的angular度,因为他们的页面更快),以及适度的CPU使用率的提高(虽然现代服务器是CPU限制,所以这通常不是一个问题)。
testing您使用SSL会话caching很容易:
gnutls-cli -V -r HOSTNAME |grep 'Session ID'
但是做testing看看它对“真实stream量”有多大影响是非常困难的,因为“真实stream量”非常复杂。 考虑到configuration改变的风险有多低,我build议收集一些好的统计数据(根据你想改进的地方),然后在生产中再次打开它,再次测量,看看你的指标是否有所改善。