如何在Python中连接FTPS服务器并下载文件?证书相关问题咨询
Python连接FTPS服务器并下载文件的完整方案
优化后的完整代码示例
结合SSL安全配置与原代码的细节优化,提供更完善的实现:
import ftplib import os import ssl from dateutil import parser from datetime import datetime def connect(host, port, user, password, verify_cert=True, client_cert=None): # 创建自定义SSL上下文 context = ssl.create_default_context() if not verify_cert: # 测试环境可临时关闭证书验证,生产环境禁止使用此配置 context.check_hostname = False context.verify_mode = ssl.CERT_NONE if client_cert: # 若需客户端证书,传入证书与密钥文件路径组成的元组(cert_file, key_file) context.load_cert_chain(*client_cert) ftp = ftplib.FTP_TLS(context=context) ftp.debugging = 2 ftp.connect(host, port) ftp.login(user, password) # 将数据连接切换为TLS加密(默认仅控制连接加密) ftp.prot_p() return ftp def retrieveFileList(ftp, ftp_paths, fileType, destinationPath, date): total_files = [] timestamps = [] # 确保目标本地目录存在 os.makedirs(destinationPath, exist_ok=True) for path in ftp_paths: try: ftp.cwd(path) except ftplib.error_perm as e: print(f"切换远程目录失败: {e}") continue files = ftp.nlst(f'*{fileType}') for file in files: try: timestamp = ftp.voidcmd(f"MDTM {file}")[4:].strip() time = parser.parse(timestamp) parsed_time = time.strftime("%Y-%m") timestamps.append(parsed_time) if not date > parsed_time: file_local_path = os.path.join(destinationPath, file) total_files.append(file) with open(file_local_path, 'wb') as f: ftp.retrbinary(f'RETR {file}', f.write) print(f"文件下载完成: {file}") except ftplib.error_perm as e: print(f"处理文件{file}失败: {e}") continue max_timestamp = max(timestamps) if timestamps else None return total_files, max_timestamp
疑问解答
1. 是否必须验证服务器证书?
不是强制要求,但生产环境必须开启验证。默认ftplib.FTP_TLS不会验证服务器证书,这会让连接暴露在中间人攻击风险中;测试环境(如本地Docker搭建的服务器)可临时关闭,但正式场景必须开启验证以确保连接的是真实目标服务器。
2. 是否需要创建SSL上下文并传入FTP_TLS()作为参数?
如果需要自定义SSL相关规则(比如证书验证逻辑、指定TLS版本、加载客户端证书),就需要创建并传入自定义SSL上下文。默认上下文仅提供基础加密能力,无法满足精细的安全配置需求,比如代码中通过上下文控制证书验证、加载客户端证书的逻辑。
3. 是否需要客户端证书?
完全取决于FTPS服务器的配置:
- 多数Docker搭建的FTPS服务器(如
fauria/vsftpd镜像)默认仅开启账号密码验证,无需客户端证书; - 若服务器配置了双向SSL认证(要求客户端提供证书证明身份),则需要准备对应客户端证书,并通过SSL上下文加载。
内容的提问来源于stack exchange,提问作者leop
相关产品推荐
相关产品推荐

