Service Fabric 클러스터의 X.509 인증서 기반 인증
이 문서에서는 Service Fabric 클러스터 보안에 대해 소개한 내용을 보완하고, Service Fabric 클러스터의 인증서 기반 인증에 대해 자세히 설명합니다. 이 글을 읽는 독자들이 기본적인 보안 개념뿐만 아니라 클러스터의 보안을 제어하기 위해 Service Fabric이 공개하는 컨트롤에 대해서도 잘 알고 있다고 가정합니다.
이 제목 아래에서 다루는 토픽은 다음과 같습니다.
- 인증서 기반 인증 기본 사항
- ID 및 해당 역할
- 인증서 구성 규칙
- 문제 해결 및 FAQ(자주 묻는 질문)
인증서 기반 인증 기본 사항
간단하게 복습하자면, 보안에서 인증서는 엔터티(주체)에 대한 정보를 비대칭 암호화 키 쌍의 소유에 바인딩하기 위한 도구로써 공개 키 암호화의 핵심을 구성합니다. 인증서로 나타내는 키는 데이터를 보호하거나 키 소유자의 ID를 증명하는 데 사용할 수 있습니다. PKI(공개 키 인프라) 시스템과 함께 사용할 경우 인증서는 인터넷 도메인의 소유권 또는 인증서 발급자(인증 기관 또는 CA라고도 하는)에 의해 부여된 특정 권한과 같은 해당 주체의 추가적 특성을 나타낼 수 있습니다. 인증서의 일반적인 애플리케이션은 TLS(전송 계층 보안) 암호화 프로토콜을 지원하여 컴퓨터 네트워크를 통해 안전하게 통신할 수 있게 하는 것입니다. 구체적으로 말하면, 클라이언트와 서버는 인증서를 사용하여 통신의 프라이버시 및 무결성을 보장하고 상호 인증을 수행합니다.
또한 Service Fabric에서 클러스터의 기본 계층(페더레이션)은 참여 노드의 안정적이고 안전한 네트워크를 달성하기 위해 TLS(여러 프로토콜 중에서)를 기반으로 합니다. Service Fabric 클라이언트 API를 통해 클러스터에 연결하는 경우 TLS까지 사용하여 트래픽을 보호하고 당사자의 ID를 설정합니다. 구체적으로 말하면, Service Fabric에서 인증에 사용할 경우 인증서를 사용하여 a) 인증서 자격 증명의 발표자가 인증서의 프라이빗 키를 소유하고 있거나 b) 인증서의 SHA-1 해시('지문')가 클러스터 정의에 포함된 선언과 일치하거나 c) 인증서의 고유한 주체 일반 이름이 클러스터 정의에 포함된 선언과 일치하고 인증서의 발급자가 알려져 있거나 신뢰할 수 있다는 것을 증명하는 데 사용할 수 있습니다.
위의 목록에서 'b'를 흔히 '지문 고정'이라고도 하며, 이때 선언은 특정 인증서를 참조하고 인증 체계의 강도는 다른 인증서와 동일한 해시 값을 생성하지만 다른 모든 측면에서 여전히 유효하며 잘 형성된 개체인 인증서를 만드는 것은 계산상 불가능하다는 것을 전제로 합니다. 항목 'c'는 인증서를 선언하는 대체 형식을 나타내며, 체계의 강도는 인증서 주체와 발급 기관에 따라 결정됩니다. 이 경우 선언은 인증서 클래스를 참조하며, 특성이 같은 두 인증서는 완전히 같은 것으로 간주됩니다.
다음 섹션에서는 Service Fabric 런타임 런타임에서 인증서를 사용하고 유효성을 검사하여 클러스터 보안을 보장하는 방법을 심층적으로 설명합니다.
ID 및 해당 역할
인증 또는 통신 채널 보안에 대해 자세히 알아보기 전에, 참여하는 작업자 및 이들이 클러스터에서 하는 역할부터 살펴보는 것이 좋습니다.
- Service Fabric 런타임('시스템'): 클러스터를 나타내는 추상화 및 기능을 제공하는 서비스 세트입니다. 시스템 인스턴스 간의 클러스터 내 통신을 뜻할 때에는 '클러스터 ID'라는 용어를 사용하고, 클러스터가 클러스터 외부의 트래픽을 받는 사람/대상이라는 뜻으로 사용될 때에는 '서버 ID'라는 용어를 사용합니다.
- 호스트된 애플리케이션('애플리케이션'): 클러스터에서 오케스트레이션되고 실행되는 클러스터 소유자가 제공하는 코드
- 클라이언트: 클러스터 구성에 따라 클러스터에 연결하고 클러스터에서 기능을 실행할 수 있는 엔터티입니다. 각각 '사용자'와 '관리자'로 권한 수준을 구분합니다. '사용자' 클라이언트는 주로 읽기 전용 작업으로 제한되고(모든 읽기 전용 기능은 아님) '관리자' 클라이언트는 클러스터의 기능에 제한 없이 액세스할 수 있습니다. (자세한 내용은 Service Fabric 클러스터의 보안 역할을 참조하세요.)
- (Azure 전용) Service Fabric 클러스터의 작업 및 관리를 위한 컨트롤을 오케스트레이션하고 노출하는 Service Fabric 서비스이며 간단하게 '서비스'라고 부릅니다. 환경에 따라 '서비스'는 Azure Service Fabric 리소스 공급자를 뜻할 수도 있고, Service Fabric 팀에서 소유하고 운영하는 다른 리소스 공급자를 뜻할 수도 있습니다.
보안 클러스터에서, 각 역할은 미리 정의된 역할 이름 및 해당 자격 증명의 쌍으로 선언된 고유한 자체 ID를 사용하여 구성할 수 있습니다. Service Fabric은 자격 증명을 인증서 또는 도메인 기반 서비스 주체로 선언할 수 있습니다. (Windows/Kerberos 기반 ID도 지원되지만 이 문서의 범위를 벗어나는 내용입니다. Service Fabric 클러스터의 Windows 기반 보안을 참조하세요.) Azure 클러스터에서는 클라이언트 역할이 Microsoft Entra ID 기반 ID로 선언될 수도 있습니다.
위에서 언급했듯이, Service Fabric 런타임은 클러스터에서 '관리자' 및 '사용자'의 두 가지 권한 수준을 정의합니다. 관리자 클라이언트와 '시스템' 구성 요소 둘 다 '관리자' 권한으로 작동하므로 서로 구분할 수 없습니다. 클러스터에 대한 연결을 설정하면 Service Fabric 런타임은 인증된 호출자에게 두 역할 중 하나를 후속 권한 부여의 기본으로 부여합니다. 인증에 대한 자세한 내용은 다음 섹션에서 살펴보겠습니다.
인증서 구성 규칙
유효성 검사 규칙
Service Fabric 클러스터의 보안 설정은 원칙적으로 다음과 같은 측면을 설명합니다.
- 인증 유형: 클러스터의 바꿀 수 없는 특성인 생성 시간입니다. 이러한 설정의 예로 'ClusterCredentialType', 'ServerCredentialType'이 있으며, 허용되는 값은 'none', 'x509' 또는 'windows'입니다. 이 문서에서는 x509 형식 인증을 집중적으로 살펴봅니다.
- (인증) 유효성 검사 규칙: 이러한 설정은 클러스터 소유자가 설정하며 특정 역할에 대해 수락할 자격 증명을 설명합니다. 자세한 사례는 아래에서 살펴보겠습니다.
- 인증 결과를 조정하거나 미묘하게 변경하는 데 사용되는 설정: 여기에는 인증서 해지 목록의 적용을 제한하거나 제한 해제하는 플래그가 포함됩니다.
참고 항목
아래에 제공된 클러스터 구성 예제는 XML 형식의 클러스터 매니페스트에서 발췌한 것으로, 이 문서에서 설명하는 Service Fabric 기능을 직접 지원하는 가장 잘 요약된 형식입니다. 클러스터 정의(독립 실행형 json 클러스터 매니페스트 또는 Azure Resource Mangement 템플릿)의 JSON 표현에서 동일한 설정을 직접 표현할 수 있습니다.
인증서 유효성 검사 규칙은 다음 요소로 구성됩니다.
- 해당 역할: 클라이언트, 관리자 클라이언트(권한 있는 역할)
- 지문 또는 주체 일반 이름으로 선언된 역할에 대해 수락된 자격 증명
지문 기반 인증서 유효성 검사 선언
지문 기반 유효성 검사 규칙에서, 클러스터에 대한 연결을 요청하는 호출자가 제공하는 자격 증명은 다음과 같이 유효성이 검사됩니다.
- 자격 증명이 유효하고 잘 형성된 인증서: 체인을 만들 수 있으며, 서명이 일치합니다.
- 인증서의 시간이 유효:(NotBefore <= 현재 < NotAfter)
- 인증서의 SHA-1 해시가 대/소문자 구분 없이 모든 공백을 제외한 문자열을 비교하는 선언과 일치합니다.
체인 구축 또는 유효성 검사 중에 발생하는 모든 트러스트 오류는 만료된 인증서를 제외하고 지문 기반 선언에 대해 억제됩니다. 다만 이 상황에 대한 프로비전도 있습니다. 구체적으로 말해서, 인증서는 키 쌍의 봉투(Envelope)일 뿐이고 보안은 클러스터 소유자가 프라이빗 키를 보호하는 수단을 설정했다는 전제 하에 알 수 없거나 오프라인인 해제 상태, 신뢰할 수 없는 루트, 잘못된 키 사용, 부분 체인은 치명적이지 않은 오류로 간주됩니다.
아래는 클러스터 매니페스트에서 발췌한 것으로, 지문 기반 유효성 검사 규칙의 예를 잘 보여줍니다.
<Section Name="Security">
<Parameter Name="ClusterCredentialType" Value="X509" />
<Parameter Name="ServerAuthCredentialType" Value="X509" />
<Parameter Name="AdminClientCertThumbprints" Value="d5ec...4264" />
<Parameter Name="ClientCertThumbprints" Value="7c8f...01b0" />
<Parameter Name="ClusterCertThumbprints" Value="abcd...1234,ef01...5678" />
<Parameter Name="ServerCertThumbprints" Value="ef01...5678" />
</Section>
위의 각 항목은 앞에서 설명한 대로 특정 ID를 참조합니다. 또한 각 항목은 쉼표로 구분된 문자열 목록으로 여러 값을 지정할 수 있습니다. 이 예제에서 들어오는 자격 증명의 유효성 검사가 성공하는 즉시 SHA-1 지문이 'd5ec...4264'인 인증서 발표자에게 '관리자' 역할이 부여됩니다. 반대로, 인증서 '7c8f...01b0'으로 인증하는 호출자에게는 주로 읽기 전용 작업으로 제한되는 '사용자' 역할이 부여됩니다. 지문이 'abcd...1234' 또는 'ef01...5678'인 인증서를 제공하는 인바운드 호출자는 클러스터의 피어 노드로 허용됩니다. 마지막으로, 클러스터의 관리 엔드포인트에 연결하는 클라이언트는 서버 인증서의 지문이 'ef01...5678'일 것으로 예상합니다.
앞서 언급했듯이, Service Fabric은 만료된 인증서를 수락하기 위한 프로비전을 만듭니다. 그 이유는 인증서의 수명이 제한되어 있으며 (특정 인증서 인스턴스를 참조하는) 지문을 통해 인증서를 선언하면 인증서가 만료되어 클러스터에 연결하지 못하거나 클러스터가 완전히 축소될 수 있기 때문입니다. 지문으로 고정된 인증서를 순전하는 것을 잊거나 소홀히 하는 경우가 많은데, 다시 복구하기는 매우 어렵습니다.
따라서 클러스터 소유자는 다음과 같이 지문을 사용하여 선언된 자체 서명된 인증서는 유효한 것으로 간주하도록 명시적으로 선언할 수 있습니다.
<Section Name="Security">
<Parameter Name="AcceptExpiredPinnedClusterCertificate" Value="true" />
</Section>
이 동작은 CA에서 발급한 인증서로 확장되지 않습니다. 확장되면 손상되어 만료된 것으로 알려진 해지된 인증서가 CA의 인증서 해지 목록에 더 이상 표시되지 않은 즉시 '유효'한 인증서가 되기 때문에 보안 위험이 발생할 수 있습니다. 자체 서명된 인증서를 사용하면 클러스터 소유자는 인증서의 프라이빗 키를 보호하는 유일한 책임자로 간주됩니다. 반면 CA에서 발급한 인증서의 경우 클러스터 소유자는 인증서가 언제 어떻게 선언 또는 손상되었는지 인식하지 못할 수 있습니다.
일반 이름 기반 인증서 유효성 검사 선언
일반 이름 기반 선언에는 다음 형식 중 하나가 사용됩니다.
- 주체 일반 이름(단독)
- 발급자 고정을 사용하는 주체 일반 이름
두 가지 선언 스타일을 보여주기 위해 클러스터 매니페스트에서 발췌한 내용부터 살펴보겠습니다.
<Section Name="Security/ServerX509Names">
<Parameter Name="server.demo.system.servicefabric.azure-int" Value="" />
</Section>
<Section Name="Security/ClusterX509Names">
<Parameter Name="cluster.demo.system.servicefabric.azure-int" Value="1b45...844d,d7fe...26c8,3ac7...6960,96ea...fb5e" />
</Section>
선언은 각각 서버 및 클러스터 ID를 참조합니다. CN 기반 선언의 클러스터 매니페스트에는 표준 '보안'과 분리된 자체 섹션이 있습니다. 두 선언 모두 'Name'은 인증서의 고유한 주체 일반 이름을 나타내고, 'Value' 필드는 다음과 같이 예상되는 발급자를 나타냅니다.
- 첫 번째 예제의 선언에서는 서버 인증서의 고유한 주체 일반 이름 요소가 "server.demo.system.servicefabric.azure-int" 문자열과 일치해야 한다고 서술합니다. 빈 'Value' 필드는 서버 인증서의 유효성이 검사되는 노드/머신에서 인증서 체인의 루트를 신뢰할 수 있어야 한다는 것을 나타내는 필드입니다. Windows에서는 인증서가 '신뢰할 수 있는 루트 CA' 저장소에 설치된 인증서에 연결할 수 있습니다.
- 두 번째 예제의 선언에서는 인증서의 일반 이름이 "cluster.demo.system.servicefabric.azure-int" 문자열과 일치하고 인증서의 직접 발급자 지문이 'Value' 필드의 쉼표로 구분된 항목 중 하나와 일치하는 경우 인증서 발표자가 클러스터에서 피어 노드로 허용된다고 서술합니다. (이 규칙 형식을 '발급자 고정을 사용하는 일반 이름'이라고 합니다.)
두 예제 모두 인증서의 체인이 생성되고 오류가 없을 것으로 예상됩니다. 즉, 해지 오류, 부분 체인 또는 시간이 유효하지 않은 트러스트 오류는 치명적인 것으로 간주되고 인증서 유효성 검사가 실패합니다. 발급자를 고정하면 '신뢰할 수 없는 루트' 상태를 치명적이지 않은 오류로 간주하게 됩니다. 클러스터 소유자는 권한 부여된/수락된 발급자 세트를 자체 PKI로 제한할 수 있으므로 겉보기와는 다르게 더 엄격한 형태의 유효성 검사입니다.
인증서 체인이 구축된 후에는 주체가 원격 이름으로 선언된 표준 TLS/SSL 정책과 비교하여 유효성이 검사됩니다. 인증서의 주체 일반 이름 또는 주체 대체 이름이 클러스터 매니페스트의 CN 선언과 일치하면 인증서가 일치하는 것으로 간주됩니다. 이때 와일드카드가 지원되며, 문자열 일치는 대소문자를 구분하지 않습니다.
(위에서 설명한 시퀀스가 인증서에 의해 선언된 각 키 사용 유형에 대해 실행될 수 있음을 명확히 해야 합니다. 인증서가 클라이언트 인증 키 사용을 지정하는 경우 체인이 클라이언트 역할에 대해 먼저 빌드되고 평가됩니다. 성공하면 평가가 완료되고 유효성 검사가 성공합니다. 인증서에 클라이언트 인증 사용이 없거나 유효성 검사가 실패한 경우 Service Fabric 런타임은 서버 인증을 위해 체인을 빌드하고 평가합니다.)
이 예제를 완료하는 다음 발췌문에서는 일반 이름으로 클라이언트 인증서를 선언합니다.
<Section Name="Security/AdminClientX509Names">
<Parameter Name="admin.demo.client.servicefabric.azure-int" Value="1b45...844d,d7fe...26c8,3ac7...6960,96ea...fb5e" />
</Section>
<Section Name="Security/ClientX509Names">
<Parameter Name="user.demo.client.servicefabric.azure-int" Value="1b45...844d,d7fe...26c8,3ac7...6960,96ea...fb5e" />
</Section>
위의 선언은 각각 관리자 및 사용자 ID에 해당합니다. 이 방식으로 선언된 인증서의 유효성 검사는 클러스터 및 서버 인증서에 대한 이전 예제에서 설명한 그대로입니다.
참고 항목
일반 이름 기반 선언의 목적은 순환을 단순화하고 클러스터 인증서를 관리하는 것입니다. 그러나 클러스터의 가용성 및 보안을 보장하기 위해 다음 권장 사항을 준수하는 것이 좋습니다.
- 신뢰할 수 있는 루트에 발급자를 고정합니다.
- 다른 PKI의 발급자를 혼합하지 않습니다.
- 모든 예상 발급자가 인증서 선언에 나열되도록 합니다. 발급자가 일치하지 않으면 유효성 검사가 실패합니다.
- PKI의 인증서 정책 엔드포인트를 검색 가능하고, 사용 가능하고, 액세스 가능하도록 만듭니다. 즉, AIA, CRL 또는 OCSP 엔드포인트가 리프 인증서에 선언되면 액세스하여 인증서 체인 구축을 완료할 수 있습니다.
이렇게 하면 X.509 인증서로 보호된 클러스터에서 연결 요청을 받는 즉시 Service Fabric 런타임은 위에서 설명한 것처럼 클러스터의 보안 설정을 사용하여 원격 파티의 자격 증명 유효성을 검사합니다. 유효성 검사가 성공하면 호출자/원격 대상이 인증된 것으로 간주됩니다. 자격 증명이 여러 유효성 검사 규칙과 일치하면 런타임은 호출자에게 일치하는 규칙 중 가장 높은 권한 역할을 부여합니다.
프레젠테이션 규칙
이전 섹션에서는 인증서로 보호된 클러스터에서 인증이 작동하는 방식을 설명했습니다. 이 섹션에서는 Service Fabric 런타임 자체가 클러스터 내 통신에 사용하는 인증서를 검색하고 로드하는 방법을 설명합니다. 이것을 "프레젠테이션" 규칙이라고 합니다.
유효성 검사 규칙과 마찬가지로, 프레젠테이션 규칙은 지문 또는 일반 이름으로 표현되는 역할 및 연결된 자격 증명 선언을 지정합니다. 유효성 검사 규칙과 달리, 일반 이름 기반 선언에는 발급자 고정에 대한 프로비전이 없으므로, 유연성과 성능이 우수합니다. 프레젠테이션 규칙은 각 고유 노드 유형에 대한 클러스터 매니페스트의 'NodeType' 섹션에 선언됩니다. 설정은 클러스터의 보안 섹션에서 분할되어 각 노드 유형이 단일 섹션에서 전체 구성을 갖는 것을 허용합니다. Azure Service Fabric 클러스터에서, 노드 유형 인증서 선언은 기본적으로 클러스터 정의의 보안 섹션에서 해당 설정으로 지정됩니다.
지문 기반 인증서 프레젠테이션 선언
앞서 설명했듯이, Service Fabric 런타임은 클러스터 내 다른 노드의 피어 역할과 클러스터 관리 작업을 위한 서버 역할을 구분합니다. 원칙적으로 이러한 설정을 구분하여 구성할 수 있지만 실제로는 일치하는 경향이 있습니다. 이 문서의 나머지 부분에서는 간단한 설명을 위해 설정이 일치하는 것으로 가정합니다.
클러스터 매니페스트에서 발췌한 다음 내용을 살펴보겠습니다.
<NodeTypes>
<NodeType Name="nt1vm">
<Certificates>
<ClusterCertificate X509FindType="FindByThumbprint" X509FindValue="cc71...1984" X509FindValueSecondary="49e2...19d6" X509StoreName="my" Name="ClusterCertificate" />
<ServerCertificate X509FindValue="cc71...1984" Name="ServerCertificate" />
<ClientCertificate X509FindValue="cc71...1984" Name="ClientCertificate" />
</Certificates>
</NodeType>
</NodeTypes>
'ClusterCertificate' 요소는 선택적 매개 변수('X509FindValueSecondary') 또는 적절한 기본값이 있는 매개 변수('X509StoreName')를 포함한 전체 구성 요소를 보여주고, 다른 선언은 축약형을 보여줍니다. 위의 클러스터 인증서 선언은 'nt1vm' 형식의 노드 보안 설정이 주 인증서 'cc71..1984' 및 보조 인증서 '49e2..19d6'으로 초기화됨을 서술합니다. 두 인증서는 LocalMachine'My' 인증서 저장소(또는 Linux의 해당 경로 var/lib/sfcerts)에서 찾을 수 있습니다.
일반 이름 기반 인증서 프레젠테이션 선언
아래 예제와 같은 주체 일반 이름으로 노드 형식 인증서를 선언할 수도 있습니다.
<NodeTypes>
<NodeType Name="nt1vm">
<Certificates>
<ClusterCertificate X509FindType="FindBySubjectName" X509FindValue="demo.cluster.azuredocpr.system.servicefabric.azure-int" Name="ClusterCertificate" />
</Certificates>
</NodeType>
</NodeTypes>
두 선언 유형과 관련하여, Service Fabric 노드는 시작 시 구성을 읽고, 지정된 인증서를 찾아 로드하고, NotBefore 특성의 내림차순으로 정렬합니다. 만료된 인증서는 무시되고, 목록의 첫 번째 요소는 이 노드에서 시도한 모든 Service Fabric 연결의 클라이언트 자격 증명으로 선택됩니다. (사실, Service Fabric은 가장 최근에 발급된 인증서를 선호합니다.)
참고 항목
7.2.445(7.2 CU4) 이전 버전에서 Service Fabric은 곧 만료되는 인증서(가장 먼 ‘NotAfter’ 속성이 있는 인증서)를 선택했습니다.
일반 이름 기반 프레젠테이션 선언의 경우 해당 주체 일반 이름이 선언의 X509FindValue(또는 X509FindValueSecondary) 필드와 대소문자까지 정확하게 동일한 경우 인증서가 일치하는 것으로 간주됩니다. 와일드카드 일치뿐만 아니라 대소문자를 구분하지 않는 문자열 비교를 지원하는 유효성 검사 규칙과 다른 점입니다.
기타 인증서 구성 설정
앞에서 Service Fabric 클러스터의 보안 설정은 인증 코드를 약간 변경할 수 있다고 했습니다. Service Fabric 클러스터 설정에 대한 문서에서는 포괄적인 최신 설정 목록을 보여주지만, 여기서는 특별한 보안 설정 몇 가지를 부연 설명하여 인증서 기반 인증에 대한 모든 것을 살펴보겠습니다. 각 설정의 의도, 기본값/동작, 인증에 미치는 영향 및 허용되는 값을 설명하겠습니다.
앞서 설명했듯이, 인증서 유효성 검사는 항상 인증서 체인을 만들고 평가하는 것을 의미합니다. CA 발급 인증서의 경우 이 간단한 OS API 호출은 일반적으로 PKI 발급, 응답 캐싱 등의 다양한 엔드포인트에 대한 여러 아웃바운드 호출을 수반합니다. 인증서 유효성 검사 호출이 Service Fabric 클러스터에서 확산되는 것을 감안할 때, PKI의 엔드포인트에서 문제가 발생하면 클러스터의 가용성이 저하되거나 전체적으로 중단될 수 있습니다. 아웃바운드 호출은 억제할 수 없지만(자세한 내용은 FAQ 섹션에서 아래 참조) 다음 설정을 사용하여 CRL 호출 실패로 인한 유효성 검사 오류를 마스킹할 수 있습니다.
- CrlCheckingFlag - "보안" 섹션에서 UINT로 변환된 문자열입니다. 이 설정의 값은 Service Fabric에서 체인 만들기 동작을 변경하여 인증서 체인 상태 오류를 마스킹하는 데 사용됩니다. Win32 CryptoAPI CertGetCertificateChain 호출에 'dwFlags' 매개 변수로 전달되며, 함수에서 수락하는 유효한 플래그 조합으로 설정할 수 있습니다. 값이 0이면 Service Fabric 런타임에서 트러스트 상태 오류를 무시합니다. 이 값은 보안 약점을 상당히 노출하므로 권장하지 않습니다. 기본값은 0x40000000(CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT)입니다.
사용 시기: 로컬 테스트 또는 인증서를 지원하도록 완전히 형성되지 않은/적절한 공개 키 인프라가 없는 자체 서명된 인증서에 사용합니다. PKI 간에 전환하는 동안 에어 갭 환경에서도 완화 수단으로 사용할 수 있습니다.
사용 방법: 캐시된 URL에만 액세스하도록 해지 검사를 강제하는 예제를 살펴보겠습니다. 전제:
#define CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLY 0x80000000
그러면 클러스터 매니페스트의 선언은 다음과 같습니다.
<Section Name="Security">
<Parameter Name="CrlCheckingFlag" Value="0x80000000" />
</Section>
- IgnoreCrlOfflineError - "보안" 섹션에서 기본값이 'false'인 부울입니다. '해지 오프라인' 체인 구축 오류 상태(또는 후속 체인 정책 유효성 검사 오류 상태)를 표시하지 않기 위한 바로 가기를 나타냅니다.
사용 시기: 로컬 테스트 또는 적절한 PKI의 백업이 없는 개발자 인증서에 사용합니다. 에어 갭 환경에서 또는 PKI를 사용할 수 없는 것으로 알려진 경우에 완화 수단으로 사용합니다.
사용 방법:
<Section Name="Security">
<Parameter Name="IgnoreCrlOfflineError" Value="true" />
</Section>
다음은 중요한 기타 설정(모두 "보안" 섹션 아래에 있음)입니다.
- AcceptExpiredPinnedClusterCertificate - 지문 기반 인증서 유효성 검사에 대한 섹션에서 설명하며, 만료된 자체 서명된 클러스터 인증서를 수락합니다.
- CertificateExpirySafetyMargin - 인증서의 NotAfter 타임스탬프까지 남은 간격(분)이며, 이 시간 동안 인증서가 만료될 위험이 있는 것으로 간주됩니다. Service Fabric은 클러스터 인증서를 모니터링하면서 남아 있는 가용성에 대한 상태 보고서를 주기적으로 내보냅니다. '안전' 간격 내에서는 이러한 상태 보고서가 '경고' 상태로 상승됩니다. 기본값은 30일입니다.
- CertificateHealthReportingInterval - 클러스터 인증서의 남은 시간 유효성에 대한 상태 보고서의 빈도를 제어합니다. 보고서는 이 간격마다 한 번만 내보내집니다. 이 값은 초 단위로 표시되며, 기본값은 8시간입니다.
- EnforcePrevalidationOnSecurityChanges - 부울이며, 보안 설정 변경 내용을 감지할 때 클러스터 업그레이드 동작을 제어합니다. 'true'로 설정하면 클러스터 업그레이드는 프레젠테이션 규칙과 일치하는 인증서 중 하나 이상이 해당 유효성 검사 규칙을 통과할 수 있도록 합니다. 새 설정이 임의의 노드에 적용되기 전에 사전 유효성 검사가 실행되지만 업그레이드를 시작할 때 Cluster Manager 서비스의 기본 복제본을 호스트하는 노드에서만 실행됩니다. 이 문서의 작성 시점을 기준으로 설정의 기본값은 'false'이며, 런타임 버전이 7.1로 시작하는 새 Azure Service Fabric 클러스터에서는 'true'로 설정됩니다.
엔드투엔드 시나리오(예제)
프레젠테이션 규칙, 유효성 검사 규칙 및 조정 플래그를 살펴보았는데, 이러한 것들이 어떻게 함께 작동할까요? 이 섹션에서는 안전한 클러스터 업그레이드를 위해 보안 설정을 활용하는 방법을 설명하는 두 가지 엔드투엔드 예제를 살펴보겠습니다. 이 문서에서는 Service Fabric에서 인증서를 적절하게 관리하는 방법에 대해 다루지 않으므로, 해당 내용을 보려면 관련 문서를 검색하세요.
프레젠테이션 규칙과 유효성 검사 규칙을 분리할 경우 두 규칙을 나눌 수 있는지, 그 결과는 무엇인지에 대한 의문(또는 우려)이 생깁니다. 노드의 인증 인증서를 선택해도 다른 노드의 유효성 검사 규칙을 통과하지 못할 수 있습니다. 사실, 이러한 불일치가 인증 관련 인시던트의 주요 원인입니다. 동시에 이러한 규칙을 분리하면 클러스터의 보안 설정을 변경하는 업그레이드 중에 클러스터가 계속 작동할 수 있습니다. 첫 번째 단계로 유효성 검사 규칙을 먼저 보강하면 클러스터의 모든 노드가 새 설정에 수렴하지만 여전히 현재 자격 증명을 사용합니다.
Service Fabric 클러스터에서 업그레이드는 (최대 5개) '업그레이드 도메인' 또는 UD를 통해 진행됩니다. 현재 UD의 노드만 지정된 시간에 업그레이드/변경되고, 클러스터의 가용성이 허용되는 경우에만 업그레이드가 다음 UD로 진행됩니다. (자세한 내용은 동일한 항목에 대한 Service Fabric 클러스터 업그레이드 및 기타 문서를 참조하세요.) 인증서/보안 변경은 클러스터에서 노드를 격리하거나 클러스터를 쿼럼 손실에 처하게 할 수 있으므로 특히 위험합니다.
노드의 보안 설정을 설명하기 위해 다음과 같은 표기 방법을 사용합니다.
Nk: {P:{TP=A}, V:{TP=A}}
- 'Nk'는 업그레이드 도메인 k의 노드를 나타냅니다.
- 'P'는 노드의 현재 프레젠테이션 규칙을 나타냅니다(클러스터 인증서만 참조한다고 가정).
- 'V'는 노드의 현재 유효성 검사 규칙을 나타냅니다(클러스터 인증서만 해당)
- 'TP=A'는 지문 기반 선언(TP)을 나타내고 'A'는 인증서 지문입니다.
- 'CN=B'는 일반 이름 기반 선언(CN)을 나타내고 'B'는 인증서의 주체 일반 이름이 됩니다.
지문을 통해 선언된 클러스터 인증서 순환
다음은 2단계 업그레이드를 사용하여 지문을 통해 선언된 보조 클러스터 인증서를 안전하게 도입하는 방법입니다. 첫 번째 단계에서는 유효성 검사 규칙에 새 인증서 선언을 도입하고, 두 번째 단계에서는 프레젠테이션 규칙에 이 선언을 도입합니다.
- 초기 상태: N0 = {P:{TP=A}, V:{TP=A}}, ... Nk = {P:{TP=A}, V:{TP=A}} - 클러스터가 미사용 상태이고, 모든 노드가 공통 구성을 공유합니다.
- 업그레이드 도메인 0 완료 시: N0 = {P:{TP=A}, V:{TP=A, TP=B}}, ... Nk = {P:{TP=A}, V:{TP=A}} - UD0의 노드는 인증서 A를 나타내고 인증서 A 또는 B를 수락합니다. 그 외의 모든 노드는 인증서 A만을 나타내고 수락합니다.
- 마지막 업그레이드 도메인 완료 시: N0 = {P:{TP=A}, V:{TP=A, TP=B}}, ... Nk = {P:{TP=A}, V:{TP=A, TP=B}} - 모든 노드가 인증서 A를 나타내고, 인증서 A 또는 B를 수락합니다.
이 시점에서 클러스터는 다시 평형 상태이기 때문에, 다음과 같이 보안 설정 업그레이드/변경의 두 번째 단계가 시작될 수 있습니다.
- 업그레이드 도메인 0 완료 시: N0 = {P:{TP=A, TP=B}, V:{TP=A, TP=B}}, ... Nk = {P:{TP=A}, V:{TP=A, TP=B}} - UD0의 노드는 B를 나타내기 시작하고, B는 클러스터의 다른 노드에서 허용됩니다.
- 마지막 업그레이드 도메인 완료 시: N0 = {P:{TP=A, TP=B}, V:{TP=A, TP=B}}, ... Nk = {P:{TP=A, TP=B}, V:{TP=A, TP=B}} - 모든 노드가 인증서 B를 나타내도록 전환했습니다. 이제 후속 업그레이드 세트를 통해 클러스터 정의에서 인증서 A를 사용 중지/제거할 수 있습니다.
클러스터를 지문에서 일반 이름 기반 인증서 선언으로 변환
인증서 선언 유형을 지문에서 일반 이름으로 변경할 때에도 위와 동일한 패턴을 따릅니다. 유효성 검사 규칙은 동일한 클러스터 정의의 지문과 일반 이름을 통해 부여된 역할의 인증서를 선언할 수 있습니다. 반면 프레젠테이션 규칙은 한 가지 선언 형식만 허용합니다. 클러스터 인증서를 지문에서 일반 이름으로 변환하는 안전한 방법은 먼저 지문을 통해 의도한 대상 인증서를 도입한 다음, 해당 선언을 일반 이름 기반 인증서로 변경하는 것입니다. 다음 예제에서는 지문 'A' 및 주체 일반 이름 'B'가 동일한 인증서를 참조하는 것으로 가정합니다.
- 초기 상태: N0 = {P:{TP=A}, V:{TP=A}}, ... Nk = {P:{TP=A}, V:{TP=A}} - 클러스터가 미사용 상태이고 모든 노드가 공통 구성을 공유하며, A는 기본 인증서 지문이 됩니다.
- 업그레이드 도메인 0 완료 시: N0 = {P:{TP=A}, V:{TP=A, CN=B}}, ... Nk = {P:{TP=A}, V:{TP=A}} - UD0의 노드는 인증서 A를 나타내고 지문 A 또는 일반 이름 B를 사용하는 인증서를 수락합니다. 그 외의 모든 노드는 인증서 A만을 나타내고 수락합니다.
- 마지막 업그레이드 도메인 완료 시: N0 = {P:{TP=A}, V:{TP=A, CN=B}}, ... Nk = {P:{TP=A}, V:{TP=A, CN=B}} - 모든 노드가 인증서 A를 나타내고, 인증서 A(TP) 또는 B(CN)를 수락합니다.
이 시점에서 후속 업그레이드를 통해 프레젠테이션 규칙을 변경할 수 있습니다.
- 업그레이드 도메인 0 완료 시: N0 = {P:{CN=B}, V:{TP=A, CN=B}}, ... Nk = {P:{TP=A}, V:{TP=A, CN=B}} - UD0의 노드는 CN이 찾은 인증서 B를 나타내고, 지문 A 또는 일반 이름 B를 사용하는 인증서를 수락합니다. 그 외의 모든 노드는 지문을 통해 선택한 인증서 A만을 나타내고 수락합니다.
- 마지막 업그레이드 도메인 완료 시: N0 = {P:{CN=B}, V:{TP=A, CN=B}}, ... Nk = {P:{CN=B}, V:{TP=A, CN=B}} - 모든 노드가 CN이 찾은 인증서 B를 나타내고, 인증서 A(TP) 또는 B(CN)를 수락합니다.
2단계를 완료하면 클러스터가 일반적인 이름 기반 인증서로 변환되고, 후속 클러스터 업그레이드에서 지문 기반 유효성 검사 선언을 제거할 수 있습니다.
참고 항목
Azure Service Fabric 클러스터에서, 위의 워크플로는 Service Fabric 리소스 공급자를 통해 오케스트레이션됩니다. 클러스터 소유자는 표시된 규칙(프레젠테이션 또는 유효성 검사)에 따라 클러스터에 인증서를 프로비저닝할 책임이 있으며 여러 단계에서 변경을 수행하는 것이 좋습니다.
인증서를 관리하고 Service Fabric 클러스터에 프로비저닝하는 내용은 별도의 문서에서 다루겠습니다.
문제 해결 및 FAQ(자주 묻는 질문)
Service Fabric 클러스터의 인증 관련 문제를 디버깅하기는 쉽지 않지만, 다음 힌트와 팁이 도움이 되기를 바랍니다. 조사를 시작하는 가장 쉬운 방법은 클러스터의 노드에서 Service Fabric 이벤트 로그를 검사하는 것입니다. 이러한 로그를 통해 증상을 파악하고, 켜져 있지만 인접한 노드 중 하나에 연결할 수 없는 노드를 알아낼 수 있습니다. Windows에서 중요한 이벤트는 일반적으로 각각 'Applications and Services Logs\Microsoft-ServiceFabric\Admin' 또는 'Operational' 채널에 기록됩니다. CAPI2 로깅을 사용하도록 설정하여 인증서 유효성 검사, CRL/CTL 검색 등에 대한 자세한 정보를 캡처하면 도움이 될 수도 있습니다. 문제 재현을 완료한 후에는 다시 사용하지 않도록 설정해야 합니다. 정보가 너무 많이 캡처될 수 있습니다.
클러스터의 매니페스트 자체에서 인증 문제가 발생하는 일반적인 증상은 다음과 같습니다.
- 노드가 다운/순환됨
- 연결 시도가 거부됨
- 연결 시도가 시간 초과됨
각 증상은 서로 다른 문제로 인해 발생할 수 있으며, 근본 원인이 같아도 증상은 다를 수 있습니다. 따라서 일반적인 문제의 간단한 샘플과 문제 해결을 위한 권장 사항을 설명하겠습니다.
노드가 메시지를 교환할 수 있지만 연결할 수는 없습니다. 연결 시도가 종료될 수 있는 원인은 '인증서 불일치' 오류입니다. Service Fabric 간 연결의 당사자 중 하나가 제시하는 인증서가 받는 사람의 유효성 검사 규칙에 실패합니다. 다음 오류 중 하나가 동반될 수 있습니다.
0x80071c44 -2147017660 FABRIC_E_SERVER_AUTHENTICATION_FAILED
추가 진단/조사를 수행하려면 연결을 시도하는 각 노드에서 어떤 인증서가 제시되고 있는지 확인합니다. 인증서를 검사하고 유효성 검사 규칙을 시도하고 에뮬레이션합니다(지문 또는 일반 이름이 같은지 확인, 발급자 지문(지정한 경우) 확인).
다음과 같은 또 다른 일반적인 오류 코드가 동반될 수 있습니다.
0x800b0109 -2146762487 CERT_E_UNTRUSTEDROOT
이 경우 인증서는 일반 이름으로 선언되며, 다음 중 하나가 적용됩니다.
- 발급자가 고정되지 않았으며, 루트 인증서를 신뢰할 수 없습니다.
- 발급자가 고정되었지만 이 인증서의 직접 발급자 지문이 선언에 포함되어 있지 않습니다.
노드가 켜져 있지만 다른 노드에 연결할 수 없습니다. 다른 노드가 장애 노드에서 인바운드 트래픽을 수신하지 않습니다. 이 경우 로컬 노드에서 인증서 로드가 실패할 수 있습니다. 다음 오류를 찾습니다.
인증서를 찾을 수 없음 - 프레젠테이션 규칙에 선언된 인증서를 LocalMachine\My(또는 지정된) 인증서 저장소의 내용으로 해결할 수 있도록 합니다. 가능한 오류 원인은 다음과 같습니다.
- 지문 선언의 문자가 잘못됨
- 인증서가 설치되지 않음
- 인증서가 만료됨
- 일반 이름 선언에 'CN=' 접두사가 있음
- 선언은 와일드카드를 지정하고 인증서 저장소에 정확한 일치 항목이 없음(선언: CN=*.mydomain.com, 실제 인증서: CN=server.mydomain.com)
알 수 없는 자격 증명 - 인증서에 해당하는 누락된 프라이빗 키를 나타내며 일반적으로 다음 오류 코드가 동반됩니다.
0x8009030d -2146893043 SEC_E_UNKNOWN_CREDENTIALS 0x8009030e -2146893042 SEC_E_NO_CREDENTIALS
이 문제를 해결하려면 프라이빗 키가 있는지 확인합니다. SFAdmins에게 프라이빗 키에 대한 'read|execute' 액세스 권한이 부여되었는지 확인합니다.
잘못된 공급자 유형 - CNG(Crypto New Generation) 인증서("Microsoft Software Key Storage Provider")를 나타냅니다. 현재 Service Fabric은 CAPI1 인증서만 지원합니다. 일반적으로 다음가 같은 오류 코드가 동반됩니다.
0x80090014 -2146893804 NTE_BAD_PROV_TYPE
이 문제를 해결하려면 CAPI1(예: "Microsoft Enhanced RSA and AES Cryptographic Provider") 공급자를 사용하여 클러스터 인증서를 다시 만듭니다. 암호화 공급자에 대한 자세한 내용은 암호화 공급자 이해를 참조하세요.