RSET 的一般用途

RSET 的一般用途

我正在尝试了解 Postfix 究竟如何处理电子邮件 - 以及 SMTP 邮件事务的一些细节。我的短期目标是调试专有(二进制、闭源)SMTP 客户端,但我首先想到的是检查成功的 SMTP 事务中会发生什么。

我计划在我们的 LAN 防火墙上阻止传出的 SMTP(端口 25),因此我将 Postfix 配置为内部邮件服务器,以接受来自(原始)本地客户端软件的邮件,该软件只能通过未经身份验证的 SMTP(通过端口 25)发送电子邮件。

smtpd我通过附加-v详细标志来打开 Postfix 进程的调试,master.cf如中所述使用 Postfix 日志进行故障排除。然后我使用 Cygwin Mutt 从我自己的工作站发送了一封电子邮件SMTP协议(的最小实现sendmail)。

Postfix 日志显示,在RCPT TO:成功处理该行并且收件人地址可以接受后,Postfix 为该smtpd事务分配了一个队列 ID,并使用 响应 SMTP 客户端(sSMTP)250 OK

但是,DATASMTP 客户端并没有发出命令,而是发出了RSET重置/中止当前邮件事务的命令,而 Postfix 则回复了250 OK

我研究了一下这个命令的作用,不出所料,简单邮件传输协议,RFC 2821提供最全面的信息:

此命令指定将中止当前邮件事务。必须丢弃所有存储的发件人、收件人和邮件数据,并清除所有缓冲区和状态表。接收方必须向 RSET 命令发送不带参数的“250 OK”回复。客户端可以随时发出重置命令。如果在 EHLO 之后立即发出,在会话中发出 EHLO 之前发出,在发送和确认数据结束指示符之后发出,或在 QUIT 之前立即发出,则它实际上相当于 NOOP(即,如果它无效)。SMTP 服务器不得在收到 RSET 后关闭连接;该操作保留用于 QUIT(参见第 4.1.1.10 节)。

由于 EHLO 意味着服务器进行一些额外的处理和响应,因此 RSET 通常比重新发出该命令更有效,即使形式语义相同。

在某些情况下,与本规范的意图相反,SMTP 服务器可能会收到底层 TCP 连接已关闭或重置的指示。为了保持邮件系统的稳健性,SMTP 服务器应该为这种情况做好准备,并且应该将其视为在连接消失之前已收到 QUIT。

以上所有情况都在一秒钟之内发生,因此不应该出现超时问题。

在下一秒,客户端发送了另一个RSET,但客户端随后等待了整整 10 秒才重新启动MAIL FROM:RCPT TO:但这一次它会执行并发出DATA命令并且事务完成(根据日志,所有这些都在同一秒内完成)。

本质上,我想知道为什么 SMTP 客户端会通过发出RSET命令而不是DATA命令来中断其自己的交易。

笔记:

  1. 我可以编辑问题以包含来自邮件日志文件的摘录,但通过调试-v,它们非常冗长,我不想用大量不相关的数据淹没人们。

  2. 我搜索了 sSMTP 源代码,但没有发现任何提及RSET

答案1

结论

我一直想知道为什么 SMTP 客户端会通过发出 RSET 命令而不是 DATA 命令来中断自己的事务。简而言之,它不会;这是 SMTP 连接被防病毒软件拦截的症状。

客户端日志

我在 sSMTP 的配置中启用了“调试”选项,但我花了一些时间才弄清楚如何在 Cygwin 中安装和配置 syslog,以便将来自 Cygwin 进程的消息记录到/var/log/messagesWindows 事件查看器中。

但是,它只记录了第一个MAIL FROM:和第二个RCPT TO:命令;没有迹象表明这些命令被发送了多次 – 或者曾经sSMTP发送过RSET命令。

正如我的问题中提到的,我检查了 sSMTP 源代码,但没有发送RSET命令的代码。

赛门铁克拦截 SMTP 流量

用户 masegaloeh 表示,防病毒软件可能正在修改 SMTP 数据包——他是对的:我暂时禁用了赛门铁克端点保护在我的计算机上,SMTP 交易正常进行。

重新启用 Symantec Endpoint Protection 后,我使用TCP查看器实用工具Windows 系统内部我可以看到 SymantecccSvcHst.exe进程正在代理所有目标端口为 25 的 TCP 流量。

我通过 telnet 连接到邮件服务器的 25 端口(netcat 无法正常工作,可能是由于 Symantec 拦截)以手动输入 SMTP 命令发送测试邮件。同时,我在运行时打开另一个终端窗口,通过 SSH 连接到邮件主机,以sudo tail -F /var/log/maillog同时监控 SMTP 服务器看到的内容。

Symantec 代理执行的拦截非常隐蔽。从邮件客户端的角度来看,几乎没有迹象表明它没有直接与 SMTP 服务器通信。大多数命令在发送时都会传递到邮件服务器,并且响应符合您的预期。直到我输入命令后DATA,Symantec 代理才开始改变情况:它响应如下:

354 Please start mail input.

这看起来很正常,但实际上,我的 Postfix 服务器的响应应该是

354 End data with <CR><LF>.<CR><LF>

DATA另外:直到我完成邮件正文并在其后添加QUIT.之后,它才真正将命令传递给 Postfix。

注意:当我输入测试消息的内容时,Symantec 代理通过发出NOOP命令保持与 Postfix 服务器的连接。

处理有问题的 SMTP 客户端

我在问题中提到,我最终的目标是排除我所在组织使用的专有(二进制、闭源)邮件客户端的故障。我发现这个客户端确实存在问题:它发送了一个无效HELO命令(没有任何主机名),然后在 SMTP 服务器礼貌地通知它其语法错误后,它就放弃并退出了——尽管我已将 Postfix 配置为不需要HELO(有效或其他)。

我通过安装 CentOS 7 的新服务器解决了这个问题,该服务器附带的 Postfix 版本足够新,这样我就可以完全禁用 postfix HELO 检查(类似于 MS Exchange 如何简单地忽略无效的 HELO 命令)。


RSET 的一般用途

我也一直在想RSET在 SMTP 事务中的一般用法,我在原始文件中找到了以下内容RFC 821对于 SMTP:

此命令指定要中止当前邮件事务。必须丢弃所有存储的发件人、收件人和邮件数据,并清除所有缓冲区和状态表。接收方必须发送 OK 回复。

RSET如果收件人电子邮件地址不是现有用户,则将使用 SMTP 事务。以下 SMTP 事务是中止 SMTP 事务场景

R: 220 MIT-Multics.ARPA Simple Mail Transfer Service Ready
S: HELO ISI-VAXA.ARPA
R: 250 MIT-Multics.ARPA

S: MAIL FROM:<[email protected]>
R: 250 OK

S: RCPT TO:<[email protected]>
R: 250 OK

S: RCPT TO:<[email protected]>
R: 550 No such user here

S: RSET
R: 250 OK

S: QUIT
R: 221 MIT-Multics.ARPA Service closing transmission channel

重复使用 SMTP 连接

SMTP 客户端可以使用同一个 SMTP 连接将多封邮件发送到同一个目的地。此功能称为SMTP 连接缓存Postfix 提供此功能。使用此性能功能时,Postfix 会RSET在每条MAIL FROM命令前发送一条消息,以验证 SMTP 连接是否仍然可用(请参阅Postfix 连接缓存)。

相关内容