无法使用 Perl 中的 Net::SMTP 模块在端口 465 上提交电子邮件

Unable to submit email on port 465 using Net::SMTP module in Perl

我想在客户端的 perl 脚本中使用 Net::SMTP 模块(不使用 Net::SMTP::SSL)在我的 smtp 服务器的端口 465 上提交电子邮件。在我的 SMTP 服务器的端口 465 上,"submissions" 服务运行,它理解 SMTPS。

我试图在 google 上找到执行此操作的方法。然后使用 Net::SMTP::SSL 模块在端口 465 上发出请求。它工作正常。

但是 Net::SMTP::SSL 的文档建议使用最新版本 Net::SMTP 而不是 Net::SMTP::SSL。 文件明确指出

Since Net::SMTP v1.28 (2014-10-08), Net::SMTP itself has support for SMTP over SSL, and also for STARTTLS. Use Net::SMTP, not Net::SMTP::SSL.

我已经将 Net::SMTP 模块更新到最新版本 3.11。

另外 Net::SMTP 的文档也明确指出

With IO::Socket::SSL installed it also provides support for implicit and explicit TLS encryption, i.e. SMTPS or SMTP+STARTTLS.

我在客户端的 perl 脚本代码部分,与提到的问题相关,如下所示:

$smtp = Net::SMTP::SSL->new("$mailserver",
                        Hello => "$localhostname",
                        Timeout => 60,
                        Port => "$port",  //Port value is 465
                        Debug => 1);
 $smtp->auth($username, $password);

...设置发送方、接收方正文等的剩余脚本

这很好用。电子邮件被提交。 用 :

替换上面的代码
$smtp = Net::SMTP->new("$mailserver",
                        Hello => "$localhostname",
                        Timeout => 60,
                        Port => "$port",  //Port value is 465
                        Debug => 1);
$smtp->auth($username, $password);

...设置发送方、接收方正文等的剩余脚本

这失败了。调试日志如下所示:

Net::SMTP>>> Net::SMTP(3.11)
Net::SMTP>>>   Net::Cmd(3.11)
Net::SMTP>>>     Exporter(5.73)
Net::SMTP>>>   IO::Socket::INET(1.39)
Net::SMTP>>>     IO::Socket(1.39)
Net::SMTP>>>       IO::Handle(1.39)
Net::SMTP: Net::Cmd::getline(): unexpected EOF on command channel:  at fescommon/mailsend-new.pl line 67.
Can't call method "auth" on an undefined value at fescommon/mailsend-new.pl line 74.

注意:Net::SMTP、Net::SMTP::SSL、IO::Socket::SSL等模块均已更新至最新版本。

预期结果是可以使用最新的 Net::SMTP 模块,而不使用 Net::SMTP::SSL(因为文档声明)

如果您想使用 smtps(即从开始的 TLS 而不是 STARTTLS 命令之后的 TLS),您必须明确说明。 Net::SMTP 并没有神奇地从端口号中得出这个要求。来自 the documentation:

new ( [ HOST ] [, OPTIONS ] )
SSL - If the connection should be done from start with SSL, contrary to later upgrade with starttls. You can use SSL arguments as documented in IO::Socket::SSL, but it will usually use the right arguments already.

因此,正确的代码应该是:

$smtp = Net::SMTP->new($mailserver,
    SSL => 1,  # <<<<<<<<<<<<<<<<<<<<<<<< THIS IS IMPORTANT
    Hello => $localhostname,
    Timeout => 60,
    Port => $port,  # Port value is 465
    Debug => 1
);