MS-SQL 접근시 "Encryption(ssl/tls) handshake failed" 오류 발생 문의 드립니다.

안녕하세요.
좋은 글들 읽기만 하다가 질문을 드려 봅니다.

  • 설치 및 dotnet 실행
    WSL2 + Ubuntu-22.04 + .Net Runtime 7.0 + Oracle Client 19.3 설치
    $ dotnet /home/test/test.dll > /dev/null 2>&1 & 실행

  • 프로그램 테스트

    1. oracle 연결 및 데이터 가져오는 프로그램 정상 동작
    2. ms-sql 연결 및 데이터 가져오는 프로그램 오류 발생(윈도우 환경[동일 PC]에서 실행하면 정상 접근 가능)
      Microsoft.Data.SqlClient.SqlException (0x80131904):
      A connection was successfully established with the server,
      but then an error occurred during the pre-login handshake.
      (provider: SSL Provider, error: 31 - Encryption(ssl/tls) handshake failed)
  • ms-sql 현황 (현재 버전에서 해결책을 찾고 있습니다.)
    windows 2008 r2 , mssql 2008 r2

  • ms-sql 오류 확인을 위해 진행해본 것

    1. 핫픽스 적용
      Security Update for SQL Server 2008 R2 SP3 (KB4057113)
    2. QueryString 내용 추가 : Encrypt=false;TrustServerCertificate=True;
    3. $ sudo vi /etc/ssl/openssl.cnf 수정후 재기동
      [system_default_sect]
      CipherString = DEFAULT:@SECLEVEL=0
    4. Ubuntu-20.04 로 변경 및 동일 환경 구성후 테스트

=> 문의사항

  1. 다른 해결책은 없을까요?
  2. 다른 리눅스 OS (CentOS, Rocky, Ubuntu 18.40 이하 버전 ) 사용해보면 다를까요?

비슷한 해결 경험이나 더 해볼만한 사항 있으시면 의견 부탁드려봅니다.

1 Like

Microsoft.Data.SqlClient.SqlException - 0x80131904
; https://www.sysnet.pe.kr/2/0/13340

4 Likes

아… ^^; 제가 경솔했군요. 이미 해보신 방법이니 위의 글은 참조할 필요가 없겠습니다.

혹시, 테스트를 하나 해보시겠어요. SQL Server 2008 R2 말고 2012 버전으로 연결해 보세요. 아마 잘 되지 않을까 싶은데요, 문서상으로 보면,

SqlClient driver support lifecycle - ADO.NET Provider for SQL Server | Microsoft Learn

아예 2008 버전 자체가 언급이 안 되고 있습니다. 어쩌면 2008 버전을 위해서라면 System.Data.SqlClient 패키지를,

NuGet Gallery | System.Data.SqlClient 4.8.5

사용해야 할 지도 모르겠습니다. (해보고 답변을 달아야 하는데… 그럴 수가 없는 상황이군요. ^^;)

4 Likes

우선 두번이나 댓글 주셔서 너무너무 감사드립니다.

지원이 중단된 오래된 버전이지만, SQL 버전을 유지해야하는 상황이라,
해당 버전에서의 해결책을 찾아보고 있습니다.

Linux OS가 버전업 하면서 점점 보안이 강화된것으로 보여져서, 낮은 버전으로 한단계씩 내려서 테스트 해보려고 합니다.

문제가 해결되거나 진전이 있으면 다시 답글남기도록 하겠습니다.

다른 의견이나, 힌트, 살펴보면 좋은 참조 있으시면 꼭 댓글 부탁드리겠습니다.

2 Likes

openssl.cnf 설정을 다음과 같이 해보세요. 잘 될 겁니다.

openssl_conf = default_conf

[default_conf]
ssl_conf = ssl_sect

[ssl_sect]
system_default = system_default_sect

[system_default_sect]
MinProtocol = TLSv1
CipherString = DEFAULT:@SECLEVEL=1

위에서 “openssl_conf = default_conf” 문자열은 cnf 파일의 처음에 와야 합니다.

4 Likes

