Service Fabric 클러스터에서 인증서 관리
이 문서에서는 Azure Service Fabric 클러스터에서 통신을 보호하는 데 사용되는 인증서의 관리에 대해 다룹니다. Service Fabric 클러스터 보안에 대한 소개와 Service Fabric의 X.509 인증서 기반 인증에 대한 설명을 보완합니다.
필수 조건
시작하기 전에, 기본적인 보안 개념과 Service Fabric이 클러스터의 보안을 구성하기 위해 공개하는 컨트롤에 대해 잘 알고 있어야 합니다.
부인
이 문서에서는 인증서 관리의 이론적 측면과 서비스, 기술 등의 세부 사항을 다루는 실습 예제를 쌍으로 제공합니다. 이 문서의 대상 그룹은 대부분 Microsoft 내부자이므로 이 문서에서는 Azure와 관련된 서비스, 기술 및 제품을 참조합니다. 특정 Microsoft 관련 세부 정보가 적용되지 않는 경우 마지막 부분에 있는 댓글 섹션에 확인 또는 지침을 요청하세요.
인증서 관리의 정의
Service Fabric 클러스터의 X.509 인증서 기반 인증 문서의 설명처럼 인증서는 기본적으로 비대칭 키 쌍을 비대칭 키 쌍이 나타내는 엔터티를 설명하는 특성과 바인딩하는 암호화 개체입니다.
그러나 인증서는 수명이 유한하고 손상되기 쉬운 소멸성 개체이기도 합니다. 인증서가 실수로 공개되거나 악용되면 보안 관점에서 인증서는 더 이상 쓸모 없게 될 수 있습니다. 이러한 특징 때문에 인증서를 정기적으로 변경하거나 보안 인시던트에 대한 조치로 인증서를 변경해야 합니다.
그 자체로 별도의 토픽인 인증서 관리의 또 다른 측면은 인증서 프라이빗 키 또는 인증서를 조달 및 프로비저닝에 관련된 엔터티의 ID을 지키는 비밀을 보호하는 것입니다.
인증서 관리는 인증서를 획득하고 인증서가 필요한 곳에 안전하게 전송하는 데 사용되는 프로세스 및 프로시저를 말합니다.
등록, 정책 설정, 권한 부여 컨트롤과 같은 일부 관리 작업은 이 문서에서 다루지 않습니다. 프로비전, 갱신, 다시 키 지정 또는 해지와 같은 다른 작업이 Service Fabric과 관련되는 경우는 우연히 있습니다. 그럼에도 불구하고 이러한 작업을 이해하면 클러스터를 제대로 보호하는 데 도움이 될 수 있으므로 이 문서에서는 이러한 작업을 다룹니다.
여러분의 직접적인 목표는 아마도 클러스터의 중단 없는 가용성을 보장하기 위해 인증서 관리를 최대한 자동화하는 것입니다. 또한 이 프로세스는 사용자 개입이 없으므로 보안에 대한 확신을 원할 것입니다. Service Fabric 클러스터를 사용하면 이 목표를 달성할 수 있습니다.
이 문서의 나머지 부분에서는 인증서 관리를 분석한 다음, 자동 롤오버 사용을 집중적으로 살펴봅니다.
특히 다음 토픽을 다룹니다.
- 소유자와 플랫폼 간의 특성 분리에 대한 가정
- 인증서 발급부터 사용까지 긴 인증서 파이프라인
- 인증서 회전: 이유, 방법 및 시기
- 어떤 문제가 발생할 수 있나요?
이 문서에서는 다음 토픽을 다루지 않습니다.
- 도메인 이름 보호 및 관리
- 인증서에 등록
- 인증서 발급을 적용하기 위한 권한 부여 컨트롤 설정
이러한 토픽에 대한 내용은 선호하는 PKI(공개 키 인프라) 서비스의 RA(등록 인증 기관)를 참조하세요. Microsoft 내부 독자인 경우 Azure Security에 문의할 수 있습니다.
인증서 관리에 포함된 역할 및 엔터티
Service Fabric 클러스터의 보안 방식은 "클러스터 소유자가 선언하고 Service Fabric 런타임이 집행"하는 방식입니다. 즉, 클러스터의 기능에 참여하는 ID의 인증서, 키 또는 기타 자격 증명은 거의 대부분 서비스 자체에서 제공되지 않습니다. 모두 클러스터 소유자가 선언합니다. 또한 클러스터 소유자는 클러스터에 인증서를 프로비저닝하고, 필요에 따라 인증서를 갱신하고, 항상 인증서의 보안을 확인해야 합니다.
구체적으로 말하면 클러스터 owner는 다음을 확인해야 합니다.
- 클러스터 매니페스트의 NodeType 섹션에 선언된 인증서는 프레젠테이션 규칙에 따라 해당 유형의 각 노드에서 찾을 수 있습니다.
- 이전 글머리 기호에 선언된 인증서는 해당 프라이빗 키가 포함된 상태로 설치됩니다.
- 프레젠테이션 규칙에 선언된 인증서는 유효성 검사 규칙을 통과해야 합니다.
Service Fabric은 다음과 같은 책임을 맡습니다.
- 클러스터 정의의 선언과 일치하는 인증서 찾기
- 필요에 따라 Service Fabric으로 제어되는 엔터티에 해당 프라이빗 키에 대한 액세스 권한 부여
- 설정된 보안 모범 사례 및 클러스터 정의에 따라 엄격한 인증서 유효성 검사
- 임박한 인증서 만료 시 또는 인증서 유효성 검사의 기본 단계를 수행하는 데 실패할 때 경고
- 호스트의 기본 구성이 클러스터 정의의 인증서 관련 측면을 (일정 수준) 충족하는지 유효성 검사
인증서 관리 부담(활성 작업)은 클러스터 owner에게만 있습니다. 다음 섹션에서는 사용 가능한 메커니즘과 이러한 메커니즘이 클러스터에 미치는 영향을 포함하여 각 관리 작업을 자세히 살펴봅니다.
인증서 경험
Service Fabric 클러스터의 컨텍스트에서 발급부터 사용까지 인증서의 진행 상황을 신속하게 살펴보겠습니다.
도메인 소유자가 PKI의 RA를 사용하여 뒤따르는 인증서와 연결하고 싶은 도메인 또는 주체를 등록합니다. 그러면 인증서는 도메인 또는 주체의 소유권에 대한 증거를 구성합니다.
또한 도메인 소유자는 지정된 도메인 또는 주체로 인증서 등록을 요청할 자격이 있는 엔터티인 권한 있는 요청자 ID를 RA에 지정합니다.
그런 다음, 권한 있는 요청자가 비밀 관리 서비스를 통해 인증서에 등록합니다. Azure에서 선택하는 비밀 관리 서비스는 안전하게 저장하고 권한 있는 엔터티가 비밀 및 인증서를 검색하도록 허용하는 Azure Key Vault입니다. 또한 Key Vault는 연결된 인증서 정책에 구성된 대로 인증서를 갱신하고 키를 다시 지정합니다. Key Vault는 Microsoft Entra ID를 ID 공급자로 사용합니다.
권한 있는 검색기 또는 프로비전 에이전트는 프라이빗 키를 포함하여 키 자격 증명 모음에서 인증서를 검색하고, 클러스터를 호스트하는 머신에 설치합니다.
(각 노드에서 높은 권한으로 실행되는) Service Fabric 서비스는 허용된 Service Fabric 엔터티가 인증서에 액세스할 권한을 부여합니다. 그들은 로컬 그룹에 의해 지정되고 ServiceFabricAdministrators와 ServiceFabricAllowedUsers 간에 분할됩니다.
Service Fabric 런타임은 페더레이션을 설정하거나 인증된 클라이언트에서 인바운드 요청을 인증하기 위해 인증서를 액세스하고 사용합니다.
프로비저닝 에이전트는 키 자격 증명 모음 인증서를 모니터링하다가 인증서 갱신을 감지하면 프로비저닝 흐름을 트리거합니다. 그러면 클러스터 소유자가 클러스터 정의를 업데이트하고, 필요한 경우 인증서를 롤오버하라는 의도를 표시합니다.
또한 프로비저닝 에이전트 또는 클러스터 소유자는 사용하지 않는 인증서를 정리하고 삭제해야 합니다.
이 문서의 목적을 위해 이전 시퀀스의 처음 두 단계는 대부분 관련이 없습니다. 유일한 연관성은 인증서의 주체 일반 이름이 클러스터 정의에 선언된 DNS 이름이라는 것입니다.
인증서 발급 및 프로비전 흐름은 다음 다이어그램에 나와 있습니다.
지문으로 선언된 인증서
주체 일반 이름으로 선언된 인증서
인증서 등록
인증서 등록 토픽은 Key Vault 설명서에서 자세히 설명합니다. 연속성과 보다 쉬운 참조를 위해 개요가 여기에 포함되어 있습니다.
Azure를 컨텍스트로 계속 사용하고 Azure Key Vault를 비밀 관리 서비스로 사용하는 권한 있는 인증서 요청자는 자격 증명 모음 소유자가 부여하는 자격 증명 모음에 대한 인증서 관리 권한 이상이 있어야 합니다. 그러면 요청자가 다음과 같이 인증서에 등록합니다.
요청자는 Key Vault에서 인증서의 도메인/주체, 원하는 발급자, 키 유형과 길이, 의도하는 키 사용량 등을 지정하는 인증서 정책을 만듭니다. 자세한 내용은 Azure Key Vault의 인증서를 참조하세요.
요청자는 이전 단계에서 지정한 정책을 사용하여 동일한 자격 증명 모음에 인증서를 만듭니다. 이렇게 하면 자격 증명 모음 개체로 키 쌍이 생성되고, 프라이빗 키로 서명된 후 서명을 받기 위해 지정된 발급자에게 전달되는 인증서 서명 요청이 생성됩니다.
발급자 또는 CA(인증 기관)가 서명된 인증서로 회신하면 결과가 자격 증명 모음에 병합되고, 다음과 같이 인증서 데이터를 사용할 수 있습니다.
{vaultUri}/certificates/{name}
: 공개 키 및 메타데이터를 포함하는 인증서{vaultUri}/keys/{name}
: 인증서의 프라이빗 키로, 암호화 작업(래핑/래핑 해제, 서명/확인)에 사용할 수 있습니다.{vaultUri}/secrets/{name}
: 프라이빗 키가 포함된 인증서로, 보호되지 않은 PFX 또는 PEM 파일로 다운로드할 수 있습니다.
키 자격 증명 모음의 인증서에는 정책을 공유하는 인증서 인스턴스의 시간순 목록이 포함되어 있습니다. 인증서 버전은 정책의 수명 및 갱신 특성에 따라 만들어집니다. 자격 증명 모음 인증서는 주체 또는 도메인/DNS 이름을 공유하지 않는 것이 좋습니다. 주체는 같지만 발급자, 키 사용과 같은 다른 특성은 상당히 다른 다양한 자격 증명 모음 인증서에서 인증서 인스턴스를 프로비저닝하면 클러스터에서 방해가 될 수 있습니다. 이 시점에서 인증서가 자격 증명 모음에 있으며 사용할 수 있습니다. 이제 프로세스의 나머지 부분을 살펴보겠습니다.
인증서 프로비저닝
키 자격 증명 모음에서 프라이빗 키가 포함된 인증서를 검색하여 클러스터의 각 호스트에 설치하는 엔터티인 프로비저닝 에이전트를 언급했습니다. (Service Fabric는 인증서를 프로비저닝하지 않습니다.)
이 문서의 컨텍스트에서 클러스터는 Azure VM(가상 머신) 또는 가상 머신 확장 집합 컬렉션에 호스트됩니다. Azure에서는 다음 메커니즘을 사용하여 자격 증명 모음의 인증서를 VM/VMSS에 프로비저닝할 수 있습니다. 이전과 마찬가지로 키 자격 증명 모음 소유자가 프로비저닝 에이전트에 키 자격 증명 모음에 대한 비밀 가져오기 권한을 부여했다고 가정합니다.
애드혹: 운영자가 키 자격 증명 모음에서(PFX/PKCS #12 또는 PEM으로) 인증서를 검색하고 각 노드에 설치합니다.
보안에서 가용성에 이르는 여러 가지 이유로 애드혹 메커니즘을 사용하지 않는 것이 좋습니다. 이에 대해서는 여기서 자세히 설명하지 않습니다. 자세한 내용은 Azure 가상 머신 확장 집합에 대한 FAQ를 참조하세요.
배포하는 동안 가상 머신 확장 집합 비밀로: 컴퓨팅 서비스는 운영자 대신 자사 ID를 사용하여 Azure 가상 머신 확장 집합에 대한 FAQ에 설명된 것처럼 템플릿 배포 사용 자격 증명 모음에서 인증서를 검색하여 가상 머신 확장 집합의 각 노드에 설치합니다.
참고 항목
이 방법을 사용하면 버전이 지정된 비밀만 프로비저닝할 수 있습니다.
Key Vault VM 확장 사용. 이렇게 하면 관찰된 인증서를 정기적으로 새로 고쳐 버전이 없는 선언을 사용하여 인증서를 프로비저닝할 수 있습니다. 이 경우 VM/VMSS는 관찰된 인증서를 포함하고 있는 키 자격 증명 모음에 대한 액세스 권한이 부여된 ID인 관리 ID가 있어야 합니다.
VMSS/컴퓨팅 기반 프로비저닝은 보안 및 가용성 이점을 제공하지만 제한도 있습니다. 기본적으로 인증서를 버전 관리 비밀로 선언해야 합니다. 이 요구 사항은 VMSS/컴퓨팅 기반 프로비전을 지문으로 선언된 인증서로 보호되는 클러스터에만 적합하게 만듭니다.
반대로 Key Vault VM 확장 기반 프로비전은 항상 관찰된 각 인증서의 최신 버전을 설치합니다. 따라서 주체 일반 이름으로 선언된 인증서로 보호되는 클러스터에만 적합합니다. 인스턴스(지문)에 의해 선언된 인증서에는 자동 새로 고침 프로비저닝 메커니즘(예: Key Vault VM 확장)을 사용하면 안 됩니다. 가용성이 손실될 위험이 크기 때문입니다.
다른 프로비저닝 메커니즘이 더 있지만, 여기에 설명된 방법은 현재 Azure Service Fabric 클러스터에 허용되는 옵션입니다.
인증서 소비 및 모니터링
앞서 설명한 것처럼, Service Fabric 런타임은 클러스터 정의에 선언된 인증서를 찾고 사용하는 일을 담당합니다. Service Fabric 클러스터의 X.509 인증서 기반 인증 문서에 Service Fabric이 프레젠테이션 및 유효성 검사 규칙을 구현하는 방법이 자세히 설명되어 있으므로 여기서는 이 내용을 다시 검토하지 않습니다. 이 문서에서는 액세스, 권한 부여 및 모니터링을 살펴보겠습니다.
Service Fabric의 인증서는 페더레이션 레이어의 상호 인증부터 관리 엔드포인트에 대한 TLS(전송 계층 보안) 인증까지 다양한 용도로 사용됩니다. 이렇게 하려면 다양한 구성 요소 또는 시스템 서비스에서 인증서의 프라이빗 키에 액세스할 수 있어야 합니다. Service Fabric 런타임은 인증서 저장소를 정기적으로 검사하여 알려진 각 프레젠테이션 규칙과 일치하는 항목을 찾습니다.
일치하는 각 인증서에 해당하는 프라이빗 키가 있으며, 임의 액세스 제어 목록은 권한이 필요한 ID에 부여된 권한(보통은 Read 및 Execute)을 포함하도록 업데이트됩니다.
이 프로세스를 비공식적으로 ACLing이라고 합니다. 이 프로세스는 1분 주기로 실행되며 설정 또는 엔드포인트 인증서로 암호화하는 데 사용되는 인증서와 같은 애플리케이션 인증서도 포함합니다. ACLing는 프레젠테이션 규칙을 따르며, 따라서 지문으로 선언된 인증서와 결과 클러스터 구성 업데이트가 없는 자동으로 새로 고침되는 인증서에는 액세스할 수 없습니다.
인증서 교체
참고 항목
IETF(Internet Engineering Task Force) RFC 3647에는 갱신이란 교체되는 인증서와 동일한 특성을 가진 인증서 발급이라고 공식적으로 정의되어 있습니다. 발급자, 주체의 공개 키 및 정보는 보존됩니다. 다시 키 지정은 발급자의 변경 가능 여부에 대한 제한 없이 새 키 쌍을 사용하여 인증서를 발급하는 것입니다. 이 구분이 중요할 수 있으므로(예: 발급자 고정을 사용하여 주체 일반 이름으로 선언된 인증서), 이 문서에서는 두 시나리오를 모두 포함하기 위해 중립 용어인 회전을 사용합니다. 갱신이 비공식적으로 사용되는 경우 키를 다시 지정하는 것을 의미합니다.
앞서 설명한 것처럼, Key Vault는 자동 인증서 회전을 지원합니다. 즉, 관련 인증서 정책은 키 자격 증명 모음에서 인증서를 회전할 때 만료 전 일 수 또는 총 수명의 백분율에 따라 지정 시간을 정의합니다. 프로비저닝 에이전트는 이 시점 이후에 호출되어야 하며, 현재-이전 인증서가 만료되기 전에 이 새 인증서를 클러스터의 모든 노드에 배포해야 합니다.
Service Fabric은 현재 클러스터에서 사용되는 인증서의 만료 날짜가 미리 결정된 간격보다 빨리 발생하는 경우 상태 경고를 발생시켜 이 프로세스를 지원합니다. 자동 프로비저닝 에이전트인 Key Vault VM 확장은 키 자격 증명 모음 인증서를 관찰하도록 구성되어 있으며, 정기적으로 키 자격 증명 모음을 폴링하고, 회전을 감지하고, 새 인증서를 검색하고 설치합니다. VM/VMSS 비밀 기능을 통해 발생하는 프로비저닝을 수행하려면 권한 있는 운영자가 새 인증서에 해당하는 버전이 지정된 Key Vault URI로 VM/VMSS를 업데이트해야 합니다.
이제 회전된 인증서가 모든 노드에 프로비저닝됩니다. 클러스터 인증서에 적용되는 회전이 주체 일반 이름으로 선언되었다고 가정하고, 앞으로 어떤 일이 발생하는지 살펴보겠습니다.
클러스터 내의 새 연결뿐만 아니라 클러스터에 대한 새 연결에서 Service Fabric 런타임은 가장 최근에 발급된 일치하는 인증서(NotBefore 속성의 가장 큰 값)를 찾아 선택합니다. 이는 이전 버전의 Service Fabric 런타임에서 변경된 사항입니다.
기존 연결은 활성 상태로 유지되거나, 자연스럽게 만료되거나 종료될 수 있으며, 내부 처리기에 새 일치 항목이 있다는 알림이 제공됩니다.
참고 항목
현재 버전 7.2 CU4 이상에서는 Service Fabric은 NotBefore 속성 값이 가장 큰(가장 최근에 발급된) 인증서를 선택합니다. 7.2 CU4 이전에는 Service Fabric은 NotAfter 값이 가장 큰(가장 최근에 만료된) 유효한 인증서를 선택했습니다.
이는 다음과 같은 중요한 관찰로 변환됩니다.
클러스터 또는 호스트된 애플리케이션의 가용성은 인증서를 회전하는 지시문보다 우선합니다. 클러스터는 결국 새 인증서에 수렴하지만 타이밍은 보장할 수 없습니다. 다음과 같습니다.
회전된 인증서가 이전 인증서를 완전히 대체했다는 사실을 관찰자가 즉시 명확하게 인지하지 못할 수 있습니다. 현재 사용 중인 인증서를 즉시 교체하도록 강제하는 유일한 방법은 호스트 머신을 다시 부팅하는 것입니다. 클러스터의 임대 연결을 구성하는 커널 모드 구성 요소는 영향을 받지 않으므로 Service Fabric 노드를 다시 시작하는 것만으로는 충분하지 않습니다. 또한 VM/VMSS를 다시 시작하면 일시적으로 가용성이 손실될 수 있습니다. 애플리케이션 인증서의 경우 각 애플리케이션 인스턴스만 다시 시작해도 됩니다.
유효성 검사 규칙을 충족하지 않는 키가 재지정된 인증서를 도입하면 효과적으로 클러스터를 중단할 수 있습니다. 이에 대한 가장 일반적인 예는 예기치 않은 발급자의 경우입니다. 클러스터 인증서는 발급자 고정을 사용하여 주체 일반 이름으로 선언되지만, 회전된 인증서는 새로운 또는 미선언 발급자가 발급한 것입니다.
인증서 정리
이번에는 Azure에서 인증서를 명시적으로 제거하기 위한 프로비저닝이 없습니다. 특정 시간에 특정 인증서가 사용되고 있는지 확인하는 것은 일반적으로 중요하지 않은 작업입니다. 이는 클러스터 인증서보다 응용 프로그램 인증서에서 더 어렵습니다. Service Fabric 자체는 프로비저닝 에이전트가 아니라서 어떤 경우에도 사용자가 선언한 인증서를 삭제하지 않습니다. 표준 프로비저닝 메커니즘의 경우:
VM/VMSS 비밀로 선언된 인증서는 VM/VMSS 정의에서 참조되고 키 자격 증명 모음에서 검색할 수 있는 한 프로비저닝됩니다. 키 자격 증명 모음 비밀 또는 인증서를 삭제하면 후속 VM/VMSS 배포가 실패합니다. 마찬가지로 키 자격 증명 모음에서 비밀 버전을 사용하지 않도록 설정하면 비밀 버전을 참조하는 VM/VMSS 배포도 실패합니다.
Key Vault VM 확장을 통해 프로비저닝되는 이전 버전의 인증서는 VM/VMSS 노드에 있을 수도 있고 없을 수도 있습니다. 에이전트는 현재 버전만 검색하여 설치하며, 인증서를 제거하지 않습니다. 일반적으로 매월 발생하는 노드 재이미징은 인증서 저장소를 OS 이미지의 콘텐츠로 초기화므로 이전 버전이 암묵적으로 제거됩니다. 그러나 가상 머신 확장 집합을 스케일 업하면 현재 버전의 관찰된 인증서만 설치됩니다. 따라서 설치된 인증서와 관련하여 노드가 균질할 것으로 가정해서는 안 됩니다.
관리 간소화: 자동 롤오버 예제
지금까지 이 문서에서는 메커니즘과 제한 사항에 대해 설명하고, 복잡한 규칙과 정의에 대해 간략하게 알아보고, 심각한 중단을 예측했습니다. 지금부터는 이 모든 걱정을 해소할 수 있도록 자동 인증서 관리를 설정하겠습니다. PaaS(Platform as a Service) v2 가상 머신 확장 집합에서 실행되는 Azure Service Fabric 클러스터의 컨텍스트에서 다음과 같이 비밀 관리를 위해 Key Vault를 사용하고 관리 ID를 활용해 보겠습니다.
- 인증서의 유효성 검사는 지문 고정에서 주체 + 발급자 고정으로 변경됩니다. 특정 발급자의 특정 주체를 가진 모든 인증서도 똑같이 신뢰할 수 있습니다.
- 인증서는 신뢰할 수 있는 저장소(Key Vault)에/에서 등록/획득되고 에이전트(여기서는 Key Vault VM 확장)에 의해 새로 고침됩니다.
- 인증서 프로비저닝은 배포 시간 및 버전 기반(Azure Compute Resource Provider에서 수행)에서 버전 없는 Key Vault URI를 사용하는 배포 후로 변경됩니다.
- 키 자격 증명 모음에 대한 액세스 권한은 사용자가 할당한 관리 ID를 통해 부여되며, 배포 중에 생성되어 가상 머신 확장 집합에 할당됩니다.
- 배포 후, 에이전트(Key Vault VM 확장)는 가상 머신 확장 집합의 각 노드에서 관찰된 인증서를 폴링하고 새로 고칩니다. Service Fabric이 자동으로 유효한 최신 인증서를 선택하므로 인증서 회전이 완전히 자동화됩니다.
이 시퀀스는 완전히 스크립트가 가능하고 자동화되며, 인증서 자동 롤오버가 구성된 클러스터의 사용자 개입 없는 초기 배포가 가능합니다. 다음 섹션에서는 PowerShell cmdlet과 JSON 템플릿 조각이 혼합된 자세한 단계를 제공합니다. Azure와 상호 작용하는 지원되는 모든 방법을 사용하여 동일한 기능을 달성할 수 있습니다.
참고 항목
이 예제에서는 인증서가 키 자격 증명 모음에 이미 있다고 가정합니다. Key Vault 관리형 인증서를 등록하고 갱신하려면 이 문서의 앞부분에서 설명한 것처럼 필수 수동 단계를 수행해야 합니다. 프로덕션 환경의 경우 Key Vault 관리형 인증서를 사용합니다. Microsoft 내부 PKI와 관련된 샘플 스크립트가 포함되어 있습니다.
참고 항목
인증서 자동 롤오버는 CA에서 발급한 인증서에만 적합합니다. Azure Portal에서 Service Fabric 클러스터를 배포하는 동안 생성된 인증서를 포함하여 자체 서명된 인증서를 사용하는 것은 무의미하지만, 발급자 지문을 리프 인증서와 동일한 것으로 선언하는 경우 로컬 또는 개발자 호스트 배포에서는 여전히 가능합니다.
시작 지점
간단한 설명을 위해 시작 상태가 다음과 같다고 가정합니다.
- Service Fabric 클러스터가 있고, 지문으로 선언된 CA 발급 인증서로 보안이 유지됩니다.
- 인증서는 키 자격 증명 모음에 저장되고 가상 머신 확장 집합 비밀로 프로비저닝됩니다.
- 동일한 인증서를 사용하여 클러스터를 일반 이름 기반 인증서 선언으로 변환하고, 주체와 발급자가 유효성을 검사할 수 있습니다. 그렇지 않은 경우 해당 목적을 위해 발급된 CA 발급 인증서를 획득하고 지문을 사용하여 클러스터 정의에 추가합니다. 이 프로세스는 Azure에서 Service Fabric 클러스터에 대한 인증서를 추가하거나 제거하는 방법에 설명되어 있습니다.
다음은 이러한 상태에 해당하는 템플릿에서 발췌한 JSON입니다. 발췌한 내용에는 여러 필수 설정이 생략되어 있으며 인증서 관련 측면만 보여줍니다.
"resources": [
{ ## VMSS definition
"apiVersion": "[variables('vmssApiVersion')]",
"type": "Microsoft.Compute/virtualMachineScaleSets",
"name": "[variables('vmNodeTypeName')]",
"location": "[variables('computeLocation')]",
"properties": {
"virtualMachineProfile": {
"extensionProfile": {
"extensions": [
{
"name": "[concat('ServiceFabricNodeVmExt','_vmNodeTypeName')]",
"properties": {
"type": "ServiceFabricNode",
"autoUpgradeMinorVersion": true,
"publisher": "Microsoft.Azure.ServiceFabric",
"settings": {
"clusterEndpoint": "[reference(parameters('clusterName')).clusterEndpoint]",
"nodeTypeRef": "[variables('vmNodeTypeName')]",
"dataPath": "D:\\SvcFab",
"durabilityLevel": "Bronze",
"certificate": {
"thumbprint": "[parameters('primaryClusterCertificateTP')]",
"x509StoreName": "[parameters('certificateStoreValue')]"
}
},
"typeHandlerVersion": "1.1"
}
},}},
"osProfile": {
"adminPassword": "[parameters('adminPassword')]",
"adminUsername": "[parameters('adminUsername')]",
"secrets": [
{
"sourceVault": {
"id": "[resourceId('Microsoft.KeyVault/vaults', parameters('keyVaultName'))]"
},
"vaultCertificates": [
{
"certificateStore": "[parameters('certificateStoreValue')]",
"certificateUrl": "[parameters('clusterCertificateUrlValue')]"
},
]}]
},
},
{ ## cluster definition
"apiVersion": "[variables('sfrpApiVersion')]",
"type": "Microsoft.ServiceFabric/clusters",
"name": "[parameters('clusterName')]",
"location": "[parameters('clusterLocation')]",
"certificate": {
"thumbprint": "[parameters('primaryClusterCertificateTP')]",
"x509StoreName": "[parameters('certificateStoreValue')]"
},
}
]
위의 코드를 보면, json [parameters('primaryClusterCertificateTP')]
지문이 있고 Key Vault URI json [parameters('clusterCertificateUrlValue')]
에서 찾은 인증서가 지문을 통해 클러스터의 유일한 인증서로 선언됩니다.
다음으로, 인증서의 자동 롤오버를 적용하는 데 필요한 추가 리소스를 설정하겠습니다.
필수 리소스 설정
앞서 언급했듯이, 가상 머신 확장 집합 비밀로 프로비전된 인증서는 키 자격 증명 모음에서 Microsoft Compute Resource Provider 서비스에 의해 검색됩니다. 이 서비스는 배포 운영자 대신 자사 ID를 사용하여 이 작업을 수행합니다. 이 프로세스는 자동 롤오버에 대해 변경됩니다. 가상 머신 확장 집합에 할당되고 해당 자격 증명 모음의 비밀에 대한 GET 권한이 부여된 관리 ID를 사용하도록 전환할 것입니다.
다음 발췌문은 동시에 배포해야 합니다. 플레이별 분석 및 설명에 대해서만 개별적으로 나열됩니다.
먼저 사용자 할당 ID를 정의합니다(기본값이 예제로 포함되어 있음). 자세한 내용은 공식 설명서를 참조하세요.
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"userAssignedIdentityName": {
"type": "string",
"defaultValue": "sftstuaicus",
"metadata": {
"description": "User-assigned managed identity name"
}
},
},
"variables": {
"vmssApiVersion": "2018-06-01",
"sfrpApiVersion": "2018-02-01",
"miApiVersion": "2018-11-30",
"kvApiVersion": "2018-02-14",
"userAssignedIdentityResourceId": "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('userAssignedIdentityName'))]"
},
"resources": [
{
"type": "Microsoft.ManagedIdentity/userAssignedIdentities",
"name": "[parameters('userAssignedIdentityName')]",
"apiVersion": "[variables('miApiVersion')]",
"location": "[resourceGroup().location]"
},
]}
다음으로, 키 자격 증명 모음 비밀에 대한 액세스 권한을 이 ID에 부여합니다. 최신 정보는 공식 설명서를 참조하세요.
"resources":
[{
"type": "Microsoft.KeyVault/vaults/accessPolicies",
"name": "[concat(parameters('keyVaultName'), '/add')]",
"apiVersion": "[variables('kvApiVersion')]",
"properties": {
"accessPolicies": [
{
"tenantId": "[reference(variables('userAssignedIdentityResourceId'), variables('miApiVersion')).tenantId]",
"objectId": "[reference(variables('userAssignedIdentityResourceId'), variables('miApiVersion')).principalId]",
"dependsOn": [
"[variables('userAssignedIdentityResourceId')]"
],
"permissions": {
"secrets": [
"get",
"list"
]}}]}}]
다음 단계에서는 다음을 수행합니다.
- 사용자 할당 ID를 가상 머신 확장 집합에 할당합니다.
- 가상 머신 확장 집합이 관리 ID 생성 및 키 자격 증명 모음에 대한 액세스 권한 부여 결과에 종속된다고 선언합니다.
- Key Vault VM 확장을 선언하고 시작 시 관찰된 인증서를 검색하도록 요구합니다. 자세한 내용은 Windows용 Key Vault VM 확장 공식 설명서를 참조하세요.
- Key Vault VM 확장에 종속되고 클러스터 인증서 선언을 지문에서 일반 이름으로 변환하도록 Service Fabric VM 확장의 정의를 업데이트합니다.
참고 항목
이러한 변경 내용은 동일한 리소스의 범위에 속하기 때문에 단일 단계로 이루어집니다.
"parameters": {
"kvvmextPollingInterval": {
"type": "string",
"defaultValue": "3600",
"metadata": {
"description": "kv vm extension polling interval in seconds"
}
},
"kvvmextLocalStoreName": {
"type": "string",
"defaultValue": "MY",
"metadata": {
"description": "kv vm extension local store name"
}
},
"kvvmextLocalStoreLocation": {
"type": "string",
"defaultValue": "LocalMachine",
"metadata": {
"description": "kv vm extension local store location"
}
},
"kvvmextObservedCertificates": {
"type": "array",
"defaultValue": [
"https://sftestcus.vault.azure.net/secrets/sftstcncluster",
"https://sftestcus.vault.azure.net/secrets/sftstcnserver"
],
"metadata": {
"description": "kv vm extension observed certificates versionless uri"
}
},
"certificateCommonName": {
"type": "string",
"defaultValue": "cus.cluster.sftstcn.system.servicefabric.azure-int",
"metadata": {
"description": "Certificate Common name"
}
},
},
"resources": [
{
"apiVersion": "[variables('vmssApiVersion')]",
"type": "Microsoft.Compute/virtualMachineScaleSets",
"name": "[variables('vmNodeTypeName')]",
"location": "[variables('computeLocation')]",
"dependsOn": [
"[variables('userAssignedIdentityResourceId')]",
"[concat('Microsoft.KeyVault/vaults/', concat(parameters('keyVaultName'), '/accessPolicies/add'))]"
],
"identity": {
"type": "UserAssigned",
"userAssignedIdentities": {
"[variables('userAssignedIdentityResourceId')]": {}
}
},
"virtualMachineProfile": {
"extensionProfile": {
"extensions": [
{
"name": "KVVMExtension",
"properties": {
"publisher": "Microsoft.Azure.KeyVault",
"type": "KeyVaultForWindows",
"typeHandlerVersion": "1.0",
"autoUpgradeMinorVersion": true,
"settings": {
"secretsManagementSettings": {
"pollingIntervalInS": "[parameters('kvvmextPollingInterval')]",
"linkOnRenewal": false,
"observedCertificates": "[parameters('kvvmextObservedCertificates')]",
"requireInitialSync": true
}
}
}
},
{
"name": "[concat('ServiceFabricNodeVmExt','_vmNodeTypeName')]",
"properties": {
"type": "ServiceFabricNode",
"provisionAfterExtensions" : [ "KVVMExtension" ],
"publisher": "Microsoft.Azure.ServiceFabric",
"settings": {
"certificate": {
"commonNames": [
"[parameters('certificateCommonName')]"
],
"x509StoreName": "[parameters('certificateStoreValue')]"
}
},
"typeHandlerVersion": "1.0"
}
},
] } ## extension profile
}, ## VM profile
"osProfile": {
"adminPassword": "[parameters('adminPassword')]",
"adminUsername": "[parameters('adminUsername')]",
}
}
]
위의 코드에서 명시적으로 나열되지는 않았지만, 키 자격 증명 모음 인증서 URL은 가상 머신 확장 집합의 OsProfile
섹션에서 제거되었습니다.
마지막 단계는 인증서 선언을 지문에서 일반 이름으로 변경하도록 클러스터 정의를 업데이트하는 것입니다. 발급자 지문도 고정하겠습니다.
"parameters": {
"certificateCommonName": {
"type": "string",
"defaultValue": "cus.cluster.sftstcn.system.servicefabric.azure-int",
"metadata": {
"description": "Certificate Common name"
}
},
"certificateIssuerThumbprint": {
"type": "string",
"defaultValue": "1b45ec255e0668375043ed5fe78a09ff1655844d,d7fe717b5ff3593764f4d90654d86e8362ec26c8,3ac7c3cac8de0dd392c02789c8be97474f456960,96ea05926e2e42cc207e358668be2c316857fb5e",
"metadata": {
"description": "Certificate issuer thumbprints separated by comma"
}
},
},
"resources": [
{
"apiVersion": "[variables('sfrpApiVersion')]",
"type": "Microsoft.ServiceFabric/clusters",
"name": "[parameters('clusterName')]",
"location": "[parameters('clusterLocation')]",
"properties": {
"certificateCommonNames": {
"commonNames": [{
"certificateCommonName": "[parameters('certificateCommonName')]",
"certificateIssuerThumbprint": "[parameters('certificateIssuerThumbprint')]"
}],
"x509StoreName": "[parameters('certificateStoreValue')]"
},
]
이제 이전에 언급한 업데이트를 단일 배포에서 실행할 수 있습니다. 해당 부분에서 Service Fabric 리소스 공급자 서비스는 클러스터 인증서를 지문에서 일반 이름으로 변환하는 세그먼트에 설명된 대로, 클러스터 업그레이드를 여러 단계로 분할합니다.
분석 및 관찰
이 섹션에서는 이 문서 전체에서 제시된 개념 및 프로세스를 설명하고 다른 중요한 부분에 주의를 집중시키기 위한 종합적인 내용을 다룹니다.
인증서 프로비저닝 정보
프로비저닝 에이전트인 Key Vault VM 확장은 미리 결정된 빈도에 따라 지속적으로 실행됩니다. 관찰된 인증서를 검색하지 못할 경우 다음 줄에서 계속 진행하고 다음 주기까지 최대 절전 모드로 전환합니다. 클러스터 부트스트랩 에이전트인 Service Fabric VM 확장에는 클러스터를 구성하기 전에 선언된 인증서가 필요합니다. 즉, Service Fabric VM 확장은 json "provisionAfterExtensions" : [ "KVVMExtension" ]"
절 및 Key Vault VM 확장의json "requireInitialSync": true
설정에 따라 여기에 표시되는 클러스터 인증서를 성공적으로 검색한 후에만 실행할 수 있습니다.
이는 Key Vault VM 확장에 첫 번째 실행(배포 후 또는 다시 부팅 후) 시에 모두 성공적으로 다운로드될 때까지 관찰된 인증서를 순환해야 함을 보여줍니다. 해당 매개 변수를 false로 설정하면 클러스터 인증서를 검색하는 데 실패하고 클러스터 배포가 실패합니다. 반대로 관찰된 인증서의 부정확하거나 잘못된 목록과 초기 동기화를 요구하면 Key Vault VM 확장 오류가 발생하고, 마찬가지로 클러스터를 배포하는 데 실패하게 됩니다.
인증서 연결 설명
Key Vault VM 확장 linkOnRenewal
플래그를 보셨을 수도 있으며, 이 플래그는 false로 설정되어 있습니다. 이 설정은 이 플래그에 의해 제어되는 동작과 클러스터 기능에 미치는 영향을 다룹니다. 이 동작은 Windows로 한정됩니다.
정의에 따라 다음을 수행합니다.
"linkOnRenewal": <Only Windows. This feature enables auto-rotation of SSL certificates, without necessitating a re-deployment or binding. e.g.: false>,
TLS 연결을 설정하는 데 사용되는 인증서는 일반적으로 S-채널 보안 지원 공급자를 통해 핸들로 획득됩니다. 즉, 클라이언트가 인증서 자체의 프라이빗 키에 직접 액세스하지 않습니다. S-채널은 인증서 확장(CERT_RENEWAL_PROP_ID) 형식으로 자격 증명의 리디렉션 또는 링크를 지원합니다.
이 속성이 설정된 경우 해당 값은 갱신 인증서의 지문을 나타내며, 따라서 S-채널은 대신 링크된 인증서를 로드하려고 시도합니다. 실제로 S-채널은 비순환적이면 좋은 이 링크된 목록이 종료될 때까지 최종 인증서(갱신 표시 없는 인증서)를 사용하여 트래버스합니다. 이 기능은 신중하게 사용할 경우 만료된 인증서와 같은 원인으로 발생하는 가용성 손실을 크게 완화합니다.
다른 경우에는 진단 및 완화하기 어려운 중단의 원인일 수 있습니다. S 채널은 주체, 발급자 또는 클라이언트에서 결과 인증서의 유효성 검사에 참여하는 기타 특정 특성과 관계없이 갱신 속성의 인증서 트래버스를 실행합니다. 결과 인증서에 연결된 프라이빗 키가 없거나 키가 해당 소비자에게 ACL되지 않았을 수 있습니다.
링크를 사용하는 경우 Key Vault VM 확장은 키 자격 증명 모음에서 관찰된 인증서를 검색할 때 일치하는 기존 인증서를 찾아 갱신 확장 속성을 통해 링크합니다. 일치는 SAN(주체 대체 이름)을 기반으로 하며, 다음 예제와 같이 두 개의 기존 인증서가 있는 경우에 작동합니다. A: CN(인증서 이름) = “Alice's accessories”, SAN = {“alice.universalexports.com”}, renewal = ‘’ B: CN = “Bob's bits”, SAN = {“bob.universalexports.com”, “bob.universalexports.net”}, renewal = ‘’
인증서 C를 Key Vault VM 확장이 검색했다고 가정합니다. CN = “Mallory's malware”, SAN = {“alice.universalexports.com”, “bob.universalexports.com”, “mallory.universalexports.com”}
인증서 A의 SAN 목록은 C의 목록에 완전히 포함되므로 A.renewal = C.thumbprint입니다. 인증서 B의 SAN 목록은 C의 목록과 교집합이 있지만 완전히 포함되는 것은 아니므로 B.renewal은 비어 있습니다.
이 상태에서 인증서 A에 대해 AcquireCredentialsHandle(S-채널)을 호출하려고 하면 실제로 원격 파티에 C를 전송하게 됩니다. Service Fabric의 경우 클러스터의 전송 하위 시스템은 상호 인증을 위해 S-채널을 사용하므로, 위에서 설명한 동작은 클러스터의 기본 통신에 직접 영향을 줍니다. 위의 예제를 계속 진행하고 A가 클러스터 인증서라고 가정하면 다음 조건에 따라 이후에 발생하는 일이 달라집니다.
- Service Fabric이 실행되는 계정에 C의 프라이빗 키가 ACL되지 않은 경우 프라이빗 키를 가져올 때 오류가 표시됩니다(SEC_E_UNKNOWN_CREDENTIALS 또는 유사한 오류).
- C의 프라이빗 키에 액세스할 수 있는 경우 다른 노드에서 반환된 권한 부여 오류(CertificateNotMatched, 권한 없음 등)가 표시됩니다.
두 경우 모두 전송에 실패하고 클러스터의 작동이 중단될 수 있습니다. 증상은 다양합니다. 설상가상으로 링크는 갱신 순서에 따라 달라집니다. 갱신 순서는 관찰된 Key Vault VM 확장의 인증서 목록 순서, 키 자격 증명 모음의 갱신 일정 또는 검색 순서를 변경하는 일시적인 오류 목록에 따라 결정됩니다.
이러한 인시던트를 완화하려면 다음을 수행하는 것이 좋습니다.
다른 자격 증명 모음 인증서의 주체 대체 이름을 혼합하지 마세요. 각 자격 증명 모음 인증서는 고유한 용도가 있으며, 주체와 SAN은 특이성과 함께 이를 반영해야 합니다.
SAN 목록에 주체 일반 이름(글자 그대로
CN=<subject common name>
)을 포함합니다.진행 방법을 잘 모르는 경우 Key Vault VM 확장으로 프로비저닝된 인증서에 갱신 시 링크를 사용하지 않도록 설정합니다.
참고 항목
링크를 사용하지 않도록 설정하는 것은 Key Vault VM 확장의 최상위 속성이며 관찰된 개별 인증서에 대해 설정할 수 없습니다.
사용자가 할당한 관리 ID를 사용하는 이유는 무엇인가요? 사용자 할당 관리 ID를 사용할 때의 결과는 어떻게 되나요?
위의 JSON 코드 조각에서 본 것처럼, 작업 및 업데이트의 특정 시퀀싱은 전환 성공 여부를 보장하고 클러스터의 가용성을 유지하는 데 필요합니다. 특히 가상 머신 확장 집합 리소스는 해당 ID를 선언하고 (사용자 관점에서) 단일 업데이트에서 비밀을 검색하는 데 사용합니다.
클러스터를 부트스트랩하는 Service Fabric VM 확장은 Key Vault VM 확장의 완료에 따라 달라지고, 이 확장은 관찰된 인증서의 검색 성공에 따라 달라집니다.
Key Vault VM 확장은 가상 머신 확장 집합 ID를 사용하여 키 자격 증명 모음에 액세스합니다. 즉, 가상 머신 확장 집합을 배포하기 전에 키 자격 증명 모음에 대한 액세스 정책이 이미 업데이트된 것입니다.
관리 ID 생성을 삭제하거나 다른 리소스에 할당하려면 배포 운영자에게 템플릿에서 참조되는 다른 리소스를 관리하는 데 필요한 역할 외에도 구독 또는 리소스 그룹에 필요한 역할(ManagedIdentityOperator)이 있어야 합니다.
보안 관점에서 볼 때, 가상 머신 확장 집합은 Azure ID와 관련하여 보안 경계로 간주됩니다. VM에 호스트되는 애플리케이션은 원칙적으로 VM을 나타내는 액세스 토큰을 획득합니다. 관리 ID 액세스 토큰은 인증되지 않은 Instance Metadata Service 엔드포인트에서 가져옵니다. VM을 공유 환경 또는 다중 테넌트 환경으로 간주하면 클러스터 인증서를 검색하는 이 방법이 표시되지 않을 수 있습니다. 하지만 이는 인증서 오토롤오버에 적합한 유일한 프로비저닝 메커니즘입니다.
문제 해결 및 FAQ(자주 묻는 질문)
Q: Key Vault 관리형 인증서를 프로그래밍 방식으로 등록하는 방법은 무엇인가요?
Key Vault 설명서에서 발급자의 이름을 찾은 다음, 다음 스크립트에서 바꿉니다.
$issuerName=<depends on your PKI of choice>
$clusterVault="sftestcus"
$clusterCertVaultName="sftstcncluster"
$clusterCertCN="cus.cluster.sftstcn.system.servicefabric.azure-int"
Set-AzKeyVaultCertificateIssuer -VaultName $clusterVault -Name $issuerName -IssuerProvider $issuerName
$distinguishedName="CN=" + $clusterCertCN
$policy = New-AzKeyVaultCertificatePolicy `
-IssuerName $issuerName `
-SubjectName $distinguishedName `
-SecretContentType 'application/x-pkcs12' `
-Ekus "1.3.6.1.5.5.7.3.1", "1.3.6.1.5.5.7.3.2" `
-ValidityInMonths 4 `
-KeyType 'RSA' `
-RenewAtPercentageLifetime 75
Add-AzKeyVaultCertificate -VaultName $clusterVault -Name $clusterCertVaultName -CertificatePolicy $policy
# poll the result of the enrollment
Get-AzKeyVaultCertificateOperation -VaultName $clusterVault -Name $clusterCertVaultName
Q: 선언되지 않은 또는 지정되지 않은 발급자가 인증서를 발급하면 어떻게 되나요? 특정 PKI의 활성 발급자 전체 목록은 어디서 얻을 수 있나요?
인증서 선언이 발급자 지문을 지정하고 인증서의 직접 발급자가 고정 발급자 목록에 포함되지 않은 경우 해당 루트를 클라이언트에서 신뢰하는지 여부에 관계없이 인증서가 잘못된 것으로 간주됩니다. 따라서 발급자 목록이 최신인지 확인하는 것이 중요합니다. 새 발급자를 도입하는 경우는 드물게 있으며, 인증서를 발급하기 전에 광범위하게 공개되어야 합니다.
일반적으로 PKI는 IETF RFC 7382에 따라 인증 사용 약관을 게시하고 유지 관리합니다. 명령문에는 기타 정보 외에도 모든 활성 발급자가 포함됩니다. 이 목록을 프로그래밍 방식으로 검색하는 것은 PKI마다 다를 수 있습니다.
Microsoft 내부 PKI의 경우 권한 있는 발급자를 검색하는 데 사용되는 엔드포인트 및 SDK에 대한 내부 설명서를 참조하세요. 클러스터 정의에 모든 예상 발급자가 포함되어 있는지 확인하기 위해 이 목록을 주기적으로 검토하는 것은 클러스터 소유자의 책임입니다.
Q: 여러 PKI가 지원되나요?
예. 예, 동일한 값을 사용하여 클러스터 매니페스트에서 여러 CN 항목을 선언할 수 없지만, 동일한 CN에 해당되는 여러 PKI의 발급자를 나열할 수는 있습니다. 이는 권장되는 방법이 아니며, 인증서 투명성 관행으로 인해 해당 인증서를 발급받지 못할 수도 있습니다. 그러나 한 PKI에서 다른 PKI로 마이그레이션하는 것처럼 이는 허용 가능한 메커니즘입니다.
Q: 현재 클러스터 인증서가 CA에서 발급되지 않았거나 의도된 주체가 없는 경우는 어떻게 되나요?
원하는 주체를 사용하여 인증서를 획득하고 지문을 사용하여 클러스터 정의에 부수적으로 추가합니다. 업그레이드가 성공적으로 완료되면 다른 클러스터 구성 업그레이드를 시작하여 인증서 선언을 일반 이름으로 변환합니다.