상호 TLS(뷰어) 검증을 위한 CloudFront 연결 함수 코드 쓰기 - Amazon CloudFront

상호 TLS(뷰어) 검증을 위한 CloudFront 연결 함수 코드 쓰기

CloudFront 연결 함수를 사용하면 mTLS 인증서 검증 및 사용자 지정 인증 로직을 위한 경량 JavaScript 함수를 작성할 수 있습니다. 연결 함수 코드는 클라이언트 인증서를 검증하고, 디바이스별 인증 규칙을 구현하고, 인증서 해지 시나리오를 처리하고, 전 세계 CloudFront 엣지 로케이션에서 TLS 연결에 대한 허용/거부 결정을 내릴 수 있습니다.

연결 함수는 자체 비즈니스 로직을 사용하여 CloudFront의 기본 제공 인증서 검증을 확장하는 강력한 방법을 제공합니다. HTTP 데이터를 처리하는 뷰어 요청 및 뷰어 응답 함수와 달리, 연결 함수는 TLS 계층에서 작동하며 인증서 정보, 클라이언트 IP 주소 및 TLS 연결 세부 정보에 액세스할 수 있습니다. 따라서 표준 PKI 검증을 넘어 제로 트러스트 보안 모델, 디바이스 인증 시스템 및 사용자 지정 인증서 검증 정책을 구현하는 데 이상적입니다.

연결 함수 코드는 시작 시간이 밀리초 미만인 안전하고 격리된 환경에서 실행되며 초당 수백만 개의 연결을 처리하도록 확장할 수 있습니다. 런타임은 인증서 검증 워크로드에 최적화되어 있으며 실시간 데이터 조회 작업을 위해 CloudFront KeyValueStore와 기본적으로 통합되어 인증서 해지 목록 확인 및 디바이스 허용 목록 검증과 같은 정교한 인증 시나리오를 지원합니다.

효과적인 연결 함수 코드를 작성하는 데 도움이 되도록 다음 주제를 참조하세요. 전체 코드 예제와 단계별 자습서는 이 가이드의 자습서 섹션을 참조하고 CloudFront 콘솔에서 사용할 수 있는 연결 함수 예제를 살펴보세요.

CloudFront 연결 함수 사용 사례 및 용도

CloudFront 연결 함수를 작성하기 전에 구현해야 하는 인증서 검증 또는 인증 로직 유형을 신중하게 결정합니다. 연결 함수는 표준 PKI 인증서 검사 외에 사용자 지정 검증이 필요한 특정 사용 사례에 맞게 설계되었습니다. 사용 사례를 이해하면 최적의 성능을 유지하면서 보안 요구 사항을 충족하는 효율적인 코드를 설계할 수 있습니다.

일반적인 연결 함수 사용 사례는 다음과 같습니다.

  • 인증서 해지 처리 - 인증서 교체 유예 기간, 내부 디바이스에 대한 신뢰할 수 있는 네트워크 예외 또는 해지된 인증서에 임시 액세스가 필요할 수 있는 긴급 액세스 시나리오를 포함하여 해지된 인증서를 처리하기 위한 사용자 지정 정책을 구현합니다.

  • 선택적 mTLS 지원 - 서로 다른 인증 정책으로 mTLS 및 비mTLS 연결을 모두 처리하여 레거시 클라이언트와의 호환성을 유지하면서 인증서를 지원하는 클라이언트에 더 나은 보안을 제공할 수 있습니다.

  • IP 기반 인증 - 클라이언트 IP 주소 확인과 인증서 검증을 결합하여 특정 지리적 리전, 회사 네트워크 또는 알려진 악성 IP 범위에서 액세스를 제한하는 등 보안을 강화합니다.

  • 다중 테넌트 인증서 검증 - 클라이언트 인증서 발급자 또는 주체 속성에 따라 다른 인증 기관 또는 검증 기준이 적용되는 테넌트별 검증 규칙을 구현합니다.

  • 시간 기반 액세스 제어 - 인증서 자체가 만료되지 않은 경우에도 특정 시간, 유지 관리 기간 또는 업무 기간 동안에만 인증서가 유효한 시간 기반 제한을 적용합니다.

