连接aws.amazon.com出现SSLV3_ALERT_HANDSHAKE_FAILURE错误求助
连接aws.amazon.com时出现SSLV3_ALERT_HANDSHAKE_FAILURE错误的排查与解决
尝试与aws.amazon.com建立安全连接时,遇到SSLV3_ALERT_HANDSHAKE_FAILURE错误。经检测AWS服务器端无异常,且相同代码连接其他站点(如example.com)可正常运行。以下是复现代码及不同环境下的报错情况:
复现代码
import socket, ssl, sys address = ( sys.argv[1], int(sys.argv[2]) if len(sys.argv) > 2 else 443 ) print("Python %s" % sys.version) print("OpenSSL %s" % ssl.OPENSSL_VERSION) print("Address %s:%d" % address) print("-" * 80) test_socket = socket.socket() test_socket.connect(address) test_ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) test_ssl_context.check_hostname = False test_ssl_context.load_default_certs() wrapped_test_socket = test_ssl_context.wrap_socket(test_socket) print("No exceptions!")
连接example.com的正常输出
Anonymous@machine:~ $ python test_ssl.py example.com Python 3.11.2 (main, Sep 14 2024, 03:00:30) [GCC 12.2.0] OpenSSL OpenSSL 3.0.15 3 Sep 2024 Address example.com:443 -------------------------------------------------------------------------------- No exceptions!
连接aws.amazon.com的报错信息
Windows环境
C:\dev\mSSL>python test_ssl.py aws.amazon.com Python 3.13.0 (tags/v3.13.0:60403a5, Oct 7 2024, 09:38:07) [MSC v.1941 64 bit (AMD64)] OpenSSL OpenSSL 3.0.15 3 Sep 2024 Address aws.amazon.com:443 -------------------------------------------------------------------------------- Traceback (most recent call last): File "C:\dev\mSSL\test_ssl.py", line 17, in <module> wrapped_test_socket = test_ssl_context.wrap_socket(test_socket) File "ssl.py", line 455, in wrap_socket File "ssl.py", line 1076, in _create File "ssl.py", line 1372, in do_handshake ssl.SSLError: [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:1020)
Linux环境
Anonymous@machine:~ $ python test_ssl.py aws.amazon.com Python 3.11.2 (main, Sep 14 2024, 03:00:30) [GCC 12.2.0] OpenSSL OpenSSL 3.0.15 3 Sep 2024 Address aws.amazon.com:443 -------------------------------------------------------------------------------- Traceback (most recent call last): File "/home/Anonymous/test_ssl.py", line 17, in <module> wrapped_test_socket = test_ssl_context.wrap_socket(test_socket) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.11/ssl.py", line 517, in wrap_socket return self.sslsocket_class._create( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.11/ssl.py", line 1108, in _create self.do_handshake() File "/usr/lib/python3.11/ssl.py", line 1379, in do_handshake self._sslobj.do_handshake() ssl.SSLError: [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:992)
问题原因及解决方法
核心原因
aws.amazon.com的服务器对TLS握手要求更严格,代码存在两个关键问题:
- 未指定SNI(Server Name Indication):AWS采用虚拟主机部署,同一IP对应多个域名,SNI是服务器识别对应证书的必要条件。原代码在
wrap_socket时未传递server_hostname参数,导致服务器无法返回正确证书,握手失败。 - 禁用主机名检查:关闭
check_hostname后,缺少对证书与域名匹配性的验证,结合SNI缺失的情况,进一步导致握手过程中的身份验证逻辑失效。
解决步骤
修改代码,在wrap_socket时添加server_hostname参数,同时建议启用主机名检查(安全最佳实践):
import socket, ssl, sys address = ( sys.argv[1], int(sys.argv[2]) if len(sys.argv) > 2 else 443 ) print("Python %s" % sys.version) print("OpenSSL %s" % ssl.OPENSSL_VERSION) print("Address %s:%d" % address) print("-" * 80) test_socket = socket.socket() test_socket.connect(address) test_ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) test_ssl_context.check_hostname = True # 启用主机名检查,提升安全性 test_ssl_context.load_default_certs() # 添加server_hostname参数,指定目标域名 wrapped_test_socket = test_ssl_context.wrap_socket(test_socket, server_hostname=address[0]) print("No exceptions!")
补充说明
- SNI是现代TLS握手的标准要求,大部分多域名托管的服务器都依赖它识别正确的证书配置。
- 保持
check_hostname=True可有效防止中间人攻击,符合安全规范。若因特殊场景需临时关闭,也必须确保server_hostname参数正确传递。
内容的提问来源于stack exchange,提问作者Anonymous
相关产品推荐
相关产品推荐

