正确响应 SMTP HELO

Proper response to SMTP HELO

以下是 SMTP 事务示例的开头 教科书计算机网络(第6国际版):

S: 220 hamburger.edu
C: HELO crepes.fr
S: 250 Hello crepes.fr, pleased to meet you

S:前缀表示是服务器发送的一行,C:表示是 客户端发送的一行。维基百科页面 SMTP 有一个 SMTP 对 HELO.

具有类似响应的示例

服务器对 HELO 规范的响应是否合规? RFC 5321 指定服务器对 HELO/EHLO 的响应,因此:

ehlo-ok-rsp    = ( "250" SP Domain [ SP ehlo-greet ] CRLF )
                    / ( "250-" Domain [ SP ehlo-greet ] CRLF
                    *( "250-" ehlo-line CRLF )
                    "250" SP ehlo-line CRLF )

根据我对规范的理解,上述示例中服务器的响应应该是

250 hamburger.edu

也就是说,它应该用 250 后跟它自己的主机名而不是 客户端的主机名,当然不是显示的任意问候消息 在示例中。

HELO 的正确回应是什么? 计算机网络示例不正确吗?

简答

示例无效,因为 Hello 紧跟在 250 之后。但是..这可能并不重要。

长(呃)答案

首先让我们看一下客户端的语法 "HELO":

"HELO" SP Domain CRLF

客户端发送 HELO 后跟 space,然后是他的域名,然后是 CRLF。我怎么知道它是客户域?嗯:

The argument clause contains the fully-qualified domain name of the SMTP client, if one is available

现在回复:

ehlo-ok-rsp = ( "250" SP Domain [ SP ehlo-greet ] CRLF ) / ( "250-" Domain [ SP ehlo-greet ] CRLF *( "250-" ehlo-line CRLF ) "250" SP ehlo-line CRLF )

这里有两个选项:

  1. "250" SP Domain [ SP ehlo-greet ] CRLF
  2. ( "250-" Domain [ SP ehlo-greet ] ...

两者都不适合 因为域名是预期的而不是我们看到的 Hello

下面的 ehelo-greet 部分还不错。 RFC 的下一页对此进行了解释:

ehlo-greet = 1*(%d0-9 / %d11-12 / %d14-127) ; string of any characters other than CR or LF

因此它可以是任何不包含 \r\n 的字符串。字符串 , pleased to meet you 显然属于该类别。

为什么没关系

综上所述,请注意示例无效这一事实并不意味着它不会在实践中发生,或者发送此类示例的服务器无法正常工作。理论和实践是有区别的。例如,如果我们查看 Java 的官方 JavaMail,在 SMTPTransport.java 的第 1662-1665 行,我们会发现以下代码:

if (first) {    // skip first line which is the greeting
    first = false;
    continue;
}

这来自名为 ehlo(String domain) 的方法,该方法处理发送和接收 HELO 命令。 Java邮件跳过了整个问候语,我怀疑其他客户端也可能这样做。

RFC 821 实际上并未指定对 HELO 的响应是什么,但所有示例都使用收件人的域作为邮件正文。后来的 RFC 定义了扩展问候 (EHLO),它实际上具有定义的响应格式。但是考虑到原始标准中缺乏明确性,实际上当客户端粗心地发送 HELO 而不是 EHLO 时,250 和 CR 之间的任何内容都是符合标准的。