본문으로 건너뛰기

SGTM Ad Block 우회 아키텍처 구성 가이드 (CloudFront 경로 마스킹)

플랫폼엔지니어링 / server-side-gtm담당자백도현새 버전 제안일26.10.22
AI 요약

Ad Blocker가 URL 경로만으로 gtm.js·g/collect 요청을 차단하는 문제를 CloudFront Function의 경로 재작성으로 우회하는 구성 절차.

목적

Ad Blocker는 서비스 도메인과 관계없이, 브라우저가 요청하는 URL의 경로(Path) — 즉 .../gtm.js, .../g/collect 같은 파일 이름 자체 — 를 기준으로 네트워크 요청을 차단한다. EKS Pod로 운영되는 Server-Side GTM(SGTM) 컨테이너 앞에서 이 문제는 두 지점에서 발생한다.

  • 1차 문제 (Loader 차단): 클라이언트가 .../gtm.js 스크립트를 로드하는 요청 자체가 차단되어 GTM 컨테이너가 실행되지 않는다.
  • 2차 문제 (Collection 차단): gtm.js 로드에 성공해도, 이후 GA4 등으로 데이터를 전송하는 .../g/collect 경로 역시 차단 목록에 포함되어 데이터 수집이 누락된다.

이 가이드를 수행하면, Ad Blocker에 걸리지 않는 임의의 '안전한' 경로(예: /my-loader.js, /my-data-point)로 클라이언트 요청을 보내고, AWS 인프라의 가장 앞단(CloudFront)에서 이를 SGTM 컨테이너가 이해하는 실제 경로(/gtm.js, /g/collect)로 내부적으로 재작성해 전달하는 구성이 완성된다 — 경로 마스킹 및 재작성(Path Masking & Rewrite).

완성 후 요청 흐름

  1. Client — GTM 스크립트 태그가 CloudFront 도메인(예: analytics.your-domain.com)을 가리킨다.
  2. AWS CloudFront — 요청을 가장 먼저 받는다. CloudFront Function(Viewer Request)이 요청 URI를 검사해 /my-loader.js→/gtm.js, /my-data-point→/g/collect로 즉시 변경한다.
  3. AWS ALB (EKS Ingress) — 경로가 변경된 요청(예: /gtm.js)을 CloudFront로부터 수신해, Ingress 규칙에 따라 EKS 클러스터 내 SGTM 서비스(Pod)로 전달한다.
  4. EKS (SGTM Pod) — 원본 경로(/gtm.js 또는 /g/collect) 요청을 받아 정상적으로 처리한다. 컨테이너 쪽 변경은 필요 없다.

클라이언트와 Ad Blocker는 .../gtm.js, .../g/collect로의 요청을 전혀 인지하지 못하므로 차단 규칙이 발동하지 않는다.

역할 구분: Amazon EKS(with AWS Load Balancer Controller)는 SGTM 컨테이너(Pod)를 실행하고, Kubernetes Ingress 리소스를 기반으로 ALB를 자동 프로비저닝·관리해 클러스터 외부 트래픽을 SGTM 서비스로 라우팅하는 게이트웨이 역할을 한다. AWS CloudFront는 이 ALB 앞단에 배치되어 CDN 역할뿐 아니라, CloudFront Function을 통해 엣지에서 요청 경로를 재작성하는 핵심 로직을 수행한다.

사전 조건

  • CloudFront의 Origin으로 사용할 EKS Ingress ALB의 DNS 주소 (예: k8s-sst-ingress-1a2b3c4d5e-1234567890.ap-northeast-2.elb.amazonaws.com). (확인 필요) — 원문은 "출력된 ADDRESS 필드에서 확인한다"고만 서술하며, 이를 조회하는 구체적인 명령어는 명시하지 않았다.
  • Ad Blocker에 차단되지 않는 고유 서브도메인(CloudFront Alternate domain name)과 그 도메인에 대응하는 ACM 인증서.

수행 방법

1단계: EKS Ingress ALB 주소 확인

CloudFront의 원본(Origin)으로 사용할 ALB의 DNS 주소를 먼저 확인한다. 출력된 ADDRESS 필드에서 SGTM Ingress에 연결된 ALB의 DNS 주소를 확인한다.

예: k8s-sst-ingress-1a2b3c4d5e-1234567890.ap-northeast-2.elb.amazonaws.com

2단계: CloudFront Function 생성 (경로 재작성)

  1. CloudFront 콘솔의 왼쪽 메뉴에서 Functions로 이동한다.
  2. Create function을 클릭하고 함수 이름(예: gtm_path_rewriter)을 지정한다.
  3. 아래 코드를 복사하여 붙여넣는다.
