Serilog 电子邮件接收器启用 SSL 错误检查

Serilog Email sink enableSSL false checks

我正在尝试在我的 EmailConnectionInfo 中使用 EnableSsl = false,但似乎 smtp client being used for the smtp connection is trying to use SSL because the default SecureSocketOptions is set to Auto. When I created a client manually and used the overloadSecureSocketOptions = None 有效。

错误:

Failed to send email: MailKit.Security.SslHandshakeException: An error occurred while attempting to establish an SSL or TLS connection.

The SSL certificate presented by the server is not trusted by the system for one or more of the following reasons:
1. The server is using a self-signed certificate which cannot be verified.
2. The local system is missing a Root or Intermediate certificate needed to verify the server's certificate.
3. The certificate presented by the server is expired or invalid.

See https://github.com/jstedfast/MailKit/blob/master/FAQ.md#InvalidSslCertificate for possible solutions. ---> System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure.

解决方法:

我正在将 ServerCertificateValidationCallback 设置为 true

在我的 Program.cs 中使用时,它有效:

.UseSerilog((hostingContext, loggerConfiguration) =>{
   Serilog.Debugging.SelfLog.Enable(Console.WriteLine);           
   loggerConfiguration.ReadFrom.Configuration(hostingContext.Configuration)
   .WriteTo.Email(
      new EmailConnectionInfo {
      FromEmail = "{email}",
      ToEmail = "{email}",
      MailServer = "{SMTP IP}",
      Port = {PORT},
      EnableSsl = false,
      EmailSubject = "Something to log",
      ServerCertificateValidationCallback = (senderX, certificate, chain, sslPolicyErrors) => true
   },
   outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj}{NewLine}{Exception}",
   batchPostingLimit: 1,
   restrictedToMinimumLevel: LogEventLevel.Warning);
});

但是,当我尝试在 appsettings.json 中包含 Email sink 的所有 serilog 设置时,无法读取 "ServerCertificateValidationCallback": "(senderX, certificate, chain, sslPolicyErrors) => true"(我的假设)

我的appsettings.json

"Serilog": {
    "Using": [ "Serilog.Sinks.File","Serilog.Sinks.Email" ],
    "MinimumLevel": "Information",
    "WriteTo": [
      ...
      {
        "Name": "Email",
        "Args": {
          "connectionInfo": {
            "MailServer": "{SMTP IP}",
            "Port": {PORT},
            "EnableSsl": false,
            "FromEmail": "{email}",
            "ToEmail": "{email}",
            "EmailSubject": "Something went wrong",
            "ServerCertificateValidationCallback": "(s, cert, chain, sslPolicyErrors) => true"
          },
          "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] {Message}{NewLine}{Exception}",
          "restrictedToMinimumLevel": "Warning",
          "batchPostingLimit": 1
        }
      }
    ],
    "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ]
  }
...

有什么想法吗?

编辑:我打开的githut issue

如您在 Mailkit's source code 中所见,当 enableSslfalse 时,它使用 SecureSocketOptions.StartTlsWhenAvailable。 TLS 在您的 Exchange 服务器中可用,因此它正在尝试使用它...

如果 Serilog.Sinks.Email 公开了更改此行为的方法 (issue 69 that you reported),那将是一种解决方法,但 我认为正确的解决方法是更新您的 Exchange 配置在此连接器上使用为 TLS 通信安装的正确证书

当入站建立 TLS 时,服务器可能会根据名称(自签名证书)获取最接近的匹配项。

您的 IT 管理员应该能够按照此post“Configuring the TLS Certificate Name for Exchange Server Receive Connectors”中描述的步骤更新 TLS 证书。

我能够利用其他一些问题来解决这个问题,并且不支持回调能够直接通过配置来设置它。这个问题的答案 () 特别有用。如果您按照他的示例进行一些修改。

您可以将 ServerCertificateValidationCallback = (senderX, certificate, chain, sslPolicyErrors) => true 添加到 SerilogEmailExtension 扩展中的 EmailConnectionInfo class

调整 Serilog 配置“Using”语句以包含已编译应用程序的名称,以便它可以找到扩展名 class 而不是“MyApp”:

"Using": [ "Serilog", "Serilog.Sinks.Console", "Serilog.Sinks.File", "MyApp" ],

这应该让你实现所有配置驱动,并且仍然添加回调来绕过异常。