CPython 3.14 imaplib 通过 SOCKS 使用已验证的 TLS
在不全局替换套接字、也不丢失邮件服务器 TLS 身份的前提下,让 CPython 3.14 的 IMAP SSL 连接经 SOCKS 转发。
IMAP SSL 连接可以经 SOCKS 转发,同时让邮件服务器保持为其 TLS 对端。有用的集成点在于客户端创建传输层的位置,即常规 IMAP 问候与能力处理开始之前。
对 CPython 3.14 而言,下面演示一个使用 PySocks 的小型适配器。它覆盖了私有的传输钩子,因此请让它与所维护的 imaplib 版本绑定:
import imaplib
import ssl
import socks
class SocksIMAP4SSL(imaplib.IMAP4_SSL):
def _create_socket(self, timeout):
stream = socks.create_connection(
(self.host, self.port),
timeout=timeout,
proxy_type=socks.SOCKS5,
proxy_addr="proxy.example",
proxy_port=1080,
proxy_rdns=True,
)
try:
return self.ssl_context.wrap_socket(
stream, server_hostname=self.host)
except Exception:
stream.close()
raise
context = ssl.create_default_context()
with SocksIMAP4SSL("imap.example", ssl_context=context,
timeout=15) as mailbox:
mailbox.noop()其中的名称与端口只是占位符,代表已经可用的代理和 IMAP 服务。对于获准使用公共代理的公共 IMAP 目标,SOCKS5 代理列表提供了候选;每个候选都必须允许所需的邮件主机与端口。PySocks 依赖负责 SOCKS 协商;imaplib 仍然负责初始化邮件会话。这里不涉及对 socket.socket 的任何全局替换。
保留邮件服务器的身份
TLS 主机名仍是 imap.example。它不是 SOCKS 主机名。传入 ssl.create_default_context() 会有意启用常规的证书与主机名校验;仅有一个加密套接字并不足以确立这些校验。
proxy_rdns=True 要求由 SOCKS 路径处理目标主机名。如果代理需要账号,其支持的凭据参数属于该传输层配置。它们并不会登录到邮箱。
把会话初始化留给 imaplib
适配器把 TLS 流交回常规构造函数。照搬旧示例重新实现 open() 可能会漏掉超时参数、缓冲以及其他初始化预期。在 CPython 3.14 中,即便是旧的 file 访问方式也只是兼容性属性,而不是可以随意重建的字段。
升级库时,请依据对应的源码复核这个私有钩子。如果维护子类并不合适,就选择提供有文档的代理传输接口的邮件客户端。无论采用哪种安排,都应保持同样的分层:代理连接、目标 TLS 验证,然后是 IMAP 认证。