使用Python ftplib连接含未信任证书的FTPS服务器时出现OSError: [Errno 0] Error问题求助
I’ve run into this exact issue before—bypassing certificate verification for FTPS in Python’s ftplib requires a bit more than just using _create_unverified_context. Let’s break down the solution step by step.
The Root Cause
Your original error stems from two key issues:
- Even when using
_create_unverified_context, the SSL context might still enforce hostname validation (sincecheck_hostnamedefaults toTrue), causing handshake failures. - You likely didn’t switch the data connection to TLS mode after login—commands like
dir()rely on this secure data channel, and skipping it leads to theOSErroryou’re seeing.
Working Solution
Here’s the corrected code that properly disables certificate checks and ensures the data connection uses TLS:
import ftplib import ssl # Create a custom SSL context that skips all certificate validation ctx = ssl.create_default_context() ctx.check_hostname = False ctx.verify_mode = ssl.CERT_NONE # Initialize FTP_TLS with our custom context ftp = ftplib.FTP_TLS(context=ctx) ftp.connect("your-hostname", 21) # Replace with your server's host and port ftp.login("your-username", "your-password") # Critical: Switch the data connection to TLS mode ftp.prot_p() # Now you can run dir() without certificate errors ftp.dir()
Alternative Approach (Modifying Default Context)
If you prefer not to create a separate context, you can modify the default context of the FTP_TLS instance directly:
import ftplib import ssl ftp = ftplib.FTP_TLS() # Disable certificate verification on the default context ftp.context.check_hostname = False ftp.context.verify_mode = ssl.CERT_NONE ftp.connect("your-hostname", 21) ftp.login("your-username", "your-password") ftp.prot_p() ftp.dir()
Why Your Previous Attempts Failed
- Using
_create_unverified_contextalone wasn’t enough becausecheck_hostnameremained enabled, triggering hostname validation even when certificate checks were turned off. - Forgetting
prot_p()meant the data connection (used fordir(), file transfers, etc.) wasn’t encrypted, leading the server to reject the unsecure connection during handshake.
Important Security Note
Disabling certificate verification should only be done for trusted internal servers or testing environments—this bypasses critical security checks that protect against man-in-the-middle attacks.
内容的提问来源于stack exchange,提问作者trivelt

