← 목록으로
eTLD와 eTLD+1 — 브라우저가 "같은 사이트"를 판단하는 기준

브라우저의 SameSite 쿠키 정책은 eTLD+1을 기준으로 same-site 여부를 판단합니다. TLD, eTLD, eTLD+1 각각의 정의와 관계를 정리합니다.

TLD

TLD(Top-Level Domain)는 도메인의 가장 오른쪽 레이블입니다. ICANN이 관리합니다.

example.com     → TLD: com
example.co.kr   → TLD: kr
example.org     → TLD: org

eTLD

eTLD(effective Top-Level Domain)는 도메인 등록이 불가능한 접미사 전체입니다. .com은 바로 아래에 도메인을 등록할 수 있지만, .kr.co.kr 같은 2차 구조를 거쳐야 등록됩니다. eTLD는 이런 깊이가 다른 도메인 구조를 동일한 레벨로 정규화합니다.

.com       → 바로 아래에 등록 가능    → example.com
.co.kr     → 바로 아래에 등록 가능    → example.co.kr
.kr        → 바로 아래에 등록 불가    → co.kr은 누구의 도메인도 아님
도메인TLDeTLD
example.comcomcom
example.co.krkrco.kr
mysite.github.ioiogithub.io
app.netlify.appappnetlify.app
example.tokyo.jpjptokyo.jp

.com은 TLD와 eTLD가 동일합니다. .co.kr은 TLD는 .kr이지만 eTLD는 .co.kr입니다. github.io는 TLD가 .io지만, GitHub이 서브도메인을 사용자별로 할당하는 구조이므로 github.io 전체가 eTLD입니다.

eTLD+1

eTLD+1은 eTLD 바로 왼쪽에 레이블 하나를 추가한 것입니다. 브라우저가 인식하는 도메인 소유권 경계이자 "사이트" 단위입니다.

전체 도메인eTLDeTLD+1
www.example.comcomexample.com
api.example.comcomexample.com
shop.example.co.krco.krexample.co.kr
user123.github.iogithub.iouser123.github.io
my-app.netlify.appnetlify.appmy-app.netlify.app

www.example.comapi.example.com은 eTLD+1이 example.com으로 동일합니다. 같은 소유자의 도메인이므로 같은 사이트입니다.

user123.github.iouser456.github.io는 eTLD+1이 다릅니다. github.io가 eTLD로 등록되어 있으므로 각각 별개의 사이트로 격리됩니다.

SameSite 판단

브라우저의 SameSite 판단은 두 URL의 eTLD+1 비교입니다.

https://www.example.com  →  eTLD+1: example.com
https://api.example.com  →  eTLD+1: example.com
→ same-site ✓

https://example.com      →  eTLD+1: example.com
https://evil.com         →  eTLD+1: evil.com
→ cross-site ✗

https://a.github.io      →  eTLD+1: a.github.io
https://b.github.io      →  eTLD+1: b.github.io
→ cross-site ✗

서브도메인은 eTLD+1이 동일하므로 항상 same-site입니다. evil.sub.example.combank.example.com은 eTLD+1이 example.com으로 같아 SameSite=Lax를 설정해도 쿠키가 전송됩니다.

Public Suffix List

eTLD 목록은 Mozilla가 관리하는 Public Suffix List(PSL)에서 정의됩니다. 모든 주요 브라우저가 이 목록을 사용합니다.

PSL 항목은 두 종류로 구분됩니다.

ICANN 도메인 — 국가·일반 최상위 도메인과 그 하위 구조입니다.

// com
com

// kr
kr
co.kr
or.kr
go.kr

// jp
jp
tokyo.jp
osaka.jp

PRIVATE 도메인 — 기업이 사용자에게 서브도메인을 할당하는 서비스입니다.

// GitHub Pages
github.io

// Netlify
netlify.app

// Vercel
vercel.app

// AWS S3
s3.amazonaws.com

PSL에 github.io가 등록되어 있으므로 username.github.io는 각각 독립된 eTLD+1로 취급됩니다.

Public Suffix List에 등록하는 방법

자체 서비스에서 사용자별 서브도메인을 발급하는 경우(예: username.myservice.com), PSL의 PRIVATE 섹션에 등록하면 각 서브도메인이 독립된 eTLD+1로 취급됩니다. 등록 절차는 GitHub 저장소에서 Pull Request를 제출하는 방식입니다.

등록 절차

1. 자격 확인 — PRIVATE 섹션 등록 요청은 반드시 도메인 소유자가 직접 제출해야 합니다. 제3자가 대신 제출하는 것은 거부됩니다. ICANN 섹션 변경은 해당 레지스트리, ICANN 또는 IANA에서 요청해야 합니다.

2. 가이드라인 확인GitHub Wiki의 Guidelines에서 포맷, 정렬 규칙, 수락 기준을 확인합니다. 항목은 TLD 기준 알파벳순으로 정렬되며, 새 항목은 올바른 위치에 삽입해야 합니다.

// My Service : https://myservice.com
// Submitted by Admin <admin@myservice.com>
myservice.com

3. DNS 검증 레코드 추가 — 등록하려는 각 도메인에 _psl TXT 레코드를 추가합니다. 값은 제출한 PR의 URL입니다.

$ dig TXT _psl.myservice.com
# "https://github.com/publicsuffix/list/pull/1234"

이 레코드는 PR 승인 후에도 유지해야 합니다. 향후 자동화를 통해 _psl 레코드가 없는 항목은 제거 대상이 될 수 있습니다.

4. PR 제출 및 테스트 — Pull Request를 생성하면 CI에서 자동으로 테스트가 실행됩니다. 테스트를 통과하지 못한 PR은 거부됩니다. 로컬에서 make test로 미리 검증할 수 있습니다.

거부 사유

다음 목적의 등록은 거부됩니다.

  • 제3자 서비스의 rate limit 우회
  • 보안 보호 기능 회피
  • 소규모, 실험적, 단기 프로젝트
  • 도메인 등록 기간이 제출일로부터 2년 미만

주의사항

PSL 등록은 전역적 영향을 가집니다. 모든 주요 브라우저가 이 목록을 사용하므로, 등록되면 해당 도메인의 서브도메인 간 쿠키 공유가 차단되고 각각 독립된 사이트로 취급됩니다. 등록 후 철회는 어렵고 우선순위가 낮으므로 신중하게 결정해야 합니다. 또한 브라우저 반영까지 수개월이 소요될 수 있습니다.

정리

도메인: blog.shop.example.co.kr

TLD     →  kr                    (ICANN이 관리하는 최상위)
eTLD    →  co.kr                 (등록 불가능한 접미사 전체)
eTLD+1  →  example.co.kr         (브라우저가 판단하는 "사이트" 단위)
나머지  →  blog.shop             (같은 사이트 내의 서브도메인)
  • TLD는 도메인의 가장 오른쪽 레이블. 등록 구조를 반영하지 못합니다.
  • eTLD는 도메인 등록이 불가능한 접미사 전체. .com, .co.kr, .github.io를 동일 레벨로 취급합니다.
  • eTLD+1은 eTLD 왼쪽에 레이블 하나를 붙인 것. 브라우저가 판단하는 사이트 경계입니다.
  • SameSite 판단은 두 URL의 eTLD+1 비교. 같으면 same-site, 다르면 cross-site.
  • Public Suffix List는 Mozilla가 관리하며 모든 주요 브라우저가 이 목록으로 eTLD를 결정합니다.

References