

# CloudFront에 대한 상호 TLS 인증(뷰어 mTLS)
<a name="mtls-authentication"></a>

상호 TLS 인증(상호 전송 계층 보안 인증 - mTLS)은 양방향 인증서 기반 인증을 요구하여 표준 TLS 인증을 확장하는 보안 프로토콜로, 클라이언트와 서버 모두 보안 연결을 설정하기 전에 자격 증명을 증명해야 합니다. 상호 TLS를 사용하면 신뢰할 수 있는 TLS 인증서를 제공하는 클라이언트만 CloudFront 배포에 액세스할 수 있습니다.

## 작동 방식
<a name="how-mtls-works"></a>

표준 TLS 핸드셰이크에서는 서버만 클라이언트에 자격 증명을 증명하는 인증서를 제공합니다. 상호 TLS를 사용하면 인증 프로세스가 양방향이 됩니다. 클라이언트가 CloudFront 배포에 연결을 시도하면 CloudFront는 TLS 핸드셰이크 중에 클라이언트 인증서를 요청합니다. 클라이언트는 보안 연결을 설정하기 전에 CloudFront가 구성된 트러스트 스토어에 대해 검증하는 유효한 X.509 인증서를 제시해야 합니다.

CloudFront는 AWS 엣지 로케이션에서 이 인증서 검증을 수행하여 오리진 서버에서 인증 복잡성을 오프로드하는 동시에 CloudFront의 글로벌 성능 이점을 유지합니다. 확인 모드(모든 클라이언트가 유효한 인증서를 제시해야 함) 또는 선택적 모드(제공 시 인증서를 검증하지만 인증서 없는 연결도 허용함)의 두 가지 모드로 mTLS를 구성할 수 있습니다.

## 사용 사례
<a name="mtls-use-cases"></a>

CloudFront를 사용한 상호 TLS 인증은 기존 인증 방법이 충분하지 않은 몇 가지 중요한 보안 시나리오를 해결합니다.
+ **콘텐츠 캐싱을 사용한 디바이스 인증** - 펌웨어 업데이트, 게임 다운로드 또는 내부 리소스에 대한 액세스를 허용하기 전에 게임 콘솔, IoT 디바이스 또는 회사 하드웨어를 인증할 수 있습니다. 각 디바이스에는 CloudFront의 캐싱 기능을 활용하면서 신뢰성을 입증하는 고유한 인증서가 포함되어 있습니다.
+ **API-to-API 인증** - 신뢰할 수 있는 비즈니스 파트너, 결제 시스템 또는 마이크로 서비스 간의 시스템 대 시스템 통신을 보호할 수 있습니다. 인증서 기반 인증을 사용하면 공유 보안 암호 또는 API 키를 사용할 필요 없이 자동 데이터 교환을 위한 강력한 자격 증명 확인을 제공합니다.

