Python FTP_TLS连接出现SSLv3握手失败问题求助
解决ftplib中[SSL: SSLV3_ALERT_HANDSHAKE_FAILURE]握手失败问题
在Python应用中使用ftplib获取文件时,反复遇到[SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:1007)错误。已根据openssl s_client检测结果配置TLSv1.2协议和AES256-GCM-SHA384密码套件,但问题仍未解决。运行环境为Docker容器python:3.10.13-bookworm,OpenSSL版本为3.0.11 19 Sep 2023。
原代码
host = 'ftp.appareldownload.com' ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2) ssl_context.set_ciphers("AES256-GCM-SHA384") ssl_context.set_alpn_protocols(["http/1.1"]) ftp = FTP_TLS() ftp.ssl_context = ssl_context ftp.connect(host) ftp.login(user=user, passwd=passwd) download_file(ftp, filename) ftp.quit()
错误栈
Attaching to my_python_app-1 my_python_app-1 | /app/main.py:29: DeprecationWarning: ssl.PROTOCOL_TLSv1_2 is deprecated my_python_app-1 | ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2) my_python_app-1 | *get* '220 ftp7.broderbros.com X2 WS_FTP Server 7.7(41376683)\n' my_python_app-1 | *resp* '220 ftp7.broderbros.com X2 WS_FTP Server 7.7(41376683)' my_python_app-1 | *cmd* 'AUTH TLS' my_python_app-1 | *put* 'AUTH TLS\r\n' my_python_app-1 | *get* '234 SSL enabled and waiting for negotiation\n' my_python_app-1 | *resp* '234 SSL enabled and waiting for negotiation' my_python_app-1 | Traceback (most recent call last): my_python_app-1 | File "/app/main.py", line 45, in <module> my_python_app-1 | testone().download_alpha('AllDBDiscoALP_4.txt') my_python_app-1 | File "/app/main.py", line 37, in download_alpha my_python_app-1 | ftp.login(user=user, passwd=passwd) my_python_app-1 | File "/usr/local/lib/python3.10/ftplib.py", line 745, in login my_python_app-1 | self.auth() my_python_app-1 | File "/usr/local/lib/python3.10/ftplib.py", line 756, in auth my_python_app-1 | self.sock = self.context.wrap_socket(self.sock, server_hostname=self.host) my_python_app-1 | File "/usr/local/lib/python3.10/ssl.py", line 513, in wrap_socket my_python_app-1 | return self.sslsocket_class._create( my_python_app-1 | File "/usr/local/lib/python3.10/ssl.py", line 1104, in _create my_python_app-1 | self.do_handshake() my_python_app-1 | File "/usr/local/lib/python3.10/ssl.py", line 1375, in do_handshake my_python_app-1 | self._sslobj.do_handshake() my_python_app-1 | ssl.SSLError: [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:1007)
问题分析与解决方案
核心问题点
- 过时的协议指定方式:
ssl.PROTOCOL_TLSv1_2已被弃用,硬指定单一协议版本可能导致协商不兼容 - 错误的ALPN设置:FTP协议不需要设置
http/1.1的ALPN协议,这会干扰握手过程 - 密码套件匹配问题:手动指定的套件可能与服务器实际支持的不匹配,OpenSSL 3.0的套件命名规则也可能存在差异
修正后的代码
import ssl from ftplib import FTP_TLS host = 'ftp.appareldownload.com' user = '你的用户名' passwd = '你的密码' # 使用TLS客户端上下文,自动协商兼容的协议版本 ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) # 若必须限制为TLSv1.2,用以下两行替代硬指定PROTOCOL_TLSv1_2 ssl_context.min_version = ssl.TLSVersion.TLSv1_2 ssl_context.max_version = ssl.TLSVersion.TLSv1_2 # 可选:若确认服务器支持AES256-GCM-SHA384则保留,否则注释掉让系统自动选择 # ssl_context.set_ciphers("AES256-GCM-SHA384") ftp = FTP_TLS() ftp.ssl_context = ssl_context ftp.connect(host) ftp.login(user=user, passwd=passwd) # download_file(ftp, filename) ftp.quit()
额外排查步骤
- 验证服务器支持的协议和套件:在容器内执行命令
openssl s_client -connect ftp.appareldownload.com:21 -starttls ftp -tls1_2,查看返回的Cipher Suite和协议信息,确认配置的套件是否匹配 - 补充CA证书:Docker容器可能缺少完整的CA证书,执行
apt-get update && apt-get install -y ca-certificates安装证书包 - 检查SNI支持:当前代码中
wrap_socket已通过server_hostname=self.host自动处理SNI,无需额外配置
内容的提问来源于stack exchange,提问作者nogenr3
相关产品推荐
相关产品推荐

