Ant*_*gan 9 smtp postfix ssmtp
我试图了解 Postfix 究竟是如何处理电子邮件的——以及 SMTP 邮件交易的一些更详细的细节。我的短期目标是调试一个专有的(二进制的、闭源的)SMTP 客户端,但我首先想我会检查成功的 SMTP 事务中会发生什么。
我计划在我们的 LAN 防火墙阻止传出 SMTP(端口 25),因此我将 Postfix 配置为内部邮件服务器,以接受来自(原始)本地客户端软件的邮件,该软件只能通过未经身份验证的 SMTP(通过端口 25)发送电子邮件。
我smtpd
通过在Postfix 日志疑难解答-v
中master.cf
描述的附加详细标志来打开 Postfix进程的调试。然后,我使用 Cygwin Mutt 和sSMTP( 的最小实现)从我自己的工作站发送了一封电子邮件。sendmail
Postfix 日志显示,在RCPT TO:
成功处理该行且收件人地址可接受后,Postfixsmtpd
为该事务分配了一个队列 ID,并使用250 OK
.
但是,DATA
SMTP 客户端并没有发出命令,而是发出了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
。
笔记:
我可以编辑问题以包括从邮件日志文件中提取的内容,但是通过-v
调试,它们非常冗长,我不想用大量无关数据淹没人们。
我搜索了 sSMTP 源代码,但没有发现任何提及RSET
.
Ant*_*gan 14
我一直想知道为什么 SMTP 客户端会通过发出 RSET 命令而不是 DATA 命令来中断它自己的事务。简短的回答是它不会。这是 SMTP 连接被防病毒软件拦截的症状。
我在 sSMTP 的配置中启用了调试选项,但我花了一些时间来弄清楚如何在 Cygwin 中安装和配置 syslog,以便将来自 Cygwin 进程的消息记录到/var/log/messages
而不是 Windows 事件查看器。
但是,它只记录了第一个MAIL FROM:
和RCPT TO:
命令;没有迹象表明这些命令被发送过一次以上——或者sSMTP
曾经发送过一个RSET
命令。
正如我的问题中提到的,我已经检查了 sSMTP 源代码,但没有发送RSET
命令的代码。
用户 masegaloeh 建议防病毒软件可能正在修改 SMTP 数据包 - 他是对的:我暂时禁用了我计算机上的Symantec Endpoint Protection,SMTP 事务正常进行。
重新启用 Symantec Endpoint Protection 后,我使用Windows Sysinternals的TCPView实用程序监视 TCP 连接,我可以看到 Symantec进程正在代理目标端口为 25 的所有 TCP 流量。ccSvcHst.exe
我 telnet 到邮件服务器上的端口 25(netcat 无法正常工作,可能是由于赛门铁克拦截)以通过手动输入 SMTP 命令发送测试邮件。同时,我打开了另一个终端窗口,通过 SSH 连接到邮件主机,同时运行sudo tail -F /var/log/maillog
以同时监视 SMTP 服务器所看到的内容。
赛门铁克代理执行的拦截是微妙的。从邮件客户端的角度来看,几乎没有迹象表明它没有直接与 SMTP 服务器通信。大多数命令在发送时都会传递到邮件服务器,并且响应是您所期望的。直到我输入DATA
命令,赛门铁克代理才开始改变:它的响应是:
354 Please start mail input.
Run Code Online (Sandbox Code Playgroud)
这看起来很正常,但实际上,来自我的 Postfix 服务器的响应应该是
354 End data with <CR><LF>.<CR><LF>
Run Code Online (Sandbox Code Playgroud)
另外:它实际上并没有将DATA
命令传递给 Postfix,直到我完成消息正文并在后面加上QUIT
.
注意:当我输入测试消息的内容时,赛门铁克代理通过发出NOOP
命令来保持与 Postfix 服务器的连接。
我在我的问题中提到,我的最终目标是对我的组织使用的专有(二进制、闭源)邮件客户端进行故障排除。我发现这个客户端真的有问题:它发送了一个无效的HELO
命令(没有任何主机名),然后在 SMTP 服务器礼貌地通知它语法错误后简单地放弃并退出——即使我已经将 Postfix 配置为不需要HELO
(有效或其他)。
我通过安装带有 CentOS 7 的新服务器解决了这个问题,该服务器带有足够新的 Postfix 版本,以便我可以完全禁用 postfix HELO 检查(类似于 MS Exchange 如何简单地忽略无效的 HELO 命令)。
我也一直想知道RSET
SMTP 事务中的一般用法,我在 SMTP 的原始RFC 821 中发现了以下内容:
此命令指定要中止当前邮件事务。必须丢弃任何存储的发件人、收件人和邮件数据,并清除所有缓冲区和状态表。接收者必须发送一个 OK 回复。
RSET
如果结果证明收件人电子邮件地址是针对不存在的用户,则将使用。以下 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:<Smith@ISI-VAXA.ARPA>
R: 250 OK
S: RCPT TO:<Jones@MIT-Multics.ARPA>
R: 250 OK
S: RCPT TO:<Green@MIT-Multics.ARPA>
R: 550 No such user here
S: RSET
R: 250 OK
S: QUIT
R: 221 MIT-Multics.ARPA Service closing transmission channel
Run Code Online (Sandbox Code Playgroud)
SMTP 客户端可以使用相同的 SMTP 连接将多条消息发送到同一目的地。此功能被Postfix称为SMTP 连接缓存。使用此性能功能时,PostfixRSET
在每个MAIL FROM
命令之前发送一个以验证 SMTP 连接仍然可用(请参阅Postfix 连接缓存)。
归档时间: |
|
查看次数: |
23391 次 |
最近记录: |