연결 함수는 CloudFront가 표준 인증서 검증(신뢰 체인 확인, 만료 확인 및 서명 검증)을 수행한 후 TLS 연결이 설정되기 전에 실행됩니다. 이 타이밍을 사용하면 CloudFront의 내장 인증서 검증을 활용하면서 사용자 지정 검증 기준을 유연하게 추가할 수 있습니다. 함수는 표준 검증 결과를 수신하고 정보를 바탕으로 표준 및 사용자 지정 기준에 따라 연결을 허용할지 또는 거부할지를 결정할 수 있습니다.

연결 함수를 설계할 때는 검증 로직의 성능 영향을 고려하세요. 함수의 실행 한도는 5밀리초이므로 복잡한 작업은 속도에 맞게 최적화해야 합니다. 복잡한 계산 대신 빠른 데이터 조회에 KeyValueStore를 사용하고 잘못된 인증서는 빠르게 실패하도록 검증 로직을 구성합니다.

CloudFront 연결 함수 이벤트 구조 및 응답 형식

CloudFront 연결 함수는 뷰어 요청 및 뷰어 응답 함수와 다른 이벤트 구조를 수신합니다. 연결 함수는 HTTP 요청/응답 데이터 대신 인증 결정에 사용할 수 있는 인증서 및 연결 정보를 수신합니다.

연결 함수의 이벤트 구조

연결 함수는 인증서 및 연결 정보가 포함된 이벤트 객체를 수신합니다. 함수의 이벤트 구조는 다음과 같습니다.

{ "clientCertificate": { "certificates": { "leaf": { "serialNumber": "string", "issuer": "string", "subject": "string", "validity": { "notBefore": "string", "notAfter": "string", }, "sha256Fingerprint": "string" } } }, "clientIp": "string", "endpoint": "string", "distributionId": "string", "connectionId": "string" }

다음은 이벤트 객체 구조의 예입니다.

{ "clientCertificate": { "certificates": { "leaf": { "serialNumber": "00:9e:2a:af:16:56:e5:47:25:7d:2e:38:c3:f9:9d:57:fa", "issuer": "C=US, O=Ram, OU=Edge, ST=WA, CN=mTLS-CA, L=Snoqualmie", "subject": "C=US, O=Ram, OU=Edge, ST=WA, CN=mTLS-CA, L=Snoqualmie", "validity": { "notBefore": "2025-09-10T23:43:10Z", "notAfter": "2055-09-11T00:43:02Z" }, "sha256Fingerprint": "_w6bJ7aOAlGOj7NUhJxTfsfee-ONg_xop3_PTgTJpqs=" } } }, "clientIp": "127.0.0.1", "endpoint": "d3lch071jze0cb.cloudfront.net", "distributionId": "E1NXS4MQZH501R", "connectionId": "NpvTe1925xfj24a67sPQr7ae42BIq03FGhJJKfrQYWZcWZFp96SIIg==" }

연결 함수 응답 형식

연결 함수는 연결을 허용할지 또는 거부할지를 나타내는 응답 객체를 반환해야 합니다. 다음과 같이 헬퍼 메서드를 사용하여 연결 결정을 내립니다.