// CloudFront Function 코드 (gtm_path_rewriter)

function handler(event) {
    var request = event.request;
    var uri = request.uri;

    // 1. GTM Loader 스크립트 경로 변환
    //    클라이언트 요청: /my-loader.js  =>  원본(ALB) 요청: /gtm.js
    if (uri === '/my-loader.js') {
        request.uri = '/gtm.js';
    }

    // 2. GTM Collection(GA4 등) 엔드포인트 경로 변환
    //    클라이언트 요청: /my-data-point =>  원본(ALB) 요청: /g/collect
    //    (이 경로는 4단계 GTM 설정과 일치해야 함)
    else if (uri === '/my-data-point') {
        // SST 컨테이너의 GA4 클라이언트가 수신하는 경로로 변경
        request.uri = '/g/collect';
    }

    return request;
}
  1. 함수를 Save하고 Publish 탭으로 이동해 함수를 정식으로 게시한다.

3단계: CloudFront Distribution 생성 및 연결

  1. CloudFront 콘솔에서 Create Distribution을 선택한다.
  2. Origin (원본)
    • Origin domain: 1단계에서 확인한 EKS Ingress ALB의 DNS 주소를 입력한다.
    • Protocol: HTTPS only를 권장한다.
  3. Default cache behavior (기본 동작)
    • Cache policy: CachingDisabled(모든 요청을 원본으로 전달) 또는 CachingOptimized(GTM 스크립트 캐시를 원할 경우)를 선택한다.
    • [매우 중요] Origin request policy: AllViewer(모든 헤더, 쿼리스트링, 쿠키 전달)를 선택한다. EKS ALB는 Host 헤더를 기준으로 Ingress 규칙을 매칭하고, GTM은 id= 쿼리 스트링이 필요하기 때문이다. AllViewer는 이 모든 것을 원본(ALB)으로 전달한다.
  4. Function associations (함수 연결)
    • Viewer Request 이벤트 유형에 대해 Function type을 CloudFront Function으로 선택하고, Function ARN에서 2단계에서 생성한 gtm_path_rewriter 함수를 선택한다.
  5. Settings (설정)
    • Alternate domain name (CNAME): Ad Blocker에 차단되지 않은 고유 서브도메인(예: analytics.your-domain.com)을 등록한다.
    • SSL certificate: 해당 도메인에 맞는 ACM 인증서를 선택한다.
  6. Create Distribution을 클릭하고 배포가 완료될 때까지 기다린다.

4단계: GTM 설정 변경 (Web & Server)

Web GTM (클라이언트 사이드)

  • GA4 데이터를 SGTM으로 전송하는 Google 태그(GA4 구성 태그)를 연다.
  • 구성 매개변수에 다음을 추가한다.
    • 매개변수: transport_url
    • 값: https://analytics.your-domain.com/my-data-point (3단계에서 설정한 CloudFront 도메인 + 2단계 Function 코드에서 설정한 '안전한' 경로)

Server GTM (서버 사이드 - EKS)

이 설정은 변경할 필요가 없다. CloudFront Function이 이미 /my-data-point를 /g/collect로 변환해 주므로, SST의 GA4 클라이언트는 기존처럼 /g/collect 경로로 들어오는 요청을 정상적으로 처리한다.

5단계: 웹사이트 HTML 스크립트 태그 수정

웹사이트 <head> 태그의 GTM 스크립트 태그를 CloudFront 도메인과 새로운 '안전한' 경로로 수정한다.

[기존 코드 (차단 대상)]

<script async src="https://analytics.your-domain.com/gtm.js?id=GTM-XXXXX"></script>

[변경 코드 (우회 적용)]

<script async src="https://analytics.your-domain.com/my-loader.js?id=GTM-XXXXX"></script>

확인 방법

원문은 별도의 검증 절차 대신 기대 동작만 서술한다: 설정이 모두 완료되면 브라우저는 .../my-loader.js와 .../my-data-point로 요청을 보내고 Ad Blocker는 이를 통과시킨다. CloudFront가 이 요청들을 EKS ALB로 전달하기 전에 .../gtm.js와 .../g/collect로 재작성하므로, EKS의 SGTM 컨테이너는 아무런 변경 없이 트래픽을 정상 처리하게 된다. (확인 필요) — 브라우저 네트워크 탭 확인 등 구체적인 검증 절차는 원문에 없다.

관련 문서

  • technology-data/server-side-gtm/sgtm-ga-collection-parity-test-2025-09.md — 이 가이드가 해결하는 Ad Blocker 차단 문제를 최초로 발견한 기능 테스트 기록.

코멘트

아직 코멘트가 없어요

종류