无法使用TLS将邮件发送到本地SMTP服务器

时间:2017-07-12 09:24:18

标签: ssl smtp exchange-server

因此我们有一个本地交换服务器,我们将其用作内部服务器的SMTP服务器。我正在努力解决它所以它适用于TLS,但现在它不是。

我有一个分配给SMTP和IIS角色的通配符证书。但是,当我尝试通过PowerShell使用send-mailmessage时,我得到了。

Send-MailMessage -SmtpServer mail.domain.com -UseSsl -port 465 -From fromaddress 
-To tomailaddress -Subject test -BodyAsHtml test -Encoding ([System.Text.Encoding]::UTF8)

根据验证程序,远程证书无效。

当我访问IIS站点(或使用相同证书的任何其他站点)时,使用的证书对我有效。

那么我做错了什么?或者我该如何排除故障。

2 个答案:

答案 0 :(得分:0)

请注意,无法使用IIS管理SMTP的SSL证书。你需要在这里使用powershell(Enable-ExchangeCertificate)[更多信息here]

示例:

  

启用ExchangeCertificate -Thumbprint   434AC224C8459924B26521298CE8834C514856AB -Services SMTP

通常,您可以使用Openssl对此类TLS连接(通过端口465)进行故障排除(请参阅here了解如何操作)。

URL也有一些解决方案,所以我不会在这里复制它们。一般来说,问题是:

  • SSL证书在远程计算机上(或密钥库中不完全受信任,不适用于您的PowerShell测试,但可能适用于您的第三方软件)
  • 仍有自签名SSL证书与SMTP一起使用

<强>结论: 我认为你仍然在SMTP端口上使用自签名的ssl证书,并且应该使用上面的命令进行更改。

答案 1 :(得分:0)

我有同样的问题。首先,我使用下面的代码保存了SMTP服务器使用的证书的副本(由于我没有访问服务器本身的权限,即使您有权访问该服务器,这也显示了所显示的服务器,因此如果不同则可以进行标记达到您的预期)。我通过LinqPad5将其作为c#程序运行。

void Main()
{
    System.Net.ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(OutputCertificateCallback);
    using (System.Net.Mail.SmtpClient S = new System.Net.Mail.SmtpClient("smtprelay.subdomain.example.com"))
    {
        S.EnableSsl = true;
        using (System.Net.Mail.MailMessage M = new System.Net.Mail.MailMessage("john.bevan@example.com", "john.bevan@example.com", "Test", "Test"))
        {
            try
            {
                S.Send(M);
                Console.WriteLine("Sent");
            }
            catch (Exception e)
            {
                Console.WriteLine("Error {0}", e);
            }
        }
    }
}

private bool OutputCertificateCallback(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors)
{
    Console.WriteLine(certificate);
    System.IO.File.WriteAllBytes(@"C:\Temp\cert.cer", certificate.Export(System.Security.Cryptography.X509Certificates.X509ContentType.Cert));
    var c2 = new System.Security.Cryptography.X509Certificates.X509Certificate2(certificate);
    return c2.Verify();
}

然后我可以通过查看保存的文件检查证书:C:\Temp\cert.cer

检查到期日期,以确保证书有效。 如果不是,那就是问题所在。获取新证书。

检查我的客户端的受信任CA中的根证书:

  • 开始,运行,MMC
  • 文件>添加/删除管理单元>证书>添加>我的用户帐户>完成>确定
  • 证书-当前用户>受信任的根证书颁发机构>证书
  • 在此列表中搜索根CA(即与证书名称相同的根CA)

如果不是,则可能需要安装根CA,中间CA或证书本身(您可以使用刚刚使用上述脚本保存的文件来安装)。

检查端口是否在防火墙上打开。您可以通过以下PowerShell进行测试:

try {
    $tcp = New-Object -TypeName 'system.net.sockets.tcpclient' -ArgumentList 'smtprelay.subdomain.example.com', 465 
    if ($tcp.Connected) {':)'} else {':('}
} catch {
    ':('
    $_.Exception.Message
}

就我而言,以上所有内容不足以发现问题。最终,我意识到该服务使用了通配符证书(例如*.example.com),但是邮件服务器位于子域(例如smtprelay.subdomain.example.com)上,因此该证书未涵盖该服务。在子域(例如*.subdomain.example.com)上使用通配符会行得通;尽管我们只是要求为服务提供一个明确命名的证书(用于smtprelay.subdomain.example.com),包括服务的各个节点的FQDN作为使用者备用名称,以防万一我们需要将特定的节点作为调试目标。