Сообщение об ошибке
SSL routines:tls_post_process_client_hello:no shared cipher
Также выводится как
- SSL_do_handshake() failed (SSL: error:0A0000C1:SSL routines::no shared cipher)
- error:0A0000C1:SSL routines::no shared cipher
openssl s_server (OpenSSL 3.x) записывает в журнал «error:0A0000C1:SSL routines:tls_post_process_client_hello:no shared cipher:<source>»; nginx пишет «SSL_do_handshake() failed (SSL: error:0A0000C1:SSL routines::no shared cipher) while SSL handshaking» с уровнем info, поэтому при уровне error_log по умолчанию этой строки не видно. OpenSSL 1.1.1 использовал код 1417A0C1.
OpenSSL (server side: nginx, Apache, Postfix, openssl s_server) — SSL_R_NO_SHARED_CIPHER
Что это означает
Так неудачное рукопожатие выглядит со стороны сервера: среди наборов шифров в ClientHello клиента нет ни одного, который был бы включён на сервере и при этом подходил бы к ключу его сертификата. Затем сервер отправляет клиенту handshake_failure (оповещение 40). Эта ошибка появляется в журналах сервера, а не в выводе клиента.
Почему это происходит
Список шифров не подходит к типу ключа сертификата
частоЕсли на сервере с сертификатом ECDSA включены только наборы ECDHE-RSA-* (или на сервере с сертификатом RSA — только ECDHE-ECDSA-*), для TLS 1.2 не остаётся ни одного пригодного набора, и рукопожатие не проходит ни у одного клиента TLS 1.2.
Урезанный вручную список шифров отсекает реальные клиенты
частоСписки, сокращённые до одного-двух наборов или только до CHACHA20, отсекают клиенты (и инструменты мониторинга), которые предпочитают другие современные наборы.
Очень старые клиенты
иногдаКлиенты, которые поддерживают только наборы шифров с обменом ключами RSA, с CBC или с 3DES (старая Java, встраиваемые устройства), не могут подключиться к серверу с современной конфигурацией; решите осознанно, нужно ли их поддерживать.
Как исправить
- 1.
Сверьте ключ сертификата с наборами шифров
Наборам ECDHE-ECDSA-* нужен сертификат ECDSA, наборам ECDHE-RSA-* — сертификат RSA; серверы с обоими сертификатами могут указывать оба семейства.
bash # ECDSA key + only ECDHE-RSA suites (or the reverse) leaves nothing usable openssl x509 -in server.pem -noout -text | grep 'Public Key Algorithm' openssl ciphers -v 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256' - 2.
Перечислите наборы шифров, которые сервер действительно принимает
Получите их список, подключаясь снаружи, и сравните с возможностями клиентов, которые вам нужно поддерживать.
bash # Which TLS 1.2 suites does the server accept? (nmap needed) nmap --script ssl-enum-ciphers -p 443 api.example.com - 3.
Используйте проверенный список наборов шифров
Возьмите за основу сгенерированную современную или промежуточную конфигурацию, а не урезайте списки вручную.
text # nginx: suites for both RSA and ECDSA certificates, TLS 1.3 enabled ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;