从.net 6升级到.net 8后无法再通过TLS连接到MariaDB

问题描述 投票:0回答:1

自从我们从 dotnet 6 切换到 dotnet 8 以来,我们无法再通过 TLS 连接到我们的 MariaDB 服务器。

这是我们的连接设置:

  var connectionString = $"server=mariabox;port=3306;user=admin;password=secret;database=tooldb;Connection Timeout=1200;KeepAlive=10";
  services.AddDbContext<ToolsDbContext>(dbContextOptionsBuilder =>
  {
    dbContextOptionsBuilder.UseMySql(new MySqlConnection(connectionString), ServerVersion.AutoDetect(connectionString));
  });

这在 dotnet 6 上可以正常工作,但现在我们得到:

MySqlConnector.MySqlException (0x80004005): SSL Authentication Error
 ---> System.Security.Authentication.AuthenticationException: Cannot determine the frame size or a corrupted frame was received.
   at System.Net.Security.SslStream.GetFrameSize(ReadOnlySpan`1 buffer)
   at System.Net.Security.SslStream.HaveFullTlsFrame(Int32& frameSize)
   at System.Net.Security.SslStream.EnsureFullTlsFrameAsync[TIOAdapter](CancellationToken cancellationToken, Int32 estimatedSize)
   at System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder`1.StateMachineBox`1.System.Threading.Tasks.Sources.IValueTaskSource<TResult>.GetResult(Int16 token)
   at System.Net.Security.SslStream.ReceiveHandshakeFrameAsync[TIOAdapter](CancellationToken cancellationToken)
   at System.Net.Security.SslStream.ForceAuthenticationAsync[TIOAdapter](Boolean receiveFirst, Byte[] reAuthenticationData, CancellationToken cancellationToken)
   at System.Net.Security.SslStream.AuthenticateAsClient(SslClientAuthenticationOptions sslClientAuthenticationOptions)
   at MySqlConnector.Core.ServerSession.InitSslAsync(ProtocolCapabilities serverCapabilities, ConnectionSettings cs, MySqlConnection connection, SslProtocols sslProtocols, IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/Core/ServerSession.cs:line 1475
   at MySqlConnector.Core.ServerSession.InitSslAsync(ProtocolCapabilities serverCapabilities, ConnectionSettings cs, MySqlConnection connection, SslProtocols sslProtocols, IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/Core/ServerSession.cs:line 1507
   at MySqlConnector.Core.ServerSession.ConnectAsync(ConnectionSettings cs, MySqlConnection connection, Int32 startTickCount, ILoadBalancer loadBalancer, IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/Core/ServerSession.cs:line 516
   at MySqlConnector.Core.ConnectionPool.ConnectSessionAsync(MySqlConnection connection, String logMessage, Int32 startTickCount, IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/Core/ConnectionPool.cs:line 363
   at MySqlConnector.Core.ConnectionPool.GetSessionAsync(MySqlConnection connection, Int32 startTickCount, IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/Core/ConnectionPool.cs:line 94
   at MySqlConnector.Core.ConnectionPool.GetSessionAsync(MySqlConnection connection, Int32 startTickCount, IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/Core/ConnectionPool.cs:line 124
   at MySqlConnector.MySqlConnection.CreateSessionAsync(ConnectionPool pool, Int32 startTickCount, Nullable`1 ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/MySqlConnection.cs:line 915
   at MySqlConnector.MySqlConnection.OpenAsync(Nullable`1 ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/MySqlConnection.cs:line 406
   at MySqlConnector.MySqlConnection.Open() in /_/src/MySqlConnector/MySqlConnection.cs:line 369
   at Microsoft.EntityFrameworkCore.ServerVersion.AutoDetect(String connectionString)

我们可以通过在连接字符串中禁用 TLS 来解决这个问题,但希望保留 TLS 加密。

  var connectionString = $"server=mariabox;port=3306;user=admin;password=secret;database=tooldb;Connection Timeout=1200;KeepAlive=10;SslMode=None";

我们使用的是 MariaDB 版本 10.4.32 以及

version_ssl_library = "OpenSSL 1.0.2p-fips  14 Aug 2018"
tls_version = "TLSv1.1,TLSv1.2,TLSv1.3"
version_ssl_library = "OpenSSL 1.0.2p-fips  14 Aug 2018"

我们的 dotnet 应用程序在 Debian 12(书虫)上的 Microsoft Azure 中运行。

Pomelo的版本是6.0.2。 MySqlConnector.dll 的版本是 2.0.0.0。

按照 Fernando 的建议,我添加了 TLS Version=TLS 1.2,但它没有改变任何东西。

更新

我创建了一个不依赖于我们的遗留代码库的小项目,我也遇到了同样的问题。在 Windows 计算机上运行时它工作正常,但是当我在 Azure 中的 debian 上运行它时,我仍然遇到相同的错误。这就是项目的样子:

MysqlTest.csproj:

<Project Sdk="Microsoft.NET.Sdk.Worker">

    <PropertyGroup>
        <AssemblyName>MysqlTest</AssemblyName>
        <RootNamespace>MysqlTest</RootNamespace>
        <NoWarn>CA1848</NoWarn>
    </PropertyGroup>

    <ItemGroup>
        <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.0"/>
        <PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="8.0.0" />
        <PackageReference Include="GitInfo" Version="3.3.3">
            <PrivateAssets>all</PrivateAssets>
            <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
        </PackageReference>
        <PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.1" />
        <PackageReference Include="Serilog.Sinks.Console" Version="4.1.0" />
        <PackageReference Include="MinVer" Version="4.3.0">
            <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
            <PrivateAssets>all</PrivateAssets>
        </PackageReference>
    </ItemGroup>
</Project>

程序.cs

using System;
using System.Linq;
using System.Reflection;
using System.Runtime.Versioning;

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

using MySqlConnector;

using MysqlTest;

var hostBuilder = Host.CreateDefaultBuilder(args);
hostBuilder.ConfigureServices((hostContext, services) =>
{
  var configuration =
  new
  {
    HostName = "test.db",
    Port = 3306,
    Database = "TestDB",
    Username = "admin",
    Password = "admin"
  };
  var connectionDatabase = $"server={configuration.HostName};port={configuration.Port};user={configuration.Username};password={configuration.Password};database={configuration.Database};Connection Timeout=1200;KeepAlive=10;SslMode=REQUIRED;TLS Version=TLS 1.2";
  services.AddDbContext<MyContext>(dbContextOptionsBuilder =>
  {
    dbContextOptionsBuilder.UseMySql(new MySqlConnection(connectionDatabase), ServerVersion.AutoDetect(connectionDatabase));
  }).AddHostedService<TestService>();

});


var host = hostBuilder.Build();

var logger = host.Services.GetRequiredService<ILogger<Program>>();

try
{
  var framework = (TargetFrameworkAttribute)Assembly.GetEntryAssembly()
    ?.GetCustomAttributes(typeof(TargetFrameworkAttribute), false).FirstOrDefault();
  logger.LogInformation("########## {AssemblyName} ##########", typeof(Program).Assembly.GetName().Name);
  logger.LogInformation("AssemblyVersion: {AssemblyVersion}", typeof(Program).Assembly.GetName().Version);
  logger.LogInformation("NET Runtime: {Framework} ({FrameworkVersion})", framework?.FrameworkName, Environment.Version);
  await host.RunAsync();
}
catch (Exception exception)
{
  logger.LogError(exception, "Finished with error.");
  throw;
}
logger.LogInformation("Service stopped.");

#pragma warning disable S1118
public partial class Program;
#pragma warning restore S1118

更新:

我刚刚在 Ubuntu 11 (bullseye) 上尝试了这个,效果很好。但不能确定 Ubuntu 版本是否是根本原因。

c# .net-core mariadb
1个回答
0
投票

问题的原因似乎是这里描述的:

https://learn.microsoft.com/en-us/dotnet/core/compatibility/cryptography/5.0/default-cipher-suites-for-tls-on-linux

dotnet 6 (mcr.microsoft.com/dotnet/sdk:6.0) 基础映像中的 openssl.conf 已包含此处描述的修复程序

openssl_conf = default_conf

[default_conf]
ssl_conf = ssl_sect

[ssl_sect]
system_default = system_default_sect

[system_default_sect]
MinProtocol = TLSv1.2
CipherString = DEFAULT@SECLEVEL=2

而 mcr.microsoft.com/dotnet/sdk:8.0 中的 openssl.conf 则没有。

因此将这些行添加到 openssl.conf 解决了问题(至少对于我的测试程序而言)。我仍然需要用我的实际应用程序来测试它。

© www.soinside.com 2019 - 2024. All rights reserved.