2013-10-02 2 views
1

У меня возникла странная проблема. Похоже, что инструмент «s_client» от OpenSSL не нравится моему SSL-сертификату приложения AppEngine, даже если он не признает его («отсутствует сертификат одноранговой сети»), но модуль SSL Python сообщает об эмитенте, диапазоне дат, серийном номере, объектах , и т. д., как будто проблем не было вообще.OpenSSL s_client и модуль SSL Python не согласны с сертификатом имени хоста

Я бы предположил, что с моим сертификатом SSL существует некоторая неправильная конфигурация, но поскольку AppEngine предоставляет очень простой мастер для загрузки сертификатов, говоря, что есть некорректная конфигурация, можно сказать, что функциональность Google нарушена ... Я сомневаюсь в этом.

Мне хотелось бы получить некоторое представление об этом, если кто-то испытал это.

s_client:

openssl s_client -connect www.abc.com:443 

выход s_client:

CONNECTED(00000003) 
3073997000: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 225 bytes 
--- 
New, (NONE), Cipher is (NONE) 
Secure Renegotiation IS NOT supported 
Compression: NONE 
Expansion: NONE 
--- 

Python 3.3 тестовый скрипт:

import socket 

from ssl import wrap_socket, CERT_NONE, PROTOCOL_SSLv23 
from ssl import SSLContext # Modern SSL? 
from ssl import HAS_SNI # Has SNI? 

from pprint import pprint 

# Stole this from "requests" package. 
def ssl_wrap_socket(sock, keyfile=None, certfile=None, cert_reqs=None, 
        ca_certs=None, server_hostname=None, 
        ssl_version=None): 

    context = SSLContext(ssl_version) 
    context.verify_mode = cert_reqs 

    if ca_certs: 
     try: 
      context.load_verify_locations(ca_certs) 
     # Py32 raises IOError 
     # Py33 raises FileNotFoundError 
     except Exception as e: # Reraise as SSLError 
      raise SSLError(e) 

    if certfile: 
     # FIXME: This block needs a test. 
     context.load_cert_chain(certfile, keyfile) 

    if HAS_SNI: # Platform-specific: OpenSSL with enabled SNI 
     return context.wrap_socket(sock, server_hostname=server_hostname) 

    return context.wrap_socket(sock) 

hostname = 'www.abc.com' 
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
s.connect((hostname, 443)) 

sslSocket = ssl_wrap_socket(s, 
          ssl_version=2, 
          cert_reqs=2, 
          ca_certs='/usr/local/lib/python3.3/dist-packages/requests/cacert.pem', 
          server_hostname=hostname) 

pprint(sslSocket.getpeercert()) 
s.close() 

Тест вывода сценария:

{'issuer': ((('countryName', 'US'),), 
      (('organizationName', 'GeoTrust, Inc.'),), 
      (('commonName', 'RapidSSL CA'),)), 
'notAfter': 'Oct 2 20:01:20 2014 GMT', 
'notBefore': 'Sep 29 02:17:38 2013 GMT', 
'serialNumber': '0E45AF', 
'subject': ((('serialNumber', 'd3tVuFeMunyn/gFFucMFHgZ2iBihdthR'),), 
      (('organizationalUnitName', 'GT22884059'),), 
      (('organizationalUnitName', 
       'See www.rapidssl.com/resources/cps (c)13'),), 
      (('organizationalUnitName', 
       'Domain Control Validated - RapidSSL(R)'),), 
      (('commonName', 'www.abc.com'),)), 
'subjectAltName': (('DNS', 'www.abc.com'), 
        ('DNS', 'abc.com')), 
'version': 3} 
+0

Возможно, проблема с SNI (ваш клиент Python может использовать его, в зависимости от того, что поддерживается), попробуйте 's_client' с опцией' -servername'. Это также может быть проблема с версией SSL/TLS, попробуйте 's_client' с' -ssl3', '-tls1',' -no_ssl3', '-no_tls1', ... – Bruno

+0

Мой AppEngine настроен для SNI, да. Это хорошее предложение, но, похоже, мне ничего не говорят. Хотя -ssl1, -ssl2 указаны в справочной системе, в нем говорится, что они являются недопустимыми параметрами. Передача -tls1, -tls1_1 и -tls1_2 не имеет значения. Я бы согласился с тем, что AppEngine ожидает версию SSL, которую я не могу предоставить теоретически, за исключением того, что я сомневаюсь, что могу поддерживать только версии, которых нет в Google. –

+1

Разница, скорее всего, будет находиться между '-ssl3' и' tls1'. 'openssl s_client -connect www.abc.com:443 -servername www.abc.com -tls1' должен иметь значение. – Bruno

ответ

1

Проблема заключалась в том, что я не включал параметр «имя_сервера» в мой вызов «s_client».

Смежные вопросы