function connectionHandler(connection) { // Helper methods to allow or deny connections if (/* some logic to determine if function should allow connection */) { connection.allow(); } else { connection.deny(); } }

뷰어 요청 및 뷰어 응답 함수와 달리 연결 함수는 HTTP 요청 또는 응답을 수정할 수 없습니다. TLS 연결만 허용하거나 거부할 수 있습니다.

CloudFront 연결 함수 JavaScript 런타임 기능

CloudFront 연결 함수는 인증서 검증 워크로드에 특별히 최적화된 안전한 고성능 환경을 제공하는 CloudFront Functions JavaScript 런타임 2.0을 사용합니다. 런타임은 수 밀리초 이내에 시작하고 CloudFront의 글로벌 엣지 네트워크에서 수백만 개의 동시 실행을 처리하도록 설계되었습니다.

런타임 환경에는 다음과 같이 포괄적인 JavaScript 언어 지원이 포함됩니다.

  • ECMAScript 2020(ES11) 지원 - 선택적 연결(?.), nullish 병합(??) 및 대용량 인증서 일련 번호 처리를 위한 BigInt를 포함한 최신 JavaScript 기능

  • 기본 제공 객체 - 객체, 배열, JSON, 수학 및 날짜와 같은 표준 JavaScript 객체

  • 콘솔 로깅 - console.log()를 사용하여 인증서 검증 결정을 디버깅하고 모니터링합니다. 테스트 중에 로그를 실시간으로 사용할 수 있으며 개발 중인 검증 로직 문제를 해결하는 데 도움이 될 수 있습니다.

  • KeyValueStore 통합 - 초고속 데이터 조회 작업을 위한 CloudFront KeyValueStore에 대한 기본 액세스로 실시간 인증서 해지 확인, 디바이스 허용 목록 검증 및 테넌트별 구성 검색 활성화

연결 함수는 인증서 검증 시나리오를 위한 고성능에 최적화되어 있습니다. 런타임은 메모리 관리, 폐영역 회수 및 리소스 정리를 자동으로 처리하여 수백만 개의 동시 연결에서 일관된 성능을 보장합니다. 모든 작업은 결정적이고 빠르게 진행되도록 설계되었으며 KeyValueStore 조회는 일반적으로 마이크로초 단위로 완료됩니다.

런타임 환경은 함수 실행 간에 완전히 격리되므로 서로 다른 클라이언트 연결 간에 데이터가 유출되지 않습니다. 각 함수 실행은 정상 상태로 시작되며 이전 실행 결과 또는 다른 연결의 클라이언트 데이터에 액세스할 수 없습니다.

CloudFront 연결 함수 헬퍼 메서드 및 API

CloudFront 연결 함수는 인증서 검증 결정을 간소화하고 관찰성을 향상하도록 설계된 특수 헬퍼 메서드를 제공합니다. 이러한 방법은 연결 검증 워크플로에 최적화되어 있으며 CloudFront의 연결 로깅 및 모니터링 시스템과 원활하게 통합됩니다.

  • connection.allow() - TLS 연결이 진행되도록 허용합니다. 이 방법은 CloudFront에 신호를 보내어 TLS 핸드셰이크를 완료하고 클라이언트가 연결을 설정할 수 있도록 합니다. 인증서 검증을 통과하고 사용자 지정 인증 로직이 충족될 때 사용

  • connection.deny() - TLS 연결을 거부하고 핸드셰이크를 종료합니다. 이 방법은 연결을 즉시 닫고 HTTP 트래픽이 흐르지 않도록 합니다. 클라이언트에 TLS 연결 오류가 발생합니다. 잘못된 인증서, 인증 실패 또는 정책 위반에 사용

  • connection.logCustomData() - 연결 로그에 사용자 지정 데이터를 추가합니다(최대 800바이트의 UTF-8 텍스트). 이 방법을 사용하면 보안 모니터링, 규정 준수 감사 및 문제 해결을 위해 CloudFront 연결 로그에 검증 결과, 인증서 세부 정보 또는 결정 근거를 포함할 수 있습니다.

이러한 메서드는 연결 결정을 내리고 모니터링 및 디버깅과 관련된 정보를 로깅하는 데 필요한 깔끔하고 선언적인 인터페이스를 제공합니다. 허용/거부 패턴은 함수의 의도가 명확하고 CloudFront가 결정에 따라 연결 처리를 최적화할 수 있도록 합니다. 사용자 지정 로깅 데이터는 CloudFront 연결 로그에서 즉시 사용할 수 있으며, 보안 모니터링 및 운영 인사이트를 위한 로그 분석 도구와 함께 사용할 수 있습니다.

함수가 완료되기 전에 항상 connection.allow() 또는 connection.deny()를 직접 호출합니다. 두 메서드가 모두 직접 호출되지 않으면 CloudFront는 보안 예방 조치로 기본적으로 연결을 거부합니다.

CloudFront 연결 함수 KeyValueStore 통합

CloudFront 연결 함수는 CloudFront KeyValueStore를 사용하여 인증서 검증 시나리오에서 초고속 데이터 조회를 수행할 수 있습니다. KeyValueStore는 모든 CloudFront 엣지 로케이션에서 최종적으로 일관된 전역 데이터 액세스를 마이크로초 수준의 조회 시간으로 제공하므로 연결 함수에 특히 유용합니다. 따라서 TLS 핸드셰이크 중에 액세스해야 하는 인증서 해지 목록, 디바이스 허용 목록, 테넌트 구성 및 기타 검증 데이터를 유지하는 데 이상적입니다.

KeyValueStore 통합은 고성능 연결 검증 워크플로를 위해 특별히 설계되었습니다.

  • kvsHandle.exists(key) - 값을 검색하지 않고 KeyValueStore에 키가 있는지 확인합니다. 인증서 해지 확인과 같은 이진 검증 시나리오에서 인증서 일련 번호가 해지 목록에 있는지 여부만 알면 되는 가장 효율적인 방법입니다.

  • kvsHandle.get(key) - 더 복잡한 검증 시나리오를 위해 KeyValueStore에서 값을 검색합니다. 인증서 또는 디바이스 식별자와 연결된 구성 데이터, 검증 규칙 또는 메타데이터에 액세스해야 할 때 사용합니다.

KeyValueStore 작업은 비동기식이며 비동기/대기 구문과 함께 사용해야 합니다. KeyValueStore는 총 크기 제한이 10MB이며 최대 1천만 개의 키-값 페어를 지원합니다. KeyValueStore 데이터는 모든 엣지 로케이션에서 최종적으로 일관되며 업데이트는 일반적으로 몇 초 이내에 전파됩니다.

최적의 성능을 위해 KeyValueStore 키를 구성하여 조회 작업을 최소화합니다. 인증서 일련 번호를 간단한 해지 확인을 위한 키로 사용하거나 다중 CA 환경의 발급자 해시와 일련 번호를 결합한 복합 키를 생성합니다. 데이터 구조를 설계할 때 키 복잡성과 KeyValueStore 용량 간의 장단점을 고려합니다.

async 및 await 사용

연결 함수는 KeyValueStore 작업 또는 기타 비동기 작업으로 작업할 때 필수적인 비동기/대기 구문을 사용하는 비동기 작업을 지원합니다. 비동기/대기 패턴을 사용하면 TLS 핸드셰이크 처리에 필요한 고성능 특성을 유지하면서 연결 결정을 내리기에 앞서 함수가 KeyValueStore 조회가 완료될 때까지 대기할 수 있습니다.

KeyValueStore 작업은 매우 빠르지만 CloudFront의 분산 인프라 전반에서 조정이 필요한 네트워크 작업이므로 연결 함수에는 적절한 비동기/대기 사용이 중요합니다. 런타임은 promise 해석을 자동으로 처리하고 함수가 5밀리초 실행 한도 내에서 완료되도록 합니다.

예 : KeyValueStore와 비동기 연결 함수
import cf from 'cloudfront'; async function connectionHandler(connection) { const kvsHandle = cf.kvs(); // Async operation to check KeyValueStore for certificate revocation const isRevoked = await kvsHandle.exists(connection.clientCertificate.certificates.leaf.serialNumber); if (isRevoked) { // Log the revocation decision with certificate details connection.logCustomData(`REVOKED_CERT:${connection.clientCertificate.certificates.leaf.serialNumber}:${connection.clientCertificate.certificates.leaf.issuer}`); console.log(`Denying connection for revoked certificate: ${connection.clientCertificate.certificates.leaf.serialNumber}`); return connection.deny(); } // Log successful validation for monitoring connection.logCustomData(`VALID_CERT:${connection.clientCertificate.certificates.leaf.serialNumber}`); console.log(`Allowing connection for valid certificate: ${connection.clientCertificate.certificates.leaf.serialNumber}`); return connection.allow(); }

KeyValueStore 메서드 또는 기타 비동기 작업을 직접 호출할 때는 항상 비동기/대기를 사용합니다. 연결 함수 런타임은 promise 해석을 자동으로 처리하고 TLS 핸드셰이크 처리의 엄격한 타이밍 제약 내에서 적절한 실행 흐름을 보장합니다. async/await는 연결 함수 환경에서 더 명확한 오류 처리와 더 나은 성능을 제공하므로 .then() 또는 콜백 패턴을 사용하지 마세요.

비동기 연결 함수를 설계할 때 KeyValueStore 작업 수를 최소화하고 검증 로직에서 가능한 한 빨리 수행하도록 코드를 구성합니다. 이렇게 하면 성능을 극대화하고 트래픽이 많은 기간 동안 제한 시간 문제의 위험을 줄일 수 있습니다. 관련 검증 검사를 일괄 처리하고 사용 사례에 가장 효율적인 KeyValueStore 메서드(exists() vs get())를 사용하는 것이 좋습니다.

연결 함수 코드 예제

다음 예제는 다양한 검증 시나리오에 일반적인 연결 함수 패턴을 보여줍니다. 다음 예제를 자체 연결 함수 구현의 시작점으로 사용합니다.

예 : 디바이스 인증서 검증

이 예제에서는 IoT 디바이스, 게임 콘솔 및 기타 클라이언트 인증 시나리오에 대한 디바이스 일련 번호 및 인증서 제목 필드를 검증합니다.

async function connectionHandler(connection) { // Custom validation: check device serial number format const serialNumber = connection.clientCertificate.certificates.leaf.serialNumber; if (!serialNumber.startsWith("DEV")) { connection.logCustomData(`INVALID_SERIAL:${serialNumber}`); return connection.deny(); } // Validate certificate subject contains required organizational unit const subject = connection.clientCertificate.certificates.leaf.subject; if (!subject.includes("OU=AuthorizedDevices")) { connection.logCustomData(`INVALID_OU:${subject}`); return connection.deny(); } // Allow connection for valid devices connection.logCustomData(`VALID_DEVICE:${serialNumber}`); return connection.allow(); }

이 함수는 디바이스 일련 번호 형식 및 조직 단위 확인을 포함하여 표준 인증서 검증 외에도 여러 검증 검사를 수행합니다.

예 : 혼합 인증을 사용하는 선택적 mTLS

이 예제에서는 서로 다른 인증 정책을 사용하여 mTLS 연결과 비mTLS 연결을 모두 처리합니다.

async function connectionHandler(connection) { if (connection.clientCertificate) { // mTLS connection - enhanced validation for certificate holders const subject = connection.clientCertificate.certificates.leaf.subject; connection.logCustomData(`MTLS_SUCCESS:${subject}:${connection.clientIp}`); console.log(`mTLS connection from: ${subject}`); return connection.allow(); } else { // Non-mTLS connection - apply IP-based restrictions const clientIp = connection.clientIp; // Only allow non-mTLS from specific IP ranges if (clientIp.startsWith("203.0.113.") || clientIp.startsWith("198.51.100.")) { connection.logCustomData(`NON_MTLS_ALLOWED:${clientIp}`); console.log(`Non-mTLS connection allowed from: ${clientIp}`); return connection.allow(); } connection.logCustomData(`NON_MTLS_DENIED:${clientIp}`); return connection.deny(); } }

이 함수는 신뢰할 수 있는 IP 범위의 레거시 클라이언트와의 호환성을 유지하면서 인증서를 통해 클라이언트에 향상된 보안을 제공합니다.