Microsoft MVP성태의 닷넷 이야기
개발 환경 구성: 254. SQL 서버 역시 SSL 3.0/TLS 1.0만을 지원하는 듯! [링크 복사], [링크+제목 복사]
조회: 18908
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 
(연관된 글이 2개 있습니다.)
(시리즈 글이 6개 있습니다.)
.NET Framework: 490. System.Data.SqlClient는 SSL 3.0/TLS 1.0만 지원하는 듯!
; https://www.sysnet.pe.kr/2/0/1833

개발 환경 구성: 254. SQL 서버 역시 SSL 3.0/TLS 1.0만을 지원하는 듯!
; https://www.sysnet.pe.kr/2/0/1835

.NET Framework: 2127. C# - Ubuntu + Microsoft.Data.SqlClient + SQL Server 2008 R2 연결 방법
; https://www.sysnet.pe.kr/2/0/13364

개발 환경 구성: 678. openssl로 생성한 인증서를 SQL Server의 암호화 인증서로 설정하는 방법
; https://www.sysnet.pe.kr/2/0/13368

개발 환경 구성: 680. C# - Ubuntu + Microsoft.Data.SqlClient + SQL Server 2008 R2 연결 방법 - TLS 1.2 지원
; https://www.sysnet.pe.kr/2/0/13370

개발 환경 구성: 682. SQL Server TLS 통신을 위해 사용되는 키 길이 확인 방법
; https://www.sysnet.pe.kr/2/0/13372




SQL 서버 역시 SSL 3.0/TLS 1.0만을 지원하는 듯!

지난 글에서 살펴본 것처럼,

System.Data.SqlClient는 SSL 3.0/TLS 1.0만 지원하는 듯!
; https://www.sysnet.pe.kr/2/0/1833

클라이언트가 이미 TLS 1.1/1.2를 지원하지 않고 있기 때문에 서버에서의 설정은 사실 무의미합니다. 그래도 한번 현상을 재현이나 해볼까요? ^^

우선, SQL 서버 측에 보안 통신을 위한 인증서를 등록해 보겠습니다.

"시작" / "Microsoft SQL Server 2008 R2" / "Configuration Tools" / "SQL Server Configuration Manager"를 실행하고 "SQL Server Network Configuration" / "Protocols for [YOUR_SQL_SERVER_INSTANCE]" 노드를 선택하고 마우스 우클릭을 해 "Properties" 메뉴를 선택해 다음의 설정을 해줍니다.

"Flags" 탭
  - "Force Encryption" 옵션을 Yes로 설정

"Certificate"
  - "Certiciate" 목록 상자에서 원하는 인증서를 선택

그런데, 받아 두었던 인증서가 "Certificate" 항목에 나타나지 않는 경우도 있습니다. 왜냐하면, 여기에 인증서가 나타나려면 2가지 조건을 만족해야 하기 때문입니다. (참조: Enabling Certificate for SSL on a SQL Server 2005 Clustered Installation)

  1. Certificates (Local Computer) 영역의 "Personal" 폴더에 위치
  2. 컴퓨터의 FQDN 이름과 일치하는 인증서(AD 참여 서버의 경우 도메인 이름까지 명시)

다행히 "Certificate" 목록 상자에 나오지 않아도 레지스트리를 통한 수작업 설정 방법이 제공되고 있으니 걱정하지 않아도 됩니다. 다음의 글에 따라,

Enabling Certificate for SSL on a SQL Server 2005 Clustered Installation
; http://blogs.msdn.com/b/jorgepc/archive/2008/02/19/enabling-certificates-for-ssl-connection-on-sql-server-2005-clustered-installation.aspx

Setting up SSL encryption for SQL Server using certificates ? Issues, tips & tricks
; http://thesqldude.com/2012/04/21/setting-up-ssl-encryption-for-sql-server-using-certificates-issues-tips-tricks/

"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQLServer\SuperSocketNetLib" 레지스트리 경로에 해당 인증서의 "Thumbprint" 값을 직접 입력하면 됩니다.

