Назад | Перейти на главную страницу

Тестирование производительности SSL на Nginx

Я запускаю nginx 1.0.0 на CentOS 6 x86_64 со стандартным OpenSSL. Ниже приведены результаты тестирования 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,40 ГГц x 2):

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

И я также получаю тот же результат, используя скорость openssl -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 где Саймон тестировал openssl без ASM для 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

Мне до сих пор не удалось собрать движок aesni на 1.0.0d, чтобы увидеть разницу. И с использованием Intel IPP требуются навыки для исправления openssl.

Итак, мои вопросы:

Как правильно проверить, использует ли nginx EVP для AES-256 или стоит ли компилировать nginx против openssl без asm для AES?

Я знаю, что каждое новое соединение потребует расшифровки RSA для обмена секретным ключом, так что это узкое место, которое следует принять во внимание, но сколько ssl_session_cache общий влияет на повторное использование сеанса SSL и могут ли такие инструменты, как ab, siege или аналогичные, имитировать реальный трафик ssl-трафика?

У меня нет ответа на ваш вопрос о EVP, но что касается кеширования сеансов SSL, ответ - «это значительно помогает». Недавно я написал патч для nginx для реализации кэширования сеансов SSL между кластерами с использованием memcached, и я обнаружил, что кеширование сеансов SSL дает значительные преимущества - вы экономите себе несколько циклов (что является важным из точки зрения пользователя, потому что они быстрее загружают свои страницы), а также умеренное улучшение использования ЦП (хотя современные серверы редко связаны с ЦП, поэтому обычно это не проблема).

Проверить, что вы используете кеширование сеанса SSL, просто:

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

Но провести тестирование, чтобы увидеть, насколько это влияет на «реальный трафик», очень сложно просто потому, что «реальный трафик» настолько сложен. Учитывая, насколько низок риск изменения конфигурации, я бы рекомендовал собрать некоторую хорошую статистику (на основе того, что вы хотите улучшить), затем включить ее в производственной среде и снова измерить, чтобы увидеть, улучшатся ли ваши показатели.

То, что я исследовал, может быть вам полезно. Есть статья из интел: 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.