I am trying to use EnableSsl = false
in my EmailConnectionInfo
but it seems like the 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 overload with SecureSocketOptions = None
it worked.
The error:
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.
The workarround:
I am setting the ServerCertificateValidationCallback
to true
When used in my Program.cs
, it works:
.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);
});
But, when I try to include all my serilog settings for Email sink
in appsettings.json
the "ServerCertificateValidationCallback": "(senderX, certificate, chain, sslPolicyErrors) => true"
cannot be read (my assumption)
my 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" ]
}
...
Any ideas?
Edit: The githut issue I opened
I was able to get this working leveraging a few other questions and without the support for the callback being able to set this directly via configuration. This question's answer (https://stackoverflow.com/a/59914193/116208) was particularly helpful. If you follow his example there with a few modifications.
You can add the ServerCertificateValidationCallback = (senderX, certificate, chain, sslPolicyErrors) => true
to the EmailConnectionInfo
in the SerilogEmailExtension
extension class
Adjust the Serilog configuration "Using" statement to include your compiled application's name so it can find the extension class instead of "MyApp":
"Using": [ "Serilog", "Serilog.Sinks.Console", "Serilog.Sinks.File", "MyApp" ],
This should let you achieve everything to be configuration driven, and still add in the callback to bypass the exception.