Name: Certificate
Type: REG_SZ
Data: ...[Your Certificate's Thumbprint]... (예: 1e385500fc7415f7843d83796b36b83450758c9e)

Thumbprint 값은 인증서 관리 콘솔에서 해당 인증서의 속성 창을 통해 구할 수 있는데, "공백 문자"가 포함되어 있기 때문에 메모장 등을 이용해 공백을 제거한 후 레지스트리에 설정해야 합니다.

결국, 다음의 2가지 처리를 해주시면 SQL 서버는 보안 통신을 할 수 있게 됩니다.

  1. "Force Encryption" 옵션을 Yes로 설정
  2. ...\SuperSocketNetLib 레지스트리 키의 "Certificate" 값에 인증서의 Thumbprint 값 입력

이 외에 주의 사항으로 해당 인증서의 개인 키 파일에 대해 SQL Server 프로세스의 실행 계정이 접근 가능해야 한다는 것입니다. 예를 들어, 제 경우에 SQL Server를 "Network Service" 계정으로 구동하는데 이로 인해 다음과 같이 (인증서 우클릭, "All Tasks" / "Manage Private Keys..." 메뉴 선택) 인증서의 개인키에 대한 접근 권한에 "Read"를 부여해야 합니다.

tls12_sql_1.png

모든 것이 정상적으로 설정되었다면 이제 SQL Service를 재시작합니다. 정상적으로 설정한 경우, 이벤트 로그에 "Event ID == 26013"으로 다음과 같은 항목을 볼 수 있습니다.

Log Name:      Application
Source:        MSSQLSERVER
Date:          2015-01-03 오후 4:33:09
Event ID:      26013
Task Category: Server
Level:         Information
Keywords:      Classic
User:          N/A
Computer:      win2008r2.testad.com
Description:
The certificate [Cert Hash(sha1) "1CB297B8F148FB061E43B3A09D0C524B75151457"] was successfully loaded for encryption.




자, 그럼 이제 TLS 제약을 좀 해볼까요? ^^

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols]

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0]

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Client]
"DisabledByDefault"=dword:00000001

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Server]
"Enabled"=dword:00000000
"DisabledByDefault"=dword:00000001

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0]

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Client]
"DisabledByDefault"=dword:00000001

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Server]
"Enabled"=dword:00000000
"DisabledByDefault"=dword:00000001

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0]

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Client]
"DisabledByDefault"=dword:00000001

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Server]
"Enabled"=dword:00000000
"DisabledByDefault"=dword:00000001

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1]

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Client]
"DisabledByDefault"=dword:00000001

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Server]
"Enabled"=dword:00000000
"DisabledByDefault"=dword:00000001

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2]

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client]
"DisabledByDefault"=dword:00000000
"Enabled"=dword:00000001

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server]
"Enabled"=dword:00000001
"DisabledByDefault"=dword:00000000

위의 레지스트리 등록은 SSL 2.0/3.0, TLS 1.0/1.1을 비활성화하고 TLS 1.2만을 활성화시킵니다. 이렇게 하고 SQL 서비스를 재시작하면 이제 Event ID == 17182, 26014 등의 오류 항목이 이벤트 로그에 남는 것을 보게 됩니다.

Log Name:      Application
Source:        MSSQLSERVER
Date:          2015-01-03 오전 7:55:44
Event ID:      17182
Task Category: Server
Level:         Error
Keywords:      Classic
User:          N/A
Computer:      win2008r2.testad.com
Description:
TDSSNIClient initialization failed with error 0x80092004, status code 0x80. Reason: Unable to initialize SSL support. Cannot find object or property.

Log Name:      Application
Source:        MSSQLSERVER
Date:          2015-01-03 오전 7:55:44
Event ID:      26014
Task Category: Server
Level:         Error
Keywords:      Classic
User:          N/A
Computer:      win2008r2.testad.com
Description:
Unable to load user-specified certificate [Cert Hash(sha1) "1E385500FC7415F7843D83796B36B83450758C9E"]. The server will not accept a connection. You should verify that the certificate is correctly installed. See "Configuring Certificate for Use by SSL" in Books Online

