I am trying to send email using C# dotnet 6.0 from Amazon Linux server. The code looks something like this:
public class EmailSender
{
private readonly SmtpOption _smtpOption;
public EmailSender(IConfiguration configuration)
{
_smtpOption = configuration.GetSection("Smtp").Get<SmtpOption>();
}
public void SendEmail()
{
string defaultBody =
"<h1>Amazon SES Test</h1>" +
"<p>This email was sent through the " +
"<a href='https://aws.amazon.com/ses'>Amazon SES</a> SMTP interface " +
"using the .NET System.Net.Mail library.</p>";
// Create and build a new MailMessage object
MailMessage message = new()
{
IsBodyHtml = true,
From = new MailAddress(_smtpOption.From, _smtpOption.FromName),
Subject = _smtpOption.Subject,
Body = _smtpOption.Body ?? defaultBody
};
message.To.Add(new MailAddress(_smtpOption.To));
using (var client = new SmtpClient(_smtpOption.Host, _smtpOption.Port))
{
// Pass SMTP credentials
client.Credentials =
new NetworkCredential(_smtpOption.Username, _smtpOption.Password);
// Enable SSL encryption
client.EnableSsl = _smtpOption.EnableSsl;
// Try to send the message. Show status in console.
try
{
Console.WriteLine("Attempting to send email...");
client.Send(message);
Console.WriteLine("Email sent!");
}
catch (Exception ex)
{
Console.WriteLine("The email was not sent.");
Console.WriteLine("Error message: " + ex.Message);
Console.WriteLine(ex);
}
}
}
}
public class SmtpOption
{
public string From { get; set; }
public string FromName { get; set; }
public string To { get; set; }
public string Host { get; set; }
public int Port { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public string Subject { get; set; }
public string Body { get; set; }
public bool EnableSsl { get; set; }
}
This code works fine on my windows development environment. But when I run this on Amazon Linux Ec2 instance, I am getting this error.
Attempting to send email...
The email was not sent.
Error message: Authentication failed, see inner exception.
System.Security.Authentication.AuthenticationException: Authentication failed, see inner exception.
---> Interop+OpenSsl+SslException: SSL Handshake failed with OpenSSL error - SSL_ERROR_SSL.
---> Interop+Crypto+OpenSslCryptographicException: error:14094438:SSL routines:ssl3_read_bytes:tlsv1 alert internal error
--- End of inner exception stack trace ---
at Interop.OpenSsl.DoSslHandshake(SafeSslHandle context, ReadOnlySpan`1 input, Byte[]& sendBuf, Int32& sendCount)
at System.Net.Security.SslStreamPal.HandshakeInternal(SafeFreeCredentials credential, SafeDeleteSslContext& context, ReadOnlySpan`1 inputBuffer, Byte[]& outputBuffer, SslAuthenticationOptions sslAuthenticationOptions)
--- End of inner exception stack trace ---
at System.Net.Security.SslStream.ForceAuthenticationAsync[TIOAdapter](TIOAdapter adapter, Boolean receiveFirst, Byte[] reAuthenticationData, Boolean isApm)
at System.Net.Security.SslStream.AuthenticateAsClient(SslClientAuthenticationOptions sslClientAuthenticationOptions)
at System.Net.Security.SslStream.AuthenticateAsClient(String targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, Boolean checkCertificateRevocation)
at System.Net.TlsStream.AuthenticateAsClient()
at System.Net.Mail.SmtpConnection.GetConnection(String host, Int32 port)
at System.Net.Mail.SmtpTransport.GetConnection(String host, Int32 port)
at System.Net.Mail.SmtpClient.GetConnection()
at System.Net.Mail.SmtpClient.Send(MailMessage message)
at EmailTester.EmailSender.SendEmail()
The code was also working in dotnet 3.1 in Amazon Linux. This started happening after we updated to 6.0
I think this is related to this breaking change introduced in dotnet 5.0 here (https://learn.microsoft.com/en-us/dotnet/core/compatibility/cryptography/5.0/default-cipher-suites-for-tls-on-linux) This link describes how to resolve this by editing openssl.cnf file however, It is not working for me.
ALso the last paragraph there says this:
On the Red Hat Enterprise Linux, CentOS, and Fedora distributions, .NET applications default to the cipher suites permitted by the system-wide cryptographic policies. On these distributions, use the crypto-policies configuration instead of changing the OpenSSL configuration file.
I am thinking since Amazon Linux is based on RHEL this might be relavant to my issue. Unfortunately the exact steps to solve this in RHEL or Amazon Linux is not clear from the link.
How do I change system-wide cryptographic policies in Amazon Linux?
Any help is appreciated. Thanks in advance.