У меня возникла странная проблема. Похоже, что инструмент «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}
Возможно, проблема с SNI (ваш клиент Python может использовать его, в зависимости от того, что поддерживается), попробуйте 's_client' с опцией' -servername'. Это также может быть проблема с версией SSL/TLS, попробуйте 's_client' с' -ssl3', '-tls1',' -no_ssl3', '-no_tls1', ... – Bruno
Мой AppEngine настроен для SNI, да. Это хорошее предложение, но, похоже, мне ничего не говорят. Хотя -ssl1, -ssl2 указаны в справочной системе, в нем говорится, что они являются недопустимыми параметрами. Передача -tls1, -tls1_1 и -tls1_2 не имеет значения. Я бы согласился с тем, что AppEngine ожидает версию SSL, которую я не могу предоставить теоретически, за исключением того, что я сомневаюсь, что могу поддерживать только версии, которых нет в Google. –
Разница, скорее всего, будет находиться между '-ssl3' и' tls1'. 'openssl s_client -connect www.abc.com:443 -servername www.abc.com -tls1' должен иметь значение. – Bruno