이 상태에서 SSL 3.0이나,

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols]

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0]

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Server]
"Enabled"=dword:00000001

TLS 1.0에 대해,

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols]

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0]

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Server]
"Enabled"=dword:00000001

둘 중의 하나라도 Server 레지스트리 키를 Enabled == 1로 설정하면 다시 SQL Server는 정상적으로 서비스가 됩니다.




어찌 보면, 자연스러운 것이 아닐까 생각됩니다. 클라이언트 측에서 SSL 3.0/TLS 1.0만을 사용해 접속하는 데 SQL 서버 측에서 그 프로토콜들을 모두 막아버리면 통신할 방법이 없으니까요.

검색을 해보니, 누군가도 TLS 1.0, SSL 3.0 관련한 문제를 결국 그 중 하나를 살려두는 것으로 해결(?)했다고 합니다.

Sql server service wont start after disabling TLS 1.0 and SSL 3.0 on windows
; http://answers.flyppdevportal.com/categories/sqlserver/sqlsecurity.aspx?ID=5f543d1f-9483-49bb-9c65-999f287eaefa

여기서 문제는? IIS 서버와 SQL 서버를 함께 설치한 경우입니다. IIS 서버를 위해 TLS 1.2 강제 설정을 했는데, 그것이 SQL 서버까지 영향을 미친 것입니다.

제가 몇몇 조합을 해보니, 이런 경우는 TLS 1.0은 살려두면서 "DisableByDefault" 설정을 1로 해두면 IIS의 TLS 1.2 접속은 강제하면서 SQL 서버는 정상적으로 TLS 1.0 서비스를 했습니다.

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0]

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Client]
"DisabledByDefault"=dword:00000000

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Server]
"Enabled"=dword:00000001
"DisabledByDefault"=dword:00000001

아쉽게도 DisabledByDefault 옵션에 대해 Microsoft의 공식 문서가 없어서 정확히 어떤 차이점으로 인해 그렇게 되는지는 알 수 없었습니다.

마지막으로, 테스트를 하다 보니 Client 역할에 대해서도 제법 많은 서비스들이 TLS 1.2만 강제한 경우 문제가 발생했습니다. 따라서, 기존 서비스들에 영향을 최소화하면서 IIS TLS 1.2 강제를 위해 다음과 같은 정도로 레지스트리 구성을 하면 좋을 것 같습니다.

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols]

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0]

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Client]
"DisabledByDefault"=dword:00000001

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Server]
"Enabled"=dword:00000000
"DisabledByDefault"=dword:00000001

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0]

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Server]
"Enabled"=dword:00000001
"DisabledByDefault"=dword:00000001

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0]

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Server]
"Enabled"=dword:00000001
"DisabledByDefault"=dword:00000001

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1]

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Server]
"Enabled"=dword:00000001
"DisabledByDefault"=dword:00000001

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2]

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server]
"Enabled"=dword:00000001
"DisabledByDefault"=dword:00000000

그런데, 아직도 의아스러운 점이 있다면? 마이크로소프트 직원에 의하면,

SSL Cipher Suites used with SQL Server
; https://techcommunity.microsoft.com/t5/sql-server-blog/ssl-cipher-suites-used-with-sql-server/ba-p/383303

"
What the best cipher suite to use is negotiated by SSL/TLS and depends upon the cipher suites supported by the OS on the client and the server
...[생략]...
Determine the highest level protocol mutually supported by the client and the server.
The currently recognised protocols are, from highest to lowest: TLS1.1, TLS1.0, SSL3.0, SSL2.0
"


라고 하는 것으로 봐서 SQL Server/Client 레벨에서가 아닌 운영체제 지원 여부에 따라 TLS/SSL을 자유롭게 선택할 수 있는 듯 싶은데, 왜 SQL 서버가 SSL 3.0/TLS 1.0을 막았을 때 서비스가 안되는 것인지... 그 부분은 여전히 설명이 안되는 것 같습니다.




