SSL рукопожатие не работает при компиляции в Ubuntu 14

1

Это поток, который я использую для настройки моего HTTPS-сервера с помощью SSL.

Он отлично работает на Windows, OS X и Ubuntu 13. Но он не работает на Ubuntu 14, и я не знаю, почему.

Это не полный код, когда он очень большой, но при необходимости я могу получить более подробную информацию.

SSL_library_init();

m_sslContext = SSL_CTX_new( SSLv23_server_method() );

SSL_CTX_use_certificate_chain_file( m_sslContext, "path/to/certificate.crt" );
SSL_CTX_use_PrivateKey_file( m_sslContext, "path/to/privatekey.pem", SSL_FILETYPE_PEM );

m_mainSocket = ::socket( PF_INET, SOCK_STREAM, IPPROTO_TCP ) );

...

::listen( m_mainSocket, SOMAXCONN );

...

SOCKET childSocketHandle;

while ( ( childSocketHandle = ::accept( m_mainSocket, ... ) ) > 0 )
{
    sslChildSocket = SSL_new( m_sslContext );
    SSL_set_fd( sslChildSocket, childSocketHandle );
    SSL_set_accept_state( sslChildSocket );
    ...
    SSL_read( sslChildSocket, bufferIn, sizeof( bufferIn ) );
    ...
    SSL_write( sslChildSocket, bufferOut, sizeof( bufferOut ) ) );
}

Проблема в том, что когда я пытаюсь подключиться из браузера (Google Chrom), он говорит:

Невозможно сделать безопасное подключение к серверу. Это может быть проблемой с сервером или может потребоваться сертификат проверки подлинности клиента, которого у вас нет. Код ошибки: ERR_SSL_PROTOCOL_ERROR

Другие браузеры говорят похожие сообщения...

Когда я пытаюсь подключиться к wget, я получаю:

wget https://example.com:443/
--2014-05-01 17:01:33--  https://example.com:443/
Resolving example.com (example.com)... 127.0.1.1
Connecting to example.com (example.com)|127.0.1.1|:443... connected.
ERROR: cannot verify example.com certificate, issued by ‘/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certificates.godaddy.com/repository/CN=Go Daddy Secure Certification Authority/serialNumber=00000000:
  Unable to locally verify the issuer authority.
To connect to example.com insecurely, use '--no-check-certificate'.

Я просто изменил серию сертификата на 00000000.

Итак... Если я наконец последую за сообщением wget и сделаю...

wget https://example.com:443/ --no-check-certificate

... ТОГДА сервер работает отлично!

Итак, вывод, который я получаю: сам сервер работает, но у рукопожатия есть некоторые проблемы с сертификатом SSL. Сертификат действителен, используется на других серверах, Apache отлично его принимает, и, как я уже сказал, эта же реализация работает в Windows, OS X и Ubuntu 13. Эта проблема происходит только на Ubuntu 14.

Вещи, которые я пытался сделать:

  1. Я попытался обновить OpenSSL [скомпилировал его сам], но ничего
    получилось.
  2. Я пытался попробовать другие методы вместо SSLv23_server_method(), ничего не произошло
  3. Я собрал в Ubuntu 13 и выполнил в Ubuntu 14 (И ЭТО РАБОТАЕТ!)

Weard (пункт 3) заключается в том, что если я скомпилирую Ubuntu 13 и работаю на Ubuntu 14, он работает! Так может быть, какая-то статическая библиотека Ubuntu 14 с проблемой?

Является ли моя реализация SSL правильной? Что еще можно сделать, чтобы я мог исправить это для Ubuntu 14 и мой сервер работал повсюду?

-

Я делаю openssl s_client -connect example.com:443 и получаю:

CONNECTED(00000003)
140735262471008:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:s23_lib.c:177:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 322 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
---
  • 0
    Чтобы разобраться, если это какая-то вещь, связанная с ОС, или компилятор, вы можете захотеть получить ту же версию компилятора, которую использует Ubuntu 14, и использовать ее в Ubuntu 13, или что-то подобное ...
  • 0
    О, да, я забыл упомянуть об этом. Я скомпилировал в 13, запустил на 14, и это сработало ... Я обновлю вопрос!