ubuntu 22.04 버전 기준으로 아래와 같이 설정후 wsl --shutdown 후 다시 실행
동일한 오류가 발생하는것을 확인하였습니다. (수정 부분 Bold 체 사용)

openssl_conf = openssl_init

[openssl_init]
providers = provider_sect
ssl_conf = ssl_sect

[ssl_sect]
system_default = system_default_sect

[system_default_sect]
MinProtocol = TLSv1
CipherString = DEFAULT:@SECLEVEL=1

1 Like

에러 내용 상세 입니다.

2023-06-08 15:06:27.468 +09:00 ERR] Connection id “0HMR7SPS2BJEB”, Request id “0HMR7SPS2BJEB:00000004”: An unhandled exception was thrown by the application.
Microsoft.Data.SqlClient.SqlException (0x80131904): A connection was successfully established with the server, but then an error occurred during the pre-login handshake. (provider: SSL Provider, error: 31 - Encryption(ssl/tls) handshake failed)
—> System.IO.IOException: Received an unexpected EOF or 0 bytes from the transport stream.
at System.Net.Security.SslStream.ReceiveBlobAsync[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 Microsoft.Data.SqlClient.SNI.SNITCPHandle.EnableSsl(UInt32 options)
at Microsoft.Data.SqlClient.SNI.TdsParserStateObjectManaged.EnableSsl(UInt32& info, Boolean tlsFirst, String serverCertificateFilename)
at Microsoft.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection)
at Microsoft.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, TaskCompletionSource1 retry, DbConnectionOptions userOptions, DbConnectionInternal& connection) at Microsoft.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal& connection)
at Microsoft.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource1 retry, DbConnectionOptions userOptions) at Microsoft.Data.ProviderBase.DbConnectionClosed.TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource1 retry, DbConnectionOptions userOptions)
at Microsoft.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry, SqlConnectionOverrides overrides)
at Microsoft.Data.SqlClient.SqlConnection.InternalOpenAsync(CancellationToken cancellationToken)
— End of stack trace from previous location —
at Dapper.SqlMapper.QueryAsync[T](IDbConnection cnn, Type effectiveType, CommandDefinition command) in /_/Dapper/SqlMapper.Async.cs:line 417

1 Like

22.04에서는 SECLEVEL 값을 0으로 주면 됩니다. 관련해서는 다음의 글에 정리했으니 참고하세요.

.NET Framework: 2127. C# - Ubuntu + Microsoft.Data.SqlClient + SQL Server 2008 R2 연결 방법 (sysnet.pe.kr)

3 Likes

역시 이미 알고계시고, 먼저 답글을 달아주셨었네요.
제가 겪었던 문제라 바로 달려왔는데 말이에요 ㅎㅎ
OpenSSL3 버전이 정식으로 사용되면서 비슷한 문제를 겪고 있는 사람들이 여럿 있는 것 같습니다.

아래는 제가 해결방법을 공유했던 깃허브 이슈 링크입니다 :slight_smile:

2 Likes

답글 정말 감사드립니다.
처음부터 다시 적용해보겠습니다.
감사합니다.

  1. ConnectionString에 옵션 추가
    TrustServerCertificate=true
  2. openssl.cnf 설정 변경
    [system_default_sect]
    CipherString = DEFAULT:@SECLEVEL=0

두분 모두 말씀해주신 것처럼
위 내용 변경및 리눅스(ubuntu 22.04) 재기동 후 정상 MS-SQL 2008 에 연결되었습니다.

제 질문글 보시면 해당 내용은 적용 해본것인데 그땐 왜 안되었을까 생각이 드네요…

혹시나 해서 wsl에서 ubuntu 삭제후 처음부터 다시 설치 후 확인하였습니다.
다시 한번 깊이 감사 드립니다.

1 Like

SQL Server 측에 2048비트의 키 길이를 갖는 인증서 설정을 해주시면 SECLEVEL 설정을 하지 않아도 됩니다. 이에 대해서는 다음의 글로 정리했으니 참고하세요.

개발 환경 구성: 680. C# - Ubuntu + Microsoft.Data.SqlClient + SQL Server 2008 R2 연결 방법 - TLS 1.2 지원 (sysnet.pe.kr)

1 Like