.NET 6升级后Amazon Linux EC2发送邮件遇SSL_ERROR_SSL问题
.NET 6.0在Amazon Linux上发送邮件SSL握手失败问题
问题场景
- 代码在Windows开发环境(.NET 6.0)运行正常,部署到Amazon Linux EC2实例后出现SSL握手失败错误
- 相同代码在.NET 3.1的Amazon Linux环境可正常运行,升级到6.0后出现问题
- 错误日志如下:
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()
涉事代码
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; } }
解决方案:调整Amazon Linux系统级加密策略
Amazon Linux基于RHEL,使用crypto-policies管理系统级加密规则,无需直接修改openssl.cnf,操作步骤如下:
查看当前加密策略
执行以下命令查看当前系统生效的加密策略:update-crypto-policies --show切换到兼容型加密策略
.NET 5+默认收紧了TLS密码套件,而Amazon SES SMTP可能依赖部分旧套件,可切换到LEGACY策略(包含更多兼容旧服务的套件):sudo update-crypto-policies --set LEGACY使策略生效
策略变更后需要重启系统或应用服务,确保新策略生效:sudo reboot
备选方案:代码层面调整(无需系统变更)
如果不想修改系统级策略,也可以在代码中指定兼容的TLS版本和套件:
// 在创建SmtpClient前添加以下配置 ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls13; // 强制使用旧版Socket处理(部分场景下可解决握手问题) AppContext.SetSwitch("System.Net.UseSocketsHttpHandler", false);
内容的提问来源于stack exchange,提问作者Sunil Shahi
相关产品推荐
相关产品推荐