Показать ещё 3 комментария
Теги:
openssl
ubuntu-14.04
handshake

1 ответ

1
Лучший ответ
It works perfectly on Windows, OS X and Ubuntu 13. But it failing to work on Ubuntu 14 only and I don't know why.
...
ERR_SSL_PROTOCOL_ERROR

ERR_SSL_PROTOCOL_ERROR указывает, что клиент и сервер не могут договориться о протоколе - SSLv3, TLS 1.0 и т.д. Я считаю, что это соответствует предупреждению protocol_version TLS. См. RFC 5246, раздел 7.2.

OpenSSL был TLS 1.2 с 1.0.1. См. OpenSSL CHANGELOG. Тем не менее, Ubuntu до 14 отключил TLS 1.1 и TLS 1.2 для аргументов interop. См. Ubuntu 12.04 LTS: версия DownSSL OpenSSL и не поддерживает TLS 1.2. Ubuntu 14 (и последующий) включает TLS 1.1 и TLS 1.2. (И TLS 1.3 находится за углом: Протокол безопасности транспортного уровня (TLS) версии 1.3 (draft-ietf-tls-rfc5246-bis-00)).

Могут быть другие проблемы, если вам нужно пройти через прокси-сервер. Проблема связана с размером ClientHello. Размер ClientHello увеличился с TLS 1.1 и TLS 1.2 из-за дополнительных наборов шифров (точнее, TLS 1.2, поскольку TLS 1.1 не добавлял никаких наборов шифров). Размер не должен иметь значения, за исключением того, что некоторые прокси имеют фиксированный буфер размера и другие жестко закодированные пределы, которые просто нарушают обмен. Это проблема с некоторыми устройствами F5 и Ironport.

Вы можете проверить TLS 1.2 и ClientHello чувствительности размера с s_client:

openssl s_client -tls1_2 -connect <server>:<port> -servername <server> \
    -cipher "SSL_RSA_WITH_3DES_EDE_CBC_SHA:TLS_RSA_WITH_3DES_EDE_CBC_SHA"

Вышеупомянутый подключается к TLS 1.2 и использует только 2 набора шифров (4 байта). Если он соединяется с 2 наборами шифров, затем отпустите -cipher и посмотрите, подключается ли он к 80+ (более 160 байт), которые встроены.

Если он не подключается к TLS 1.2, попробуйте либо -tls1 либо -ssl3.

РЕДАКТИРОВАТЬ: Проблема - это древний сервер и TLS 1.1 и TLS 1.2. См. Ниже шаги по изоляции проблемы.

У вас есть три возможных исправления.

Первый

Первое исправление заключается в том, чтобы обновить сервер до того, что не было древним. Если это прокси-сервер, тогда исправьте прокси-сервер.

второй

Если вам необходимо изменить версии протокола, выполните следующие действия, чтобы получить только SSLv3 или YLS 1.0:

m_sslContext = SSL_CTX_new( SSLv23_server_method() );
const long flags = SSL_OP_NO_SSLv2 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2;
SSL_CTX_set_options(m_sslContext, flags);

В третьих

Если вам нужно изменить список наборов шифров:

m_sslContext = SSL_CTX_new( SSLv23_server_method() );
const char* const PREFERRED_CIPHERS = "kEECDH:kEDH:kRSA:AESGCM:AES256:AES128:3DES:"
    "SHA256:SHA84:SHA1:!aNULL:!eNULL:HIGH:!RC4:!MD5:!SRP:!PSK:!ADH:!AECDH";
res = SSL_CTX_set_cipher_list(m_sslContext, PREFERRED_CIPHERS);

РЕДАКТИРОВАТЬ: Проблема - это древний сервер и TLS 1.1 и TLS 1.2. Вам нужно использовать (1) сверху или (2) сверху. В идеале, древний сервер будет исправлен, чтобы каждый мог воспользоваться.

TLS 1.2 не работает:

$ openssl s_client -tls1_2 -connect www.example.com:443 -CAfile gd-class2-root.crt 
CONNECTED(00000003)
140735211598300:error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number:s3_pkt.c:337:
...

