MailKit发送Office365邮件失败 特定服务器AUTH阶段连接超时
问题现象
应用在本地环境、其余业务服务器上均可正常发送邮件,仅单台服务器发送持续失败,抛出如下异常:
System.IO.IOException: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond ---> System.Net.Sockets.SocketException: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
业务侧使用的邮件发送代码如下:
public static void SendEmail(EmailCreateViewModel viewModel) { var message = new MimeMessage(); message.From.Add(new MailboxAddress("Sender Name", "test@senderemail.com")); message.To.Add(new MailboxAddress("Recipient Name", "test@recipientemail.com")); message.Subject = viewModel.Subject; message.Body = new TextPart("plain") { Text = viewModel.TextBody }; using (var client = new SmtpClient(new ProtocolLogger("C:\smtp.log"))) { try { if(viewModel.BypassServerCertificateValidationCallback) client.ServerCertificateValidationCallback = (sender, certificate, certChainType, errors) => true; client.SslProtocols = System.Security.Authentication.SslProtocols.Tls | System.Security.Authentication.SslProtocols.Tls11 | System.Security.Authentication.SslProtocols.Tls12; client.Connect("smtp.office365.com", 587, SecureSocketOptions.StartTls); client.Authenticate(viewModel.User, viewModel.Password); client.Send(message); client.Disconnect(true); } catch (Exception ep) { Log("failed to send email with the following error:"); Log(ep.ToString()); } } }
抓取的SMTP交互日志如下:
Connected to smtp://smtp.office365.com:587/?starttls=always S: 220 SI2PR02CA0002.outlook.office365.com Microsoft ESMTP MAIL Service ready at Thu, 16 Jun 2022 03:02:14 +0000 C: EHLO <Insert Server Name> S: 250-SI2PR02CA0002.outlook.office365.com Hello [<Insert Server IP>] S: 250-SIZE 157286400 S: 250-PIPELINING S: 250-DSN S: 250-ENHANCEDSTATUSCODES S: 250-STARTTLS S: 250-8BITMIME S: 250-BINARYMIME S: 250-CHUNKING S: 250 SMTPUTF8 C: STARTTLS S: 220 2.0.0 SMTP server ready C: EHLO <Insert Server Name> S: 250-SI2PR02CA0002.outlook.office365.com Hello [<Insert Server IP>] S: 250-SIZE 157286400 S: 250-PIPELINING S: 250-DSN S: 250-ENHANCEDSTATUSCODES S: 250-AUTH LOGIN XOAUTH2 S: 250-8BITMIME S: 250-BINARYMIME S: 250-CHUNKING S: 250 SMTPUTF8 C: AUTH LOGIN
从日志可确认:TCP连接建立、EHLO交互、STARTTLS握手流程均正常,客户端发送AUTH LOGIN认证请求后未收到服务端响应,最终触发超时。
已完成的排查操作:
- 关闭服务器系统防火墙、禁用Windows Defender,问题未解决
- 在该服务器上使用PowerShell,配置完全一致的SMTP服务地址、587端口、TLS参数可正常发送邮件,排除基础网络连通性问题
排查思路与解决方案
按优先级从高到低依次排查:
- 排查进程运行身份的网络配置差异
这是该类问题最高频的诱因:PowerShell默认在当前登录用户的上下文下运行,而多数业务应用是以Windows服务、IIS站点的形式运行,使用的是本地服务、网络服务或自定义服务账号,不同身份对应的网络栈配置完全独立。- 第一步先把应用的运行身份临时改成你当前跑PowerShell的登录账号,测试发信。如果改完能正常发信,直接定位为服务账号的配置问题:
- 执行
netsh winhttp show proxy查看系统级WinHTTP代理配置:用户级代理(PowerShell用的配置)和系统级代理(服务账号默认用的配置)是独立存储的,如果系统级配置了错误的代理,直接执行netsh winhttp reset proxy重置即可。 - 检查服务账号是否有权限访问系统证书存储的受信任根证书目录,TLS握手后的认证阶段需要读取证书相关密钥,权限不足会导致流程卡住无响应。
- 执行
- 第一步先把应用的运行身份临时改成你当前跑PowerShell的登录账号,测试发信。如果改完能正常发信,直接定位为服务账号的配置问题:
- 排查应用层安全管控的进程级拦截
关闭Windows Defender不代表没有其他安全拦截:企业服务器普遍部署的EDR、终端杀毒、流量管控软件都会做SMTP协议的应用层检测,通常会放通PowerShell等系统可信进程的流量,但非白名单的业务进程发送SMTP认证请求时,会直接在驱动层丢包,不会返回RST重置包,最终表现为超时,和你现在的日志表现完全吻合。- 临时把业务应用的exe路径加入所有安全软件的白名单,或按运维规范临时停止安全管控服务测试,确认是否为拦截导致。
- 修正TLS配置错误
代码中硬编码Tls | Tls1.1 | Tls1.2的组合存在兼容问题:目前Office365已经完全弃用TLS1.0、TLS1.1协议,硬编码多版本枚举在部分旧补丁版本的Windows上会导致加密套件协商异常,在认证阶段卡住。- 删除手动指定
client.SslProtocols的代码行,让MimeKit跟随操作系统自动协商最高支持的TLS版本。 - 确认服务器已开启TLS1.2默认客户端配置:检查注册表路径
HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client下,DisabledByDefault值为0,Enabled值为1,同时安装最新的Windows系统补丁更新加密套件支持。
- 删除手动指定
- 调整超时配置验证
代码中未手动指定SmtpClient的超时时间,MimeKit默认超时为120秒,部分服务器上TLS会话复用异常会导致认证阶段耗时超过默认阈值,可以手动设置更长超时测试:client.Timeout = 300000;(设置为5分钟)。 - 抓包确认流量拦截点
如果以上排查都没解决,在服务器上安装Wireshark抓取587端口的双向流量:- 如果抓到了Office365返回的认证响应包,但应用层没收到,说明是本地过滤驱动、WFP网络层拦截了流量
- 如果完全没收到Office365的回包,联系网络管理员检查出口防火墙是否对该进程的SMTP会话做了拦截
内容的提问来源于stack exchange,提问作者Lawrence
相关产品推荐
相关产品推荐

