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 认证。

相关文章