TLS 1.1 не работает:

$ openssl s_client -tls1_1 -connect www.example.com:443 -CAfile gd-class2-root.crt 
CONNECTED(00000003)
140735211598300:error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number:s3_pkt.c:337:
...

TLS 1.0 работает:

$ openssl s_client -tls1 -connect www.example.com:443 -CAfile gd-class2-root.crt 
CONNECTED(00000003)
depth=2 C = US, O = "The Go Daddy Group, Inc.", OU = Go Daddy Class 2 Certification Authority
verify return:1
...

SSL v3 работает:

$ openssl s_client -ssl3 -connect www.example.com:443 -CAfile gd-class2-root.crt 
CONNECTED(00000003)
depth=2 C = US, O = "The Go Daddy Group, Inc.", OU = Go Daddy Class 2 Certification Authority
verify return:1
...

When I try to connect from wget, I get:
...
Unable to locally verify the issuer authority.
...
So... If I finally follow the wget message and do...

wget https://mydomain.com:443/ --no-check-certificate

... THEN the server works perfectly!

Это другая проблема. wget, вероятно, избегает проблемы, включив одно из исправлений выше. След Wirehsark скажет вам.

Кроме того, если вы предоставили реальное имя сервера, мы могли бы помочь вам определить корневой ЦС, который вы должны использовать (чтобы избежать невозможности Unable to locally verify the issuer authority).

Вот что я вижу с s_client:

$ openssl s_client -connect www.example.com:443
CONNECTED(00000003)
depth=1 C = US, ST = Arizona, L = Scottsdale, O = "GoDaddy.com, Inc.", OU = http://certificates.godaddy.com/repository, CN = Go Daddy Secure Certification Authority, serialNumber = 07969287
verify error:num=20:unable to get local issuer certificate
verify return:0
---
Certificate chain
 0 s:/OU=Domain Control Validated/CN=*.example.com
   i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certificates.godaddy.com/repository/CN=Go Daddy Secure Certification Authority/serialNumber=07969287
 1 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certificates.godaddy.com/repository/CN=Go Daddy Secure Certification Authority/serialNumber=07969287
   i:/C=US/O=The Go Daddy Group, Inc./OU=Go Daddy Class 2 Certification Authority
...

Таким образом, вам необходимо пройти сертификационный центр Go Daddy Class 2. Вы можете получить это из Go Daddy Repository, SSL Certificate Information. Файл gd-class2-root.crt, и вы можете передать его s_client а результат - Verify return code: 0 (ok):