**Topics**
+ [작동 방식](#how-mtls-works)
+ [사용 사례](#mtls-use-cases)
+ [트러스트 스토어 및 인증서 관리](trust-stores-certificate-management.md)
+ [CloudFront 배포에 상호 TLS 활성화](enable-mtls-distributions.md)
+ [CloudFront 연결 함수 연결](connection-functions.md)
+ [추가 설정 구성](configuring-additional-settings.md)
+ [오리진으로 전달된 캐시 정책에 대한 뷰어 mTLS 헤더](viewer-mtls-headers.md)
+ [CloudFront 연결 함수 및 KVS를 사용한 해지](revocation-connection-function-kvs.md)
+ [연결 로그를 사용한 관찰성](connection-logs.md)

# 트러스트 스토어 및 인증서 관리
<a name="trust-stores-certificate-management"></a>

트러스트 스토어를 생성하고 구성하는 것은 CloudFront와의 상호 TLS 인증을 구현하기 위한 필수 요구 사항입니다. 트러스트 스토어에는 CloudFront가 인증 프로세스 중에 클라이언트 인증서를 검증하는 데 사용하는 인증 기관(CA) 인증서가 포함되어 있습니다.

## 트러스트 스토어란 무엇인가요?
<a name="what-is-trust-store"></a>

트러스트 스토어는 CloudFront가 상호 TLS 인증 중에 클라이언트 인증서를 검증하는 데 사용하는 CA 인증서의 리포지토리입니다. 트러스트 스토어에는 클라이언트 인증서를 인증하기 위한 신뢰 체인을 구성하는 루트 및 중간 CA 인증서가 포함되어 있습니다.

CloudFront와 상호 TLS를 구현하면 트러스트 스토어는 유효한 클라이언트 인증서를 발급하기 위해 신뢰할 수 있는 인증 기관을 정의합니다. CloudFront는 TLS 핸드셰이크 중에 트러스트 스토어에 대해 각 클라이언트 인증서를 검증합니다. 트러스트 스토어의 CA 중 하나에 연결된 인증서를 제공하는 클라이언트만 성공적으로 인증됩니다.

CloudFront의 트러스트 스토어는 여러 배포와 연결할 수 있는 계정 수준 리소스입니다. 이를 통해 CA 인증서 관리를 간소화하면서 전체 CloudFront 배포에서 일관된 인증서 검증 정책을 유지할 수 있습니다.

## 인증 기관 지원
<a name="ca-support"></a>

CloudFront는 AWS 프라이빗 인증 기관과 타사 프라이빗 인증 기관에서 발급한 인증서를 지원합니다. 이러한 유연성을 통해 기존 인증서 인프라를 사용하거나 조직 요구 사항에 따라 AWS 관리형 인증서 서비스를 활용할 수 있습니다.
+ **AWS 프라이빗 인증 기관:** 관리형 프라이빗 인증 기관 서비스를 제공하는 AWS Private CA에서 발급한 인증서를 사용할 수 있습니다. 이 통합은 인증서 수명 주기 관리를 간소화하고 다른 AWS 서비스와의 원활한 통합을 제공합니다.
+ **타사 프라이빗 인증 기관:** 엔터프라이즈 CA 또는 기타 타사 인증서 공급자를 포함하여 기존 프라이빗 인증 기관 인프라의 인증서를 사용할 수도 있습니다. 이렇게 하면 CloudFront의 mTLS 기능을 추가하면서 현재 인증서 관리 프로세스를 유지할 수 있습니다.

## 인증서 요구 사항 및 사양
<a name="certificate-requirements"></a>

트러스트 스토어에는 포함된 CA 인증서에 대한 특정 요구 사항이 있습니다.

### CA 인증서 형식 요구 사항
<a name="ca-cert-format-requirements"></a>
+ **형식:** PEM(Privacy Enhanced Mail) 형식
+ **콘텐츠 경계:** 인증서는 -----BEGIN CERTIFICATE----- 및 -----END CERTIFICATE----- 경계 내에 묶여야 합니다.
+ **주석:** 앞에는 \$1 문자를 붙여야 하며 - 문자를 포함할 수 없습니다.
+ **줄 바꿈:** 인증서 사이에 빈 줄이 허용되지 않습니다.

### 지원되는 인증서 사양
<a name="supported-cert-specs"></a>
+ **인증서 유형:** X.509v3
+ **퍼블릭 키 유형:**
  + RSA 2048, RSA 3072, RSA 4096
  + ECDSA: secp256r1, secp384r1
+ **서명 알고리즘:**
  + RSA를 사용하는 SHA256, SHA384, SHA512
  + EC를 사용하는 SHA256, SHA384, SHA512
  + MGF1 지원 RSASSA-PSS를 사용하는 SHA256, SHA384, SHA512

### 예제 인증서 번들 형식
<a name="example-cert-bundle"></a>

여러 인증서(PEM 인코딩):

```
# Root CA Certificate
-----BEGIN CERTIFICATE-----
MIIDXTCCAkWgAwIBAgIJAKoK/OvD/XqiMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
aWRnaXRzIFB0eSBMdGQwHhcNMTcwNzEyMTU0NzQ4WhcNMjcwNzEwMTU0NzQ4WjBF
MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEAuuExKvY1xzHFylsHiuowqpmzs7rEcuuylOuEszpFp+BtXh0ZuEtts9LP
-----END CERTIFICATE-----
# Intermediate CA Certificate
-----BEGIN CERTIFICATE-----
MIIDXTCCAkWgAwIBAgIJAKoK/OvD/XqjMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
aWRnaXRzIFB0eSBMdGQwHhcNMTcwNzEyMTU0NzQ4WhcNMjcwNzEwMTU0NzQ4WjBF
MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEAuuExKvY1xzHFylsHiuowqpmzs7rEcuuylOuEszpFp+BtXh0ZuEtts9LP
-----END CERTIFICATE-----
```

## 트러스트 스토어 생성
<a name="create-trust-store"></a>

트러스트 스토어를 생성하기 전에 PEM 형식의 CA 인증서 번들을 Amazon S3 버킷에 업로드해야 합니다. 인증서 번들에는 클라이언트 인증서를 검증하는 데 필요한 신뢰할 수 있는 모든 루트 및 중간 CA 인증서가 포함되어야 합니다.

CA 인증서 번들은 트러스트 스토어를 생성할 때 S3에서 한 번만 읽습니다. CA 인증서 번들을 나중에 변경하는 경우 트러스트 스토어를 수동으로 업데이트해야 합니다. 트러스트 스토어와 S3 CA 인증서 번들 간에 동기화가 유지되지 않습니다.

### 사전 조건
<a name="trust-store-prerequisites"></a>
+ Amazon S3 버킷에 업로드된 인증 기관(CA)의 인증서 번들
+ CloudFront 리소스를 생성하는 데 필요한 권한

### 트러스트 스토어를 생성하려면(콘솔)
<a name="create-trust-store-console"></a>

1. AWS Management Console에 로그인한 다음 [https://console.aws.amazon.com/cloudfront/v4/home](https://console.aws.amazon.com/cloudfront/v4/home)에서 CloudFront 콘솔을 엽니다.

1. 탐색 창에서 **트러스트 스토어**를 선택합니다.

1. **트러스트 스토어 생성**을 선택합니다.

1. **트러스트 스토어 이름**에 트러스트 스토어의 이름을 입력합니다.

1. **인증 기관(CA) 번들**의 경우 PEM 형식 CA 인증서 번들에 Amazon S3 경로를 입력합니다.

1. **트러스트 스토어 생성**을 선택합니다.

### 트러스트 스토어를 생성하려면(AWS CLI)
<a name="create-trust-store-cli"></a>

```
aws cloudfront create-trust-store \
  --name MyTrustStore \
  --certificate-authority-bundle-s3-location Bucket=my-bucket,Key=ca-bundle.pem \
  --tags Items=[{Key=Environment,Value=Production}]
```

## 트러스트 스토어를 배포와 연결
<a name="associate-trust-store"></a>

트러스트 스토어를 생성한 후에는 이를 CloudFront 배포와 연결하여 상호 TLS 인증을 활성화해야 합니다.

### 사전 조건
<a name="associate-prerequisites"></a>
+ HTTPS 전용 뷰어 프로토콜 정책이 활성화되고 HTTP3 지원이 비활성화된 기존 CloudFront 배포입니다.

### 트러스트 스토어를 연결하려면(콘솔)
<a name="associate-trust-store-console"></a>

CloudFront 콘솔 내에서 트러스트 스토어 세부 정보 페이지 또는 배포 설정 페이지를 통해 트러스트 스토어를 연결할 수 있는 두 가지 방법이 있습니다.

**트러스트 스토어 세부 정보 페이지를 통해 트러스트 스토어 연결:**

1. AWS Management Console에 로그인한 다음 [https://console.aws.amazon.com/cloudfront/v4/home](https://console.aws.amazon.com/cloudfront/v4/home)에서 CloudFront 콘솔을 엽니다.

1. 탐색 창에서 **트러스트 스토어**를 선택합니다.

1. 연결할 트러스트 스토어의 이름을 선택합니다.

1. **배포에 연결**을 선택합니다.

1. 사용 가능한 뷰어 mTLS 옵션을 구성합니다.
   + **클라이언트 인증서 검증 모드:** 필수 모드와 선택 모드 중에서 선택합니다. 필수 모드에서는 모든 클라이언트가 인증서를 제시해야 합니다. 선택적 모드에서는 인증서를 제공하는 클라이언트가 검증되는 반면, 인증서를 제공하지 않는 클라이언트는 액세스가 허용됩니다.
   + **트러스트 스토어 CA 이름 알림:** TLS 핸드셰이크 중에 트러스트 스토어의 CA 이름을 클라이언트에 알릴지 여부를 선택합니다.
   + **인증서 만료 날짜 무시:** 만료된 인증서와의 연결을 허용할지 여부를 선택합니다(다른 검증 기준은 계속 적용됨).
   + **연결 함수:** 선택적 연결 함수를 연결하여 다른 사용자 지정 기준에 따라 연결을 허용/거부할 수 있습니다.

1. 트러스트 스토어와 연결할 배포를 하나 이상 선택합니다. HTTP3가 비활성화되고 HTTPS 전용 캐시 동작이 있는 배포만 뷰어 mTLS를 지원할 수 있습니다.

1. **연결**을 선택합니다.

**배포 설정 페이지를 통해 트러스트 스토어 연결:**

1. AWS Management Console에 로그인한 다음 [https://console.aws.amazon.com/cloudfront/v4/home](https://console.aws.amazon.com/cloudfront/v4/home)에서 CloudFront 콘솔을 엽니다.

1. 연결하려는 배포를 선택합니다.

1. **일반** 탭의 **설정** 컨테이너에서 오른쪽 상단 모서리에 있는 **편집**을 선택합니다.

1. 페이지 하단까지 아래로 스크롤하여 **연결** 컨테이너 내에서 **뷰어 mTLS** 스위치를 켭니다.

1. 사용 가능한 뷰어 mTLS 옵션을 구성합니다.
   + **클라이언트 인증서 검증 모드:** 필수 모드와 선택 모드 중에서 선택합니다. 필수 모드에서는 모든 클라이언트가 인증서를 제시해야 합니다. 선택적 모드에서는 인증서를 제공하는 클라이언트가 검증되는 반면, 인증서를 제공하지 않는 클라이언트는 액세스가 허용됩니다.
   + **트러스트 스토어 CA 이름 알림:** TLS 핸드셰이크 중에 트러스트 스토어의 CA 이름을 클라이언트에 알릴지 여부를 선택합니다.
   + **인증서 만료 날짜 무시:** 만료된 인증서와의 연결을 허용할지 여부를 선택합니다(다른 검증 기준은 계속 적용됨).
   + **연결 함수:** 선택적 연결 함수를 연결하여 다른 사용자 지정 기준에 따라 연결을 허용/거부할 수 있습니다.

1. 오른쪽 하단 모서리에서 **변경 사항 저장**을 선택합니다.

### 트러스트 스토어를 연결하려면(AWS CLI)
<a name="associate-trust-store-cli"></a>

트러스트 스토어는 DistributionConfig.ViewerMtlsConfig 속성을 통해 배포에 연결할 수 있습니다. 즉, 먼저 배포 구성을 가져온 다음 후속 UpdateDistribution 요청에서 ViewerMtlsConfig를 제공해야 합니다.

```
// First fetch the distribution
aws cloudfront get-distribution {DISTRIBUTION_ID}

// Update the distribution config, for example:
Distribution config, file://distConf.json: 
{
  ...other fields,
  ViewerMtlsConfig: {
    Mode: 'required',
    TrustStoreConfig: {
        AdvertiseTrustStoreCaNames: false,
        IgnoreCertificateExpiry: true,
        TrustStoreId: {TRUST_STORE_ID}
    }
  }
}

aws cloudfront update-distribution \
   --id {DISTRIBUTION_ID} \
   --if-match {ETAG} \
   --distribution-config file://distConf.json
```

## 트러스트 스토어 관리
<a name="manage-trust-stores"></a>

### 트러스트 스토어 세부 정보 보기
<a name="view-trust-store-details"></a>

1. AWS Management Console에 로그인한 다음 [https://console.aws.amazon.com/cloudfront/v4/home](https://console.aws.amazon.com/cloudfront/v4/home)에서 CloudFront 콘솔을 엽니다.

1. 탐색 창에서 **트러스트 스토어**를 선택합니다.

1. 트러스트 스토어 이름을 선택하여 세부 정보 페이지를 봅니다.

세부 정보 페이지에는 다음이 표시됩니다.
+ 트러스트 스토어 이름 및 ID
+ CA 인증서 수
+ 생성 날짜 및 마지막 수정 날짜
+ 연결된 배포
+ Tags

### 트러스트 스토어 수정
<a name="modify-trust-store"></a>

CA 인증서 번들을 교체하려면:

1. AWS Management Console에 로그인한 다음 [https://console.aws.amazon.com/cloudfront/v4/home](https://console.aws.amazon.com/cloudfront/v4/home)에서 CloudFront 콘솔을 엽니다.

1. 탐색 창에서 **트러스트 스토어**를 선택합니다.

1. 트러스트 스토어의 이름을 선택합니다.

1. **작업**을 선택한 다음 **편집**을 선택합니다.

1. **인증 기관(CA) 번들**에 업데이트된 CA 번들 PEM 파일의 Amazon S3 위치를 입력합니다.

1. **트러스트 스토어 업데이트**를 선택합니다.

### 트러스트 스토어 삭제
<a name="delete-trust-store"></a>

**사전 조건:** 먼저 모든 CloudFront 배포에서 트러스트 스토어의 연결을 해제해야 합니다.

1. AWS Management Console에 로그인한 다음 [https://console.aws.amazon.com/cloudfront/v4/home](https://console.aws.amazon.com/cloudfront/v4/home)에서 CloudFront 콘솔을 엽니다.

1. 탐색 창에서 **트러스트 스토어**를 선택합니다.

1. 트러스트 스토어의 이름을 선택합니다.

1. **트러스트 스토어 삭제**를 선택합니다.

1. [**삭제**]를 선택하여 확인합니다.

### 다음 단계
<a name="trust-store-next-steps"></a>

트러스트 스토어를 생성하고 CloudFront 배포와 연결한 후 배포에서 상호 TLS 인증을 활성화하고 인증서 헤더를 오리진에 전달하는 등의 추가 설정을 구성할 수 있습니다. 배포에서 mTLS를 활성화하는 방법에 대한 자세한 지침은 [CloudFront 배포에 상호 TLS 활성화](enable-mtls-distributions.md) 섹션을 참조하세요.

# CloudFront 배포에 상호 TLS 활성화
<a name="enable-mtls-distributions"></a>

## 사전 조건 및 요구 사항
<a name="mtls-prerequisites-requirements"></a>

CloudFront의 상호 TLS 확인 모드에서는 모든 클라이언트가 TLS 핸드셰이크 중에 유효한 인증서를 제시하고 유효한 인증서가 없는 연결을 거부해야 합니다. CloudFront 배포에서 상호 TLS를 활성화하기 전에 다음을 확인해야 합니다.
+ 인증 기관 인증서로 트러스트 스토어를 생성함
+ 트러스트 스토어가 CloudFront 배포와 연결됨
+ 모든 배포 캐시 동작이 HTTPS 전용 뷰어 프로토콜 정책을 사용함
+ 배포에서 HTTP/2를 사용하고 있음(기본 설정, HTTP/3에서는 뷰어 mTLS가 지원되지 않음)

**참고**  
상호 TLS 인증에는 뷰어와 CloudFront 간의 HTTPS 연결이 필요합니다. HTTP 연결을 지원하는 캐시 동작이 있는 배포에서는 mTLS를 활성화할 수 없습니다.

## 상호 TLS 활성화(콘솔)
<a name="enable-mtls-console"></a>

### 새 배포의 경우
<a name="enable-mtls-new-distributions"></a>

CloudFront 콘솔에서 새 배포를 생성하는 과정에서는 뷰어 mTLS를 구성할 수 없습니다. 먼저 모든 방법(콘솔, CLI, API)으로 배포를 생성한 다음 배포 설정을 편집하여 아래 기존 배포 지침에 따라 뷰어 mTLS를 활성화합니다.

### 기존 배포의 경우
<a name="enable-mtls-existing-distributions"></a>

1. AWS Management Console에 로그인한 다음 [https://console.aws.amazon.com/cloudfront/v4/home](https://console.aws.amazon.com/cloudfront/v4/home)에서 CloudFront 콘솔을 엽니다.

1. 배포 목록에서 수정하려는 배포를 선택합니다.

1. 모든 캐시 동작의 뷰어 프로토콜 정책을 **HTTP를 HTTPS로 리디렉션** 또는 **HTTPS 전용**으로 설정해야 합니다. (**캐시 동작** 탭을 선택하여 HTTP 프로토콜 정책으로 캐시 동작을 보고 업데이트할 수 있습니다.)

1. **일반** 탭을 선택합니다.

1. **설정** 섹션에서 **편집**을 선택합니다.

1. **연결성** 섹션에서 **뷰어 상호 인증(mTLS)**을 찾습니다.

1. **상호 인증 활성화**를 켜기로 전환합니다.

1. **클라이언트 인증서 검증 모드**에서 **필수**(모든 클라이언트가 인증서를 제시해야 함) 또는 **선택 사항**(클라이언트가 선택적으로 인증서를 제공할 수 있음)을 선택합니다.

1. **트러스트 스토어**에서 이전에 생성한 트러스트 스토어를 선택합니다.

1. (선택 사항) TLS 핸드셰이크 중에 CloudFront가 클라이언트에 CA 이름을 보내도록 하려면 **트러스트 스토어 CA 이름 알리기**를 전환합니다.

1. (선택 사항) 만료된 인증서와의 연결을 허용하려면 **인증서 만료 날짜 무시**를 전환합니다.

1. **변경 사항 저장**을 선택합니다.

## 상호 TLS 활성화(AWS CLI)
<a name="enable-mtls-cli"></a>

### 새 배포의 경우
<a name="enable-mtls-cli-new"></a>

다음 예제에서는 mTLS 설정을 포함하는 배포 구성 파일(distribution-config.json)을 생성하는 방법을 보여줍니다.

```
{
  "CallerReference": "cli-example-1",
  "Origins": {
    "Quantity": 1,
    "Items": [
      {
        "Id": "my-origin",
        "DomainName": "example.com",
        "CustomOriginConfig": {
          "HTTPPort": 80,
          "HTTPSPort": 443,
          "OriginProtocolPolicy": "https-only"
        }
      }
    ]
  },
  "DefaultCacheBehavior": {
    "TargetOriginId": "my-origin",
    "ViewerProtocolPolicy": "https-only",
    "MinTTL": 0,
    "ForwardedValues": {
      "QueryString": false,
      "Cookies": {
        "Forward": "none"
      }
    }
  },
  "ViewerCertificate": {
    "CloudFrontDefaultCertificate": true
  },
  "ViewerMtlsConfig": {
    "Mode": "required", 
    "TrustStoreConfig": {
        "TrustStoreId": {TRUST_STORE_ID},
        "AdvertiseTrustStoreCaNames": true,
        "IgnoreCertificateExpiry": true
    }
  },
  "Enabled": true
}
```

다음 예제 명령을 사용하여 mTLS가 활성화된 배포를 생성합니다.

```
aws cloudfront create-distribution --distribution-config file://distribution-config.json
```

### 기존 배포의 경우
<a name="enable-mtls-cli-existing"></a>

다음 예제 명령을 사용하여 현재 배포 구성을 가져옵니다.

```
aws cloudfront get-distribution-config --id E1A2B3C4D5E6F7 --output json > dist-config.json
```

파일을 편집하여 mTLS 설정을 추가합니다. 배포 구성에 다음 예제 섹션을 추가합니다.

```
"ViewerMtlsConfig": {
    "Mode": "required", 
    "TrustStoreConfig": {
        "TrustStoreId": {TRUST_STORE_ID},
        "AdvertiseTrustStoreCaNames": true,
        "IgnoreCertificateExpiry": true
    }
}
```

파일에서 ETag 필드를 제거하되 값을 별도로 저장합니다.

다음 예제 명령을 사용하여 배포를 새 구성으로 업데이트합니다.

```
aws cloudfront update-distribution \
    --id E1A2B3C4D5E6F7 \
    --if-match YOUR-ETAG-VALUE \
    --distribution-config file://dist-config.json
```

## 뷰어 프로토콜 정책
<a name="viewer-protocol-policies"></a>

상호 TLS를 사용하는 경우 모든 배포 캐시 동작을 HTTPS 전용 뷰어 프로토콜 정책으로 구성해야 합니다.
+ **HTTP를 HTTPS로 리디렉션** - 인증서 검증을 수행하기 전에 HTTP 요청을 HTTPS로 리디렉션합니다.
+ **HTTPS 전용** - HTTPS 요청만 수락하고 인증서 검증을 수행합니다.

**참고**  
HTTP 연결은 인증서 검증을 수행할 수 없으므로 HTTP 및 HTTPS 뷰어 프로토콜 정책은 상호 TLS에서 지원되지 않습니다.

## 다음 단계
<a name="enable-mtls-next-steps"></a>

CloudFront 배포에서 뷰어 TLS를 활성화한 후 연결 함수를 연결하여 사용자 지정 인증서 검증 로직을 구현할 수 있습니다. 연결 함수를 사용하면 사용자 지정 검증 규칙, 인증서 해지 확인 및 로깅을 통해 기본 제공 mTLS 인증 기능을 확장할 수 있습니다. 연결 함수 생성 및 연결에 대한 자세한 내용은 [CloudFront 연결 함수 연결](connection-functions.md) 섹션을 참조하세요.

# CloudFront 연결 함수 연결
<a name="connection-functions"></a>

CloudFront 연결 함수를 사용하면 TLS 핸드셰이크 중에 사용자 지정 인증서 검증 로직을 구현하여 내장 mTLS 인증 기능을 확장할 수 있습니다.

## 연결 함수란 무엇입니까?
<a name="what-are-connection-functions"></a>

연결 함수는 클라이언트 인증서가 검증된 후 TLS 핸드셰이크 중에 실행되는 JavaScript 함수입니다. 검증된 클라이언트 인증서는 연결 함수로 전달되며, 이 시점에서 연결 함수는 액세스 권한 부여 여부를 추가로 결정할 수 있습니다. 연결 함수에 대한 자세한 내용은 [CloudFront Functions를 사용하여 엣지에서 사용자 지정](cloudfront-functions.md) 섹션을 참조하세요.

## 연결 함수가 mTLS에서 작동하는 방식
<a name="how-connection-functions-work"></a>

클라이언트가 CloudFront 배포에 대한 mTLS 연결을 설정하려고 하면 다음 시퀀스가 발생합니다.

1. 클라이언트가 CloudFront 엣지 로케이션으로 TLS 핸드셰이크를 시작합니다.

1. CloudFront가 클라이언트 인증서를 요청하고 수신합니다.

1. CloudFront가 트러스트 스토어에 대해 표준 인증서 검증을 수행합니다.

1. 인증서가 표준 검증을 통과하면 CloudFront는 연결 함수를 간접적으로 호출합니다. **ViewerMtlsConfig** 내에서 **IgnoreCertificateExpiry**가 활성화된 경우 만료되었지만 유효한 인증서도 연결 함수로 전달됩니다. 클라이언트 인증서가 유효하지 않으면 연결 함수가 간접 호출되지 않습니다.

1. 연결 함수는 구문 분석된 인증서 정보와 연결 세부 정보를 수신합니다.

1. 함수는 사용자 지정 로직을 기반으로 허용/거부 결정을 내립니다.

1. CloudFront는 사용자의 결정에 따라 TLS 연결을 완료하거나 종료합니다.

연결 함수는 확인 모드와 선택적 모드(클라이언트가 인증서를 제공하는 경우) 모두에 대해 간접적으로 호출됩니다.

## 연결 함수 생성
<a name="create-connection-function"></a>

CloudFront 콘솔 또는 AWS CLI를 사용하여 연결 함수를 생성할 수 있습니다.

### 연결 함수를 생성하려면(콘솔)
<a name="create-connection-function-console"></a>

1. AWS Management Console에 로그인한 다음 [https://console.aws.amazon.com/cloudfront/v4/home](https://console.aws.amazon.com/cloudfront/v4/home)에서 CloudFront 콘솔을 엽니다.

1. 탐색 창에서 **함수**를 선택합니다.

1. **연결 함수** 탭을 선택한 다음 **연결 함수 생성**을 선택합니다.

1. AWS 계정 내에서 고유한 함수 이름을 입력합니다.

1. **계속**을 선택합니다.

1. 함수 편집기에서 인증서 검증을 위한 JavaScript 코드를 작성합니다. 함수 핸들러는 허용 또는 거부를 직접 호출해야 합니다.

1. 선택 사항: KeyValue 스토어를 연결 함수에 연결하여 해지 제어를 구현할 수 있습니다.

1. **변경 사항 저장**을 선택합니다.

### 연결 함수를 생성하려면(AWS CLI)
<a name="create-connection-function-cli"></a>

다음 예제에서는 연결 함수를 생성하는 방법을 보여줍니다.

code.js와 같은 별도의 파일에 함수 코드를 작성합니다.

```
function connectionHandler(connection) {
  connection.allow();
}
```

```
aws cloudfront create-connection-function \
  --name "certificate-validator" \
  --connection-function-config '{
      "Comment": "Client certificate validation function",
      "Runtime": "cloudfront-js-2.0"
  }' \
  --connection-function-code fileb://code.js
```

## 연결 함수 코드 구조
<a name="connection-function-code-structure"></a>

연결 함수는 인증서 및 연결 정보가 포함된 연결 객체를 수신하는 connectionHandler 함수를 구현합니다. 함수는 `connection.allow()` 또는 `connection.deny()`를 사용하여 연결에 대한 결정을 내려야 합니다.

### 기본 연결 함수 예제
<a name="basic-connection-function-example"></a>

다음 예제는 클라이언트 인증서의 제목 필드를 확인하는 간단한 연결 함수를 보여줍니다.

```
function connectionHandler(connection) {
    // Only process if a certificate was presented
    if (!connection.clientCertificate) {
        console.log("No certificate presented");
        connection.deny();
    }
    
    // Check the subject field for specific organization
    const subject = connection.clientCertificate.certificates.leaf.subject;
    if (!subject.includes("O=ExampleCorp")) {
        console.log("Certificate not from authorized organization");
       connection.deny();
    } else {
        // All checks passed
        console.log("Certificate validation passed");
        connection.allow();
    }
}
```

연결 객체에서 사용할 수 있는 클라이언트 인증서 속성의 전체 사양은 여기에서 확인할 수 있습니다.

```
{
  "connectionId": "Fdb-Eb7L9gVn2cFakz7wWyBJIDAD4-oNO6g8r3vXDV132BtnIVtqDA==", // Unique identifier for this TLS connection
  "clientIp": "203.0.113.42", // IP address of the connecting client (IPv4 or IPv6)
  "clientCertificate": {
    "certificates": {
      "leaf": {
        "subject": "CN=client.example.com,O=Example Corp,C=US", // Distinguished Name (DN) of the certificate holder
        "issuer": "CN=Example Corp Intermediate CA,O=Example Corp,C=US", // Distinguished Name (DN) of the certificate authority that issued this certificate
        "serialNumber": "4a:3f:5c:92:d1:e8:7b:6c", // Unique serial number assigned by the issuing CA (hexadecimal)
        "validity": {
          "notBefore": "2024-01-15T00:00:00Z", // Certificate validity start date (ISO 8601 format)
          "notAfter": "2025-01-14T23:59:59Z"   // Certificate expiration date (ISO 8601 format)
        },
        "sha256Fingerprint": "a1b2c3d4e5f6...abc123def456", // SHA-256 hash of the certificate (64 hex characters)
      },
    },
  },
}
```

## 연결 함수 연결
<a name="associate-connection-function-section"></a>

연결 함수를 생성한 후에는 이를 라이브 단계에 게시하고 배포와 연결해야 합니다.

### 연결 함수를 게시하고 연결하려면(콘솔)
<a name="publish-associate-console"></a>

1. AWS Management Console에 로그인한 다음 [https://console.aws.amazon.com/cloudfront/v4/home](https://console.aws.amazon.com/cloudfront/v4/home)에서 CloudFront 콘솔을 엽니다.

1. 탐색 창에서 **함수**를 선택합니다.

1. **연결 함수** 탭을 선택하고 연결 함수를 선택합니다.

1. **게시**를 선택하여 라이브 단계로 이동합니다.

1. 게시 섹션 아래의 연결된 배포 테이블에서 **연결 추가**를 선택합니다.

1. 연결하려는 뷰어 mTLS가 활성화된 배포를 선택합니다.

또는 배포 세부 정보 페이지에서 게시된 연결 함수를 연결할 수도 있습니다.

1. 모든 배포가 나열된 콘솔 홈 페이지로 이동합니다.

1. 연결하려는 배포를 선택합니다.

1. **일반** 탭을 선택합니다.

1. **설정** 섹션에서 **편집**을 선택합니다.

1. **연결성** 섹션에서 **뷰어 상호 인증(mTLS)**을 찾습니다.

1. **연결 함수**에서 함수를 선택합니다.

1. **변경 사항 저장**을 선택합니다.

### 연결 함수를 연결하려면(AWS CLI)
<a name="associate-connection-function-cli"></a>

다음 예제에서는 연결 함수를 배포와 연결하는 방법을 보여줍니다.

```
// DistributionConfig:
{
   ...other settings,
    "ConnectionFunctionAssociation": {
        "Id": "cf_30c2CV2elHwCoInb3LtcaUJkZeD"
    }
}
```

## 연결 함수 사용 사례
<a name="connection-function-use-cases"></a>

연결 함수를 사용하면 다음과 같은 여러 고급 mTLS 사용 사례를 사용할 수 있습니다.
+ **인증서 속성 검증** - 조직 단위 요구 사항 또는 주체 대체 이름 패턴과 같은 클라이언트 인증서의 특정 필드를 확인합니다.
+ **인증서 해지 확인** - KeyValueStore를 사용하여 해지된 인증서 일련 번호를 저장하는 사용자 지정 인증서 해지 확인을 구현합니다.
+ **IP 기반 인증서 정책** - 클라이언트 IP 주소 또는 지리적 제한에 따라 다른 인증서 정책을 적용합니다.
+ **다중 테넌트 검증** - 호스트 이름 또는 인증서 속성에 따라 다양한 인증서 요구 사항이 적용되는 테넌트별 검증 규칙을 구현합니다.

**참고**  
연결 함수는 TLS 핸드셰이크 중에 클라이언트 연결당 한 번 실행됩니다.  
연결 함수는 HTTP 요청/응답을 수정하지 않고 연결만 허용하거나 거부할 수 있습니다.  
라이브 단계 함수(게시됨)만 배포와 연결할 수 있습니다.  
각 배포에는 최대 하나의 연결 함수가 있을 수 있습니다.

## 다음 단계
<a name="connection-function-next-steps"></a>

연결 함수를 CloudFront 배포와 연결한 후 선택적 설정을 구성하여 mTLS 구현의 동작을 사용자 지정할 수 있습니다. 선택적 클라이언트 인증서 검증 모드와 같은 추가 설정을 구성하는 방법에 대한 자세한 지침은 [추가 설정 구성](configuring-additional-settings.md) 섹션을 참조하세요.

# 추가 설정 구성
<a name="configuring-additional-settings"></a>

기본 상호 TLS 인증을 활성화한 후 특정 사용 사례 및 요구 사항에 맞게 인증 동작을 사용자 지정하도록 추가 설정을 구성할 수 있습니다.

## 클라이언트 인증서 검증 선택적 모드
<a name="optional-mode"></a>

CloudFront는 제공된 클라이언트 인증서를 검증하지만 인증서를 제시하지 않는 클라이언트에 대한 액세스를 허용하는 선택적 클라이언트 인증서 검증 모드를 제공합니다.

### 선택적 모드 동작
<a name="optional-mode-behavior"></a>
+ 유효한 인증서가 있는 클라이언트에 대한 연결을 부여합니다(잘못된 인증서는 거부됨).
+ 인증서 없이 클라이언트에 연결 허용
+ 단일 배포를 통해 혼합 클라이언트 인증 시나리오를 허용합니다.

선택적 모드는 mTLS 인증으로 점진적으로 마이그레이션하거나, 인증서가 있는 클라이언트 및 인증서가 없는 클라이언트를 지원하거나, 레거시 클라이언트와의 이전 버전 호환성을 유지하는 데 적합합니다.

**참고**  
선택적 모드에서는 클라이언트가 인증서를 제시하지 않더라도 연결 함수가 계속 간접 호출됩니다. 이를 통해 클라이언트 IP 주소 로깅 또는 인증서 제시 여부에 따라 다른 정책 적용과 같은 사용자 지정 로직을 구현할 수 있습니다.

### 선택적 모드를 구성하려면(콘솔)
<a name="configure-optional-mode-console"></a>

1. 배포 설정에서 **일반** 탭으로 이동하여 **편집**을 선택합니다.

1. **연결성** 컨테이너 내의 **뷰어 상호 인증(mTLS)** 섹션으로 스크롤합니다.

1. **클라이언트 인증서 검증 모드**에서 **선택 사항**을 선택합니다.

1. 변경 내용을 저장합니다.

### 선택적 모드를 구성하려면(AWS CLI)
<a name="configure-optional-mode-cli"></a>

다음 예제에서는 선택적 모드를 구성하는 방법을 보여줍니다.

```
"ViewerMtlsConfig": {
   "Mode": "optional",
   ...other settings
}
```

## 인증 기관 광고
<a name="ca-advertisement"></a>

AdvertiseTrustStoreCaNames 필드는 TLS 핸드셰이크 중에 CloudFront가 신뢰할 수 있는 CA 이름 목록을 클라이언트에 전송할지 여부를 제어하여 클라이언트가 적절한 인증서를 선택할 수 있도록 지원합니다.

### CA 광고를 구성하려면(콘솔)
<a name="configure-ca-advertisement-console"></a>

1. 배포 설정에서 **일반** 탭으로 이동하여 **편집**을 선택합니다.

1. **연결성** 컨테이너 내의 **뷰어 상호 인증(mTLS)** 섹션으로 스크롤합니다.

1. **트러스트 스토어 CA 이름 광고** 확인란을 선택하거나 선택 취소합니다.

1. **변경 사항 저장**을 선택합니다.

### CA 광고를 구성하려면(AWS CLI)
<a name="configure-ca-advertisement-cli"></a>

다음 예제에서는 CA 광고를 활성화하는 방법을 보여줍니다.

```
"ViewerMtlsConfig": {
   "Mode": "required", // or "optional"
   "TrustStoreConfig": {
      "AdvertiseTrustStoreCaNames": true,
      ...other settings
   } 
}
```

## 인증서 만료 처리
<a name="certificate-expiration-handling"></a>

IgnoreCertificateExpiry 속성은 CloudFront가 만료된 클라이언트 인증서에 응답하는 방법을 결정합니다. 기본적으로 CloudFront는 만료된 클라이언트 인증서를 거부하지만 필요할 때 수락하도록 구성할 수 있습니다. 이는 일반적으로 즉시 업데이트할 수 없는 인증서가 만료된 디바이스를 대상으로 활성화됩니다.

### 인증서 만료 처리를 구성하려면(콘솔)
<a name="configure-expiration-console"></a>

1. 배포 설정에서 **일반** 탭으로 이동하여 **편집**을 선택합니다.

1. **연결성** 컨테이너의 **뷰어 상호 인증(mTLS)** 섹션으로 스크롤합니다.

1. **인증서 만료 날짜 무시** 확인란을 선택하거나 선택 취소합니다.

1. **변경 사항 저장**을 선택합니다.

### 인증서 만료 처리를 구성하려면(AWS CLI)
<a name="configure-expiration-cli"></a>

다음 예제에서는 인증서 만료를 무시하는 방법을 보여줍니다.

```
"ViewerMtlsConfig": {
  "Mode": "required", // or "optional"
  "TrustStoreConfig": {
     "IgnoreCertificateExpiry": false,
     ...other settings
  }
}
```

**참고**  
**IgnoreCertificateExpiry**는 인증서 검증 날짜에만 적용됩니다. 다른 모든 인증서 검증 검사(신뢰 체인, 서명 검증)는 계속 적용됩니다.

## 다음 단계
<a name="additional-settings-next-steps"></a>

추가 설정을 구성한 후 헤더 전달을 설정하여 인증서 정보를 오리진에 전달하고, 연결 함수 및 KeyValueStore를 사용하여 인증서 해지를 구현하고, 모니터링을 위해 연결 로그를 활성화할 수 있습니다. 오리진에 인증서 정보를 전달하는 방법에 대한 자세한 내용은 [오리진에 헤더 전달](viewer-mtls-headers.md)을 참조하세요.

# 오리진으로 전달된 캐시 정책에 대한 뷰어 mTLS 헤더
<a name="viewer-mtls-headers"></a>

상호 TLS 인증을 사용하는 경우, CloudFront는 클라이언트 인증서에서 정보를 추출하여 오리진에 HTTP 헤더로 전달할 수 있습니다. 이렇게 하면 오리진 서버가 인증서 검증 로직을 구현하지 않고도 인증서 세부 정보에 액세스할 수 있습니다.

캐시 동작을 생성하는 데 사용할 수 있는 헤더는 다음과 같습니다.


| 헤더 이름 | 설명 | 예시 값 | 
| --- | --- | --- | 
| CloudFront-Viewer-Cert-Serial-Number | 인증서 일련 번호의 16진수 표현 | 4a:3f:5c:92:d1:e8:7b:6c | 
| CloudFront-Viewer-Cert-Issuer | 발급자 고유 이름(DN)의 RFC2253 문자열 표현 | CN=rootcamtls.com,OU=rootCA,O=mTLS,L=Seattle,ST=Washington,C=US | 
| CloudFront-Viewer-Cert-Subject | 주체 고유 이름(DN)의 RFC2253 문자열 표현 | CN=client\$1.com,OU=client-3,O=mTLS,ST=Washington,C=US | 
| CloudFront-Viewer-Cert-Present | 인증서가 있는지 여부를 나타내는 1(존재) 또는 0(존재하지 않음)입니다. 이 값은 필수 모드에서 항상 1입니다. | 1 | 
| CloudFront-Viewer-Cert-Sha256 | 클라이언트 인증서의 SHA256 해시 | 01fbf94fef5569753420c349f49adbfd80af5275377816e3ab1fb371b29cb586 | 

오리진 요청의 경우 캐시 동작에 사용할 수 있는 위의 헤더 외에도 두 개의 추가 헤더가 제공됩니다.


| 헤더 이름 | 설명 | 예시 값 | 
| --- | --- | --- | 
| CloudFront-Viewer-Cert-Validity | notBefore 및 notAfter 날짜의 ISO8601 형식 | CloudFront-Viewer-Cert-Validity: NotBefore=2023-09-21T01:50:17Z;NotAfter=2024-09-20T01:50:17Z | 
| CloudFront-Viewer-Cert-Pem | 리프 인증서의 URL 인코딩 PEM 형식 | CloudFront-Viewer-Cert-Pem: -----BEGIN%20CERTIFICATE-----%0AMIIG<...reduced...>NmrUlw%0A-----END%20CERTIFICATE-----%0A | 

## 헤더 전달 구성
<a name="configure-header-forwarding"></a>

### 콘솔
<a name="configure-headers-console"></a>

확인 모드에서 CloudFront는 모든 뷰어 요청에 CloudFront-Viewer-Cert-\$1 헤더를 자동으로 추가합니다. 이러한 헤더를 오리진에 전달하려면 다음을 수행합니다.

1. 기본 목록 배포 페이지에서 뷰어 mTLS가 활성화된 배포를 선택하고 **동작** 탭으로 이동합니다.

1. 캐시 동작을 선택한 다음 **편집**을 선택합니다.

1. **오리진 요청 정책** 섹션에서 **정책 생성**을 선택하거나 기존 정책을 선택합니다.

1. 오리진 요청 정책에 다음 헤더가 포함되어 있는지 확인합니다.
   + CloudFront-Viewer-Cert-Serial-Number
   + CloudFront-Viewer-Cert-Issuer
   + CloudFront-Viewer-Cert-Subject
   + CloudFront-Viewer-Cert-Present
   + Cloudfront-Viewer-Cert-Sha256
   + CloudFront-Viewer-Cert-Validity
   + CloudFront-Viewer-Cert-Pem

1. **생성**(새 정책의 경우) 또는 **변경 사항 저장**(기존 정책의 경우)을 선택합니다.

1. 캐시 동작 내에서 정책을 선택하고 변경 사항을 저장합니다.

### AWS CLI 사용
<a name="configure-headers-cli"></a>

다음 예제에서는 확인 모드를 위한 mTLS 헤더가 포함된 오리진 요청 정책을 생성하는 방법을 보여줍니다.

```
aws cloudfront create-origin-request-policy \
  --origin-request-policy-config '{
    "Name": "MTLSHeadersPolicy",
    "HeadersConfig": {
      "HeaderBehavior": "whitelist",
      "Headers": {
        "Quantity": 5,
        "Items": [
          "CloudFront-Viewer-Cert-Serial-Number",
          "CloudFront-Viewer-Cert-Issuer",
          "CloudFront-Viewer-Cert-Subject",
          "CloudFront-Viewer-Cert-Validity",
          "CloudFront-Viewer-Cert-Pem"
        ]
      }
    },
    "CookiesConfig": {
      "CookieBehavior": "none"
    },
    "QueryStringsConfig": {
      "QueryStringBehavior": "none"
    }
  }'
```

## 헤더 처리 고려 사항
<a name="header-processing-considerations"></a>

인증서 헤더로 작업할 때는 다음 모범 사례를 고려하세요.
+ **헤더 검증:** 추가 보안 조치로 오리진의 인증서 헤더 값을 확인합니다.
+ **헤더 크기 제한:** 오리진 서버가 처리할 수 있도록 PEM 인증서 헤더의 크기를 키울 수 있습니다.
+ **캐시 고려 사항:** 캐시 키에서 인증서 헤더를 사용하면 캐시 조각화가 증가합니다.
+ **교차 오리진 요청:** 애플리케이션에서 CORS를 사용하는 경우 인증서 헤더를 허용하도록 구성해야 할 수 있습니다.

## 다음 단계
<a name="headers-next-steps"></a>

헤더 전달을 구성한 후 CloudFront 연결 함수 및 KeyValueStore를 사용하여 인증서 해지 확인을 구현할 수 있습니다. 해지 확인 구현에 대한 자세한 내용은 [CloudFront 연결 함수 및 KVS를 사용한 해지](revocation-connection-function-kvs.md) 섹션을 참조하세요.

# CloudFront 연결 함수 및 KVS를 사용한 해지
<a name="revocation-connection-function-kvs"></a>

CloudFront 연결 함수를 KeyValueStore와 결합하여 상호 TLS 인증에 대한 인증서 해지 확인을 구현할 수 있습니다. 이 접근 방식은 CloudFront의 기본 제공 인증서 검증을 보완하는 확장형 실시간 인증서 해지 메커니즘을 제공합니다.

연결 함수는 CloudFront 엣지 로케이션에서 TLS 연결 설정 중에 실행되는 JavaScript 함수로, mTLS 인증을 위한 사용자 지정 인증서 검증 로직을 구현할 수 있습니다. 연결 함수에 대한 자세한 내용은 [CloudFront 연결 함수 연결](connection-functions.md) 섹션을 참조하세요.

## 연결 함수에서 인증서 해지 작동 방식
<a name="how-revocation-works"></a>

CloudFront의 표준 인증서 검증은 인증서 체인, 서명 및 만료를 확인하지만 내장 인증서 해지 확인은 포함하지 않습니다. 연결 함수를 사용하면 TLS 핸드셰이크 중에 사용자 지정 해지 확인을 구현할 수 있습니다.

인증서 해지 프로세스는 다음과 같이 작동합니다.

1. 해지된 인증서 일련 번호를 CloudFront KeyValueStore에 저장합니다.

1. 클라이언트가 인증서를 제시하면 연결 함수가 간접 호출됩니다.

1. 함수는 KeyValueStore에 대해 인증서의 일련 번호를 확인합니다.

1. 스토어에서 일련 번호를 찾으면 인증서가 해지됩니다.

1. 함수는 해지된 인증서에 대한 연결을 거부합니다.

이 접근 방식은 CloudFront의 글로벌 엣지 네트워크에서 해지 확인을 실시간에 가깝게 제공합니다.

## 해지된 인증서에 대한 KeyValueStore 설정
<a name="setup-kvs-revoked-certs"></a>

먼저 KeyValueStore를 생성하여 해지된 인증서의 일련 번호를 저장합니다.

### KeyValueStore를 생성하는 방법(콘솔)
<a name="create-kvs-console"></a>

1. AWS Management Console에 로그인한 다음 [https://console.aws.amazon.com/cloudfront/v4/home](https://console.aws.amazon.com/cloudfront/v4/home)에서 CloudFront 콘솔을 엽니다.

1. 탐색 창에서 **키 값 스토어**를 선택합니다.

1. **키 값 스토어 생성**을 선택합니다.

1. 키 값 스토어의 이름(예: revoked-certificates)을 입력합니다.

1. (선택 사항) 설명을 추가합니다.

1. **키 값 스토어 생성**을 선택합니다.

### KeyValueStore를 생성하려면(AWS CLI)
<a name="create-kvs-cli"></a>

다음 예제에서는 KeyValueStore를 생성하는 방법을 보여줍니다.

```
aws cloudfront create-key-value-store \
  --name "revoked-certificates" \
  --comment "Store for revoked certificate serial numbers"
```

## 해지된 인증서 일련 번호 가져오기
<a name="import-revoked-serials"></a>

KeyValueStore를 생성한 후 해지된 인증서의 일련 번호를 가져와야 합니다.

### 해지 데이터 준비
<a name="prepare-revocation-data"></a>

해지된 인증서 일련 번호를 사용하여 JSON 파일을 생성합니다.

```
{
  "data": [
    {
      "key": "ABC123DEF456",
      "value": ""
    },
    {
      "key": "789XYZ012GHI",
      "value": ""
    }
  ]
}
```

### S3에서 가져오기
<a name="import-from-s3"></a>

1. 이 JSON 파일을 S3 버킷에 업로드합니다.

1. 파일을 KeyValueStore로 가져옵니다.

   ```
   aws cloudfront create-key-value-store \
     --name "revoked-certificates" \
     --import-source '{
       "SourceType": "S3",
       "SourceARN": "arn:aws:s3:::amzn-s3-demo-bucket1/revoked-serials.json"
     }'
   ```

## 해지 확인을 위한 연결 함수 생성
<a name="create-revocation-connection-function"></a>

KeyValueStore에 대해 인증서 일련 번호를 확인하는 연결 함수를 생성합니다.

### 연결 함수 코드 예제
<a name="revocation-function-example"></a>

다음 예제에서는 인증서 해지 확인을 수행하는 연결 함수를 보여줍니다.

```
import cf from 'cloudfront';

async function connectionHandler(connection) {
    const kvsHandle = cf.kvs();
    
    // Get client certificate serial number
    const clientSerialNumber = connection.clientCertificate.certificates.leaf.serialNumber;
    
    // Check if the serial number exists in the KeyValueStore
    const isRevoked = await kvsHandle.exists(clientSerialNumber.replaceAll(':', ''));
    
    if (isRevoked) {
        console.log(`Certificate ${clientSerialNumber} is revoked. Denying connection.`);
        connection.logCustomData(`REVOKED:${clientSerialNumber}`);
        connection.deny();
    } else {
        console.log(`Certificate ${clientSerialNumber} is valid. Allowing connection.`);
        connection.allow();
    }
    
}
```

### 연결 함수를 생성하려면(AWS CLI)
<a name="create-revocation-function-cli"></a>

다음 예제에서는 KeyValueStore 연결을 사용하여 연결 함수를 생성하는 방법을 보여줍니다.

```
aws cloudfront create-connection-function \
  --name "revocation-checker" \
  --connection-function-config '{
      "Comment": "Certificate revocation checking function",
      "Runtime": "cloudfront-js-2.0",
      "KeyValueStoreAssociations": {
          "Quantity": 1,
          "Items": [
              {
                  "KeyValueStoreARN": "arn:aws:cloudfront::123456789012:key-value-store/revoked-certificates"
              }
          ]
      }
  }' \
  --connection-function-code fileb://revocation-checker.js
```

## 함수를 배포에 연결합니다.
<a name="associate-revocation-function"></a>

연결 함수를 생성하고 게시한 후 [CloudFront 연결 함수 연결](connection-functions.md) 섹션에 설명된 대로 mTLS 지원 CloudFront 배포와 연결합니다.

# 연결 로그를 사용한 관찰성
<a name="connection-logs"></a>

CloudFront 연결 로그는 상호 TLS 인증 이벤트에 대한 자세한 가시성을 제공하므로 인증서 검증을 모니터링하고, 연결 시도를 추적하고, 인증 문제를 해결할 수 있습니다.

## 연결 로그란 무엇인가요?
<a name="what-are-connection-logs"></a>

연결 로그는 상호 TLS 지원 배포의 TLS 핸드셰이크 및 인증서 검증에 대한 자세한 정보를 캡처합니다. HTTP 요청 정보를 기록하는 표준 액세스 로그와 달리 연결 로그는 특히 다음을 포함한 TLS 연결 설정 단계에 중점을 둡니다.
+ 연결 상태(성공/실패)
+ 클라이언트 인증서 세부 정보
+ TLS 프로토콜 및 암호 정보
+ 연결 타이밍 지표
+ 연결 함수의 사용자 지정 데이터

이러한 로그는 인증서 기반 인증 이벤트에 대한 포괄적인 가시성을 제공하여 보안을 모니터링하고 문제를 해결하며 규정 준수 요구 사항을 충족하는 데 도움이 됩니다.

## 연결 로그 활성화
<a name="enable-connection-logs"></a>

연결 로그는 상호 TLS 인증이 활성화된 배포에만 사용할 수 있습니다. CloudWatch Logs, Amazon Data Firehose 및 Amazon S3를 비롯한 여러 대상으로 연결 로그를 전송할 수 있습니다.

### 사전 조건
<a name="connection-logs-prerequisites"></a>

연결 로그를 활성화하기 전에:
+ CloudFront 배포에 대한 상호 TLS 구성
+ CloudFront 배포에 대한 연결 로그 활성화
+ 선택한 로깅 대상에 필요한 권한이 있는지 확인합니다.
+ 교차 계정 전송의 경우 적절한 IAM 정책을 구성합니다.

### 연결 로그를 활성화하려면(콘솔)
<a name="enable-connection-logs-console"></a>

1. AWS Management Console에 로그인한 다음 [https://console.aws.amazon.com/cloudfront/v4/home](https://console.aws.amazon.com/cloudfront/v4/home)에서 CloudFront 콘솔을 엽니다.

1. 배포 목록에서 mTLS 지원 배포를 선택합니다.

1. **Logging**(로깅) 탭을 선택합니다.

1. **추가**를 선택합니다.

1. 로그를 수신할 서비스를 선택합니다.
   + **CloudWatch 로그**
   + **Firehose** – 
   + **Amazon S3**

1. **대상**에서 선택한 서비스의 리소스를 선택합니다.
   + CloudWatch Logs에서 **로그 그룹 이름**을 입력합니다.
   + Firehose의 경우 **Firehose 전송 스트림**을 선택합니다.
   + Amazon S3의 경우 **버킷 이름**을 입력합니다(접두사 포함은 선택 사항).

1. (선택 사항) 추가 설정 구성:
   + **필드 선택:** 포함할 특정 로그 필드를 선택합니다.
   + **출력 형식:** JSON, 일반, w3c, 원시 또는 Parquet(S3만 해당) 중에서 선택합니다.
   + **필드 구분 기호:** 로그 필드를 구분하는 방법을 지정합니다.

1. **변경 사항 저장**을 선택합니다

### 연결 로그를 활성화하려면(AWS CLI)
<a name="enable-connection-logs-cli"></a>

다음 예제에서는 CloudWatch API를 사용하여 연결 로그를 활성화하는 방법을 보여줍니다.

```
# Step 1: Create a delivery source
aws logs put-delivery-source \
  --name "cf-mtls-connection-logs" \
  --resource-arn "arn:aws:cloudfront::123456789012:distribution/E1A2B3C4D5E6F7" \
  --log-type CONNECTION_LOGS

# Step 2: Create a delivery destination
aws logs put-delivery-destination \
  --name "s3-destination" \
  --delivery-destination-configuration \
  "destinationResourceArn=arn:aws:s3:::amzn-s3-demo-bucket1"

# Step 3: Create the delivery
aws logs create-delivery \
  --delivery-source-name "cf-mtls-connection-logs" \
  --delivery-destination-arn "arn:aws:logs:us-east-1:123456789012:delivery-destination:s3-destination"
```

**참고**  
CloudWatch API를 사용하는 경우 로그를 다른 리전으로 전송할 때도 미국 동부(버지니아 북부) 리전(us-east-1)을 지정해야 합니다.

## 연결 로그 필드
<a name="connection-log-fields"></a>

연결 로그에는 각 TLS 연결 시도에 대한 세부 정보가 포함됩니다.


| 필드 | 설명 | 예제 | 
| --- | --- | --- | 
| eventTimestamp | 연결이 설정되거나 실패한 경우 ISO 8601 타임스탬프 | 1731620046814 | 
| connectionId | TLS 연결의 고유 식별자 | oLHiEKbQSn8lkvJfA3D4gFowK3\$1iZ0g4i5nMUjE1Akod8TuAzn5nzg== | 
| connectionStatus |  mTLS 연결 시도의 상태입니다.  | Success 또는 Failed | 
| clientIp | 연결 클라이언트의 IP 주소 | 2001:0db8:85a3:0000:0000:8a2e:0370:7334 | 
| clientPort | 클라이언트에서 사용하는 포트 | 12137 | 
| serverIp | CloudFront 엣지 서버의 IP 주소 | 99.84.71.136 | 
| distributionId | CloudFront 배포 ID | E2DX1SLDPK0123 | 
| distributionTenantId | CloudFront 배포 테넌트 ID(해당하는 경우) | dt\$12te1Ura9X3R2iCGNjW123 | 
| tlsProtocol | 사용된 TLS 프로토콜 버전 | TLSv1.3 | 
| tlsCipher | 연결에 사용되는 TLS 암호 제품군 | TLS\$1AES\$1128\$1GCM\$1SHA256 | 
| tlsHandshakeDuration | TLS 핸드셰이크 기간(밀리초) | 153 | 
| tlsSni | TLS 핸드셰이크의 서버 이름 표시 값 | d111111abcdef8.cloudfront.net | 
| clientLeafCertSerialNumber | 클라이언트 인증서의 일련 번호 | 00:b1:43:ed:93:d2:d8:f3:9d | 
| clientLeafCertSubject | 클라이언트 인증서의 제목 필드 | C=US, ST=WA, L=Seattle, O=Amazon.com, OU=CloudFront, CN=client.test.mtls.net | 
| clientLeafCertIssuer | 클라이언트 인증서의 발급자 필드 | C=US, ST=WA, L=Seattle, O=Amazon.com, OU=CloudFront, CN=test.mtls.net | 
| clientLeafCertValidity | 클라이언트 인증서의 유효 기간 | NotBefore=2025-06-05T23:28:21Z;NotAfter=2125-05-12T23:28:21Z | 
| connectionLogCustomData | 연결 함수를 통해 추가된 사용자 지정 데이터 | REVOKED:00:b1:43:ed:93:d2:d8:f3:9d | 

## 연결 오류 코드
<a name="connection-error-codes"></a>

```
Failed:ClientCertMaxChainDepthExceeded
Failed:ClientCertMaxSizeExceeded
Failed:ClientCertUntrusted
Failed:ClientCertNotYetValid
Failed:ClientCertExpired
Failed:ClientCertTypeUnsupported
Failed:ClientCertInvalid
Failed:ClientCertIntentInvalid
Failed:ClientCertRejected
Failed:ClientCertMissing
Failed:TcpError
Failed:TcpTimeout
Failed:ConnectionFunctionError
Failed:ConnectionFunctionDenied
Failed:Internal
Failed:UnmappedConnectionError
```

연결이 실패하면 CloudFront는 특정 사유 코드를 기록합니다.


| 코드 | 설명 | 
| --- | --- | 
| ClientCertMaxChainDepthExceeded | 최대 인증서 체인 깊이 초과 | 
| ClientCertMaxSizeExceeded | 최대 인증서 크기 초과 | 
| ClientCertUntrusted | 클라이언트 인증서를 신뢰할 수 없음 | 
| ClientCertNotYetValid | 인증서가 아직 유효하지 않음 | 
| ClientCertExpired | 인증서가 만료됨 | 
| ClientCertTypeUnsupported | 클라이언트 인증서 유형이 지원되지 않음 | 
| ClientCertInvalid | 인증서가 잘못됨 | 
| ClientCertIntentInvalid | 인증서 의도가 잘못됨 | 
| ClientCertRejected | 사용자 지정 검증에서 거부된 인증서 | 
| ClientCertMissing | 인증서 누락 | 
| TcpError |  연결을 설정하는 동안 오류 발생  | 
| TcpTimeout |  제한 시간 내에 연결을 설정할 수 없음  | 
| ConnectionFunctionError |  연결 함수 실행 중에 발견되지 않은 예외 발생  | 
| 내부 |  내부 서비스 오류 발생  | 
| UnmappedConnectionError |  다른 범주에 속하지 않는 오류 발생  | 