[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]

[연관 글]






[최초 등록일: ]
[최종 수정일: 6/13/2023]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 




1  2  3  4  5  6  7  8  [9]  10  11  12  13  14  15  ...
NoWriterDateCnt.TitleFile(s)
13406정성태9/4/20233558VS.NET IDE: 186. Visual Studio Community 버전의 라이선스
13405정성태9/3/20233984닷넷: 2138. C# - async 메서드 호출 원칙
13404정성태8/29/20233527오류 유형: 876. Windows - 키보드의 등호(=, Equals sign) 키가 눌리지 않는 경우
13403정성태8/21/20233329오류 유형: 875. The following signatures couldn't be verified because the public key is not available: NO_PUBKEY EB3E94ADBE1229CF
13402정성태8/20/20233407닷넷: 2137. ILSpy의 nuget 라이브러리 버전 - ICSharpCode.Decompiler
13401정성태8/19/20233635닷넷: 2136. .NET 5+ 환경에서 P/Invoke의 성능을 높이기 위한 SuppressGCTransition 특성 [1]
13400정성태8/10/20233488오류 유형: 874. 파이썬 - pymssql을 윈도우 환경에서 설치 불가
13399정성태8/9/20233465닷넷: 2135. C# - 지역 변수로 이해하는 메서드 매개변수의 값/참조 전달
13398정성태8/3/20234294스크립트: 55. 파이썬 - pyodbc를 이용한 SQL Server 연결 사용법
13397정성태7/23/20233792닷넷: 2134. C# - 문자열 연결 시 string.Create를 이용한 GC 할당 최소화
13396정성태7/22/20233501스크립트: 54. 파이썬 pystack 소개 - 메모리 덤프로부터 콜 스택 열거
13395정성태7/20/20233416개발 환경 구성: 685. 로컬에서 개발 중인 ASP.NET Core/5+ 웹 사이트에 대해 localhost 이외의 호스트 이름으로 접근하는 방법
13394정성태7/16/20233370오류 유형: 873. Oracle.ManagedDataAccess.Client - 쿼리 수행 시 System.InvalidOperationException
13393정성태7/16/20233557닷넷: 2133. C# - Oracle 데이터베이스의 Sleep 쿼리 실행하는 방법
13392정성태7/16/20233446오류 유형: 872. Oracle - ORA-01031: insufficient privileges
13391정성태7/14/20233490닷넷: 2132. C# - sealed 클래스의 메서드를 callback 호출했을 때 인라인 처리가 될까요?
13390정성태7/12/20233444스크립트: 53. 파이썬 - localhost 호출 시의 hang 현상
13389정성태7/5/20233471개발 환경 구성: 684. IIS Express로 호스팅하는 웹을 WSL 환경에서 접근하는 방법
13388정성태7/3/20233601오류 유형: 871. 윈도우 탐색기에서 열리지 않는 zip 파일 - The Compressed (zipped) Folder '[...].zip' is invalid. [1]파일 다운로드1
13387정성태6/28/20233643오류 유형: 870. _mysql - Commands out of sync; you can't run this command now
13386정성태6/27/20233711Linux: 61. docker - 원격 제어를 위한 TCP 바인딩 추가
13385정성태6/27/20233931Linux: 60. Linux - 외부에서의 접속을 허용하기 위한 TCP 포트 여는 방법
13384정성태6/26/20233657.NET Framework: 2131. C# - Source Generator로 해결하는 enum 박싱 문제파일 다운로드1
13383정성태6/26/20233418개발 환경 구성: 683. GPU 런타임을 사용하는 Colab 노트북 설정
13382정성태6/25/20233475.NET Framework: 2130. C# - Win32 API를 이용한 윈도우 계정 정보 (예: 마지막 로그온 시간)파일 다운로드1
13381정성태6/25/20233867오류 유형: 869. Fatal Python error: init_fs_encoding: failed to get the Python codec of the filesystem encoding
1  2  3  4  5  6  7  8  [9]  10  11  12  13  14  15  ...