为 Indy 的 SMTP 连接指定代理 IOHandler
用对应 Indy 版本的 IOHandler 属性把 SOCKS 或 HTTP CONNECT 接入 TIdSMTP,邮件与代理设置彼此独立。
在 Indy 中,把代理挂到 TIdSMTP 所使用的 IOHandler 上。让 TIdSMTP.Host 和 Port 仍然指向邮件服务。IOHandler 的代理组件提供中间服务器地址,并在同一条连接上完成代理握手。
使用哪个属性取决于 Indy 版本:Indy 9 提供 SocksInfo;Indy 10 使用 TransparentProxy。请检查应用程序中的组件库,而不是只凭 Delphi 发行版名称挑选示例。
使用 SOCKS5 的 Indy 10
假设窗体已经拥有这些组件:
Smtp: TIdSMTPMailSocket: TIdIOHandlerStackSocks: TIdSocksInfo
在打开 SMTP 连接之前把它们连接并配置好:
Smtp.Host := 'smtp.example.net';
Smtp.Port := 587;
Smtp.IOHandler := MailSocket;
Socks.Host := 'proxy.example.net';
Socks.Port := 1080;
Socks.Version := svSocks5;
MailSocket.TransparentProxy := Socks;
端口值只是示例。SMTP 端口必须与你要使用的服务和 TLS 模式相匹配。SOCKS 端口属于代理。
对于允许使用公网中间服务器的获准公网 SMTP 测试,SOCKS5 代理列表提供候选地址。确认候选地址允许实际邮件主机和端口,并使用无代理认证分支,不要保留先前代理的凭据。
TIdSocksInfo 以 svNoSocks 开头,因此仅设置代理主机名并不会启用它。请选择适当的 SOCKS 版本。如果代理要求 SOCKS5 用户名/密码认证,既要配置认证方式,也要配置凭据:
Socks.Authentication := saUsernamePassword;
Socks.Username := ProxyUser;
Socks.Password := ProxyPassword;
ProxyUser 和 ProxyPassword 表示由应用程序提供的值。这些属性用于向代理认证。请在邮件客户端中单独配置 SMTP 账户及其认证方式。
保留已有的 TLS IOHandler
使用 STARTTLS 或隐式 TLS 的邮件客户端需要其具备 SSL 能力的 IOHandler。不要为了添加代理就把该组件换成普通的 TIdIOHandlerStack。
在 Indy 10 中,SSL IOHandler 的基类派生自 TIdIOHandlerStack 并继承其代理支持。对于名为 MailTLS 的已有兼容 SSL IOHandler,连接变成:
Smtp.IOHandler := MailTLS;
MailTLS.TransparentProxy := Socks;
SMTP 组件的 UseTLS 设置仍然决定邮件服务的 TLS 模式。请在面向 smtp.example.net 的 TLS 集成中配置证书信任与主机名验证,而不是针对代理主机名。添加隧道本身并不会建立证书验证。
改用 HTTP CONNECT 代理
对于 Indy 10,请使用 TIdConnectThroughHttpProxy 组件,它由 IdConnectThroughHttpProxy 提供。假设已有一个属于窗体的、名为 HttpTunnel 的实例:
HttpTunnel.Host := 'proxy.example.net';
HttpTunnel.Port := 8080;
HttpTunnel.Enabled := True;
MailSocket.TransparentProxy := HttpTunnel;
如果 SMTP 使用 MailTLS,则改为把 HttpTunnel 赋给该处理器的 TransparentProxy。邮件目标仍留在 Smtp 上。
该组件建立 HTTP CONNECT 隧道,并通过其 Username 和 Password 属性实现 Basic 代理认证。需要其他认证机制的代理需要兼容实现;不要以为这两个属性提供所有 HTTP 认证方案。
代理还必须允许 CONNECT 到邮件服务器的实际端口。允许隧道到 443 上的 Web 服务器并不意味着允许到达 587 上的提交服务或 25 上的 SMTP 服务器。
Indy 9 的连接
Indy 9 使用 TIdIOHandlerSocket 及其 SocksInfo 属性。对于名为 Socket9 和 Socks9 的窗体组件,等效接线如下:
Smtp.IOHandler := Socket9;
Socket9.SocksInfo := Socks9;
Socks9.Host := 'proxy.example.net';
Socks9.Port := 1080;
Socks9.Version := svSocks5;
它的 SOCKS 实现支持 4、4a 和 5 版本。Indy 10 的 TransparentProxy 与 HTTP CONNECT 组件布局不能直接粘贴到这个较旧的接口中。
不需要用另一个 TCP 客户端进行单独的前置代理登录。代理认证、隧道建立和 SMTP 交换都必须属于 SMTP 组件实际使用的那条连接。接线正确后,故障可以定位在代理协商、SMTP 问候、TLS 或邮件认证上,而不是把每次拒绝都当成邮件密码错误。