$ openssl s_client -connect www.example.com:443 -CAfile gd-class2-root.crt 
CONNECTED(00000003)
depth=2 C = US, O = "The Go Daddy Group, Inc.", OU = Go Daddy Class 2 Certification Authority
verify return:1
depth=1 C = US, ST = Arizona, L = Scottsdale, O = "GoDaddy.com, Inc.", OU = http://certificates.godaddy.com/repository, CN = Go Daddy Secure Certification Authority, serialNumber = 07969287
verify return:1
depth=0 OU = Domain Control Validated, CN = *.example.com
verify return:1
---
Certificate chain
 0 s:/OU=Domain Control Validated/CN=*.example.com
   i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certificates.godaddy.com/repository/CN=Go Daddy Secure Certification Authority/serialNumber=07969287
 1 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certificates.godaddy.com/repository/CN=Go Daddy Secure Certification Authority/serialNumber=07969287
   i:/C=US/O=The Go Daddy Group, Inc./OU=Go Daddy Class 2 Certification Authority
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIFRTCCBC2gAwIBAgIHKyKXfFXVZjANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE
BhMCVVMxEDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAY
BgNVBAoTEUdvRGFkZHkuY29tLCBJbmMuMTMwMQYDVQQLEypodHRwOi8vY2VydGlm
aWNhdGVzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkxMDAuBgNVBAMTJ0dvIERhZGR5
IFNlY3VyZSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTERMA8GA1UEBRMIMDc5Njky
ODcwHhcNMTQwMzIxMTYyMjU2WhcNMTUwMzIxMTYyMjU2WjA8MSEwHwYDVQQLExhE
b21haW4gQ29udHJvbCBWYWxpZGF0ZWQxFzAVBgNVBAMMDiouc3RheWZpbG0uY29t
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyRsNuqBROD+6RsmkJk7S
KtTpFO5ke92AfWnEnZuKCbbRo/WjmtCPNLQC7fAQxPJb6i/cCt9cusQqlpFjHTg/
lD5Dqoqn/GXMe4hfKbV8VV3NAjWr8f0M/M1ftaL+zo5UtRjdAEIC9ysfbKqqBOxP
hqGPiL0QpkKQ5YZMiz3S4UZzwQ1Unjj43xH4IZFffsdwY5uJqfeoOl/6qBNAQIyg
1Hk00er/+1UlO2hpMe/qjiCZvGSRUat/O51AgyCPFGDmhSEi6rjyeLvEgpILzgR7
K1/BsCe2Kxi+SRIt8UK2jFjXSRnCQyjtgOitbk/sM0afhUUIb7ns95RWAiXt5CpD
0QIDAQABo4IBuzCCAbcwDwYDVR0TAQH/BAUwAwEBADAdBgNVHSUEFjAUBggrBgEF
BQcDAQYIKwYBBQUHAwIwDgYDVR0PAQH/BAQDAgWgMDQGA1UdHwQtMCswKaAnoCWG
I2h0dHA6Ly9jcmwuZ29kYWRkeS5jb20vZ2RzMS0xMDYuY3JsMFMGA1UdIARMMEow
SAYLYIZIAYb9bQEHFwEwOTA3BggrBgEFBQcCARYraHR0cDovL2NlcnRpZmljYXRl
cy5nb2RhZGR5LmNvbS9yZXBvc2l0b3J5LzCBgAYIKwYBBQUHAQEEdDByMCQGCCsG
AQUFBzABhhhodHRwOi8vb2NzcC5nb2RhZGR5LmNvbS8wSgYIKwYBBQUHMAKGPmh0
dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3NpdG9yeS9nZF9pbnRl
cm1lZGlhdGUuY3J0MB8GA1UdIwQYMBaAFP2sYTKTbEXW4u6FX5q653aZaMznMCcG
A1UdEQQgMB6CDiouc3RheWZpbG0uY29tggxzdGF5ZmlsbS5jb20wHQYDVR0OBBYE
FOZLbPozya++C27Grhs5pPUut4WFMA0GCSqGSIb3DQEBBQUAA4IBAQBPv85UBt3g
1XGHwZ9ARxpG9InoHRQledSbRckchU35awnIXuXd6pE+kZ7RctR6BywiPRrQnmYm
0D7wHP+BVoN2cZIkTHHgx/hILGTYk47CKyVcL9+WyDd5UXkJYyfdMzfia6dnG4wZ
ucsdR8Ete2do35yZmCZHU5L9KwXarQRuNexbiOqb4kBjUaIhN79NZs1h812QWLLB
+uRhvHOfQuSleEx1ggou/rwaYKNGYrIJl4/kpCquDXbqebkR1B+ad49GD+yBMyOm
/AOfGSU6YTUfZRGjzS2yAozs+QZFUrZTDHyt6Z93OLD+4O07SSAfTD3AlQlG/V1M
KwHuBUl22QD4
-----END CERTIFICATE-----
subject=/OU=Domain Control Validated/CN=*.example.com
issuer=/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certificates.godaddy.com/repository/CN=Go Daddy Secure Certification Authority/serialNumber=07969287
---
No client certificate CA names sent
---
SSL handshake has read 2765 bytes and written 843 bytes
---
New, TLSv1/SSLv3, Cipher is AES128-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : AES128-SHA
    Session-ID: 990D00002F519EEFC297CD4CB157B2F7...
    Session-ID-ctx: 
    Master-Key: A4B16EA84F4CD1E8D56A0B601A678AEE...
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1399002932
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)
  • 0
    Я пробовал оба решения 2 и 3 ... ничего не произошло :-(
  • 0
    SSL_CTX_set_cipher_list () для sslChildSocket, исправьте это в ответе ... Я пытался, но я исправил неправильно ...
Показать ещё 7 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню