1P by GN⁺ | ★ favorite | 댓글 1개
  • uBlock Origin 커밋은 Firefox 네트워크 처리에서 CNAME uncloaking 흐름을 재작성하고, DNS 조회로 얻은 IP를 details.ip에 반영하도록 바꿈
  • 기존 cnames Map 캐시는 사라지고, dnsList, dnsDict, dnsWritePtr 기반의 256개 링 버퍼60000ms TTL 캐시로 대체됨
  • DNS 조회는 browser.dns.resolve(hn, [ 'canonical_name' ])를 사용하며, 결과의 canonicalNameaddresses[0]를 각각 CNAME과 IP로 활용함
  • CNAME 예외 처리는 1st-party, ignore list, root document 조건을 유지하고, IPv4 주소나 [로 시작하는 호스트명은 재조회에서 제외
  • Chromium 최소 버전은 80.0, Opera 최소 버전은 67.0으로 올라가며, 숨김 설정의 cnameMaxTTL 기본값은 제거됨

Firefox DNS 캐시 구조 재작성

  • platform/firefox/vapi-background-ext.js의 CNAME uncloaking 관련 코드가 전역 Map 중심 구조에서 클래스 내부 DNS 캐시 구조로 바뀜
  • 기존 cnameUncloakEnabled 전역 상태와 cnames Map 대신 다음 필드로 캐시를 관리함
    • dnsList: 링 버퍼
    • dnsWritePtr: 다음 쓰기 위치
    • dnsMaxCount: 최대 256
    • dnsDict: 호스트명에서 링 버퍼 인덱스로 매핑
    • dnsEntryTTL: 60000ms
  • 생성자에서는 canUncloakCnamescnameUncloakEnabledtrue로 초기화됨

요청 처리 흐름

  • onBeforeSuspendableRequest(details)는 요청 URL에서 호스트명을 뽑은 뒤 dnsFromCache(hn)로 캐시를 먼저 확인함
  • 캐시된 DNS 항목에 ip가 있으면 details.ip에 설정함
  • 기본 super.onBeforeSuspendableRequest(details) 호출 결과가 취소나 리다이렉트 등으로 끝나면 그 결과를 그대로 반환함
  • 캐시된 DNS 항목이 Promise가 아니면 onAfterDNSResolution(hn, details, dnsEntry)로 후속 처리를 이어감
  • DNS 재조회 조건을 만족하지 않거나 details.proxyInfo?.proxyDNS가 있으면 추가 DNS 처리를 하지 않음

DNS 조회와 저장 방식

  • dnsShouldResolve(hn)은 빈 호스트명, [로 시작하는 호스트명, IPv4 주소 형태를 DNS 조회 대상에서 제외
  • dnsResolve(hn, details)는 링 버퍼의 현재 위치에 호스트명을 등록하고 dnsAPI.resolve(hn, [ 'canonical_name' ])를 호출함
  • 조회 성공 시 dnsToCache(hn, rec, details)가 실행되고, 실패하면 dnsToCache(hn)로 빈 항목을 캐시에 남김
  • dnsToCache는 새 캐시 항목에 hn과 만료 시각을 저장함
    • cnameFromRecord가 값을 반환하면 dnsEntry.cname에 저장함
    • ipFromRecord가 값을 반환하면 dnsEntry.ip에 저장함
  • dnsFromCache는 캐시 항목이 Promise이면 그대로 반환하고, 만료된 항목은 dnsListdnsDict에서 제거함

CNAME과 IP 반영 조건

  • cnameFromRecord(hn, record, details)record.canonicalName이 없거나 원래 호스트명과 같으면 CNAME을 반환하지 않음
  • cnameIgnore1stParty가 켜져 있으면 CNAME과 원래 호스트명의 도메인이 같은 경우를 제외함
  • cnameIgnoreList가 있으면 해당 정규식에 매칭되지 않는 CNAME은 제외됨
  • cnameIgnoreRootDocument가 켜져 있으면 요청 호스트명이 details.documentUrl || details.url의 호스트명과 같을 때 제외함
  • ipFromRecord(record)record.addresses가 배열이고 비어 있지 않을 때 첫 번째 주소 addresses[0]를 반환함

URL 재작성과 후속 필터링

  • onAfterDNSResolution은 DNS 항목에 CNAME이 있고 cnameUncloakEnabled가 켜져 있으면 uncloakURL로 URL을 재작성함
  • URL을 바꿀 때 기존 URL은 details.aliasURL에 저장하고, 새 URL은 details.url에 반영함
  • DNS 항목의 IP가 있고 현재 details.ip와 다르면 details.ip를 갱신함
  • CNAME 재작성이나 IP 변경이 발생한 경우에만 기본 클래스의 onBeforeSuspendableRequest(details)를 다시 호출함
  • uncloakURL은 URL 안의 호스트명 위치를 찾아 CNAME으로 바꾸며, cnameReplayFullURL 값에 따라 전체 URL을 이어 붙이거나 경로 앞부분까지만 유지함

설정과 manifest 변경

  • setOptions에서 cnameMaxTTL 처리가 제거됨
  • 옵션 변경 시 기존 cnames Map 초기화 대신 dnsList.fill(null)dnsDict.clear()로 DNS 캐시를 비움
  • src/js/background.js의 숨김 설정 기본값에서 cnameMaxTTL: 120이 삭제됨
  • platform/chromium/manifest.jsonminimum_chrome_version73.0에서 80.0으로 변경됨
  • platform/opera/manifest.jsonminimum_opera_version60.0에서 67.0으로 변경됨

댓글과 토론

Hacker News 의견들
  • 제목이 잘못된 것 같음. uBlock Origin은 이미 여러 해 전부터 이 기능을 지원했고, 다만 Firefox에서만 가능했음
    이번 건 완전히 새로운 기능이라기보다 그 코드의 리팩터링으로 보임

    • 지금도 지원하고, 예전에도 지원했음 :P
    • 단순 리팩터링 이상으로 보임. 이제 실제 요청이 나가기 전에 IP 기준 차단을 더 이른 단계에서 할 수 있게 된 듯함
      다만 한 도메인에 여러 IP가 있을 때 브라우저가 어떤 IP를 고를지 알 수 없어서 완벽하진 않음
    • 제목을 페이지 제목으로 되돌렸음. 제출 제목은 “uBlock Origin supports filtering CNAME cloaking sites on Firefox now”였음
      더 정확하고 중립적인 제목을 제안하면 다시 바꿀 수 있음. 다만 추가 맥락 없는 GitHub 커밋은 보통 HN 스레드로는 썩 좋지 않음
  • 아직 직접 피해를 보진 않았지만, Chrome이 정말 uBO를 없애면 갈아탈 수 있게 이미 확장들을 Firefox용으로 다시 손보고 있음

    • “만약”이 아니라 “언제”의 문제임. 2020년부터 이미 “언제”였고, 실제로 오고 있음
      몇 번의 릴리스 안에 도착할 테니 준비해야 함
    • 가족들을 Brave로 옮기고 있음. 차이를 거의 못 느끼고, 브라우저가 사용자 중심 콘텐츠 필터링을 계속 지원할 거라는 확신이 더 큼
    • 이미 Canary 릴리스에서는 제거됐음
    • “확장을 Firefox용으로 다시 쓴다”는 게 무슨 뜻인지 모르겠음. Firefox도 같은 API를 씀
      많아야 background.service_workerbackground.scripts로 바꾸는 정도, 말 그대로 키 이름만 바꾸면 됨
    • 잘 모르는 사람들을 위해 묻자면, uBO가 무엇이고 대부분의 확장에 어떤 영향을 주는 건가?
  • uBlock Origin은 Firefox를 더 훌륭하게 만들어 주는 요소이고, Chrome 등 대신 Firefox를 쓰는 큰 이유 중 하나임
    인터넷을 실제로 탐색 가능한 상태로 만들어 줌

    • 몇 년 전에 이 조합으로 옮겼고, 떠날 이유를 한 번도 못 봤음. Android 휴대폰에서도 마찬가지로, 내가 본 유일하게 쓸 만한 모바일 웹 경험임
      10년 넘게 몇몇 사이트에서 표시 문제가 있었지만, 그런 사이트들은 Chrome에서도 문제가 있었음
      개인적으로 광고는 현대 사회의 암 같은 존재라고 봄. 하얀 거짓말과 그렇지 않은 거짓말, 조작이 뒤섞여 있고, 거기에 엄청난 돈이 흐른다는 점 때문에 오히려 더 존중할 만한 게 없음
    • Mozilla가 광고 회사가 되어 가고 있어서 그 점은 바뀔 수 있음
    • Brave와 Firefox를 둘 다 써봤는데 솔직히 큰 차이는 못 느꼈음. 그래도 철학과 비영리 조직에서 나온다는 점 때문에 Firefox를 더 선호함
      Brave도 품질 좋은 프로젝트라 백업으로 쓰고, 가끔은 창 분할과 훨씬 나은 탭 관리 때문에 Vivaldi도 섞어 씀
  • CNAME 클로킹이란 게 광고 사이트가 와일드카드 레코드를 가리키는 무작위 생성 하위 도메인을 쓰는 걸 뜻하나?

    • 그게 일부임
      보통 contentsite.com을 방문하면 광고는 adsite.com에서 제공됨. 광고 차단 규칙은 adsite.com을 막으면 광고가 보이지 않음
      CNAME 클로킹은 메인 사이트가 adsite.contentsite.com 같은 하위 도메인을 adsite.com으로 가리키게 만드는 방식임. 그러면 광고 차단기는 정상 사이트에 속한 것처럼 보이는 수백만 개 하위 도메인을 막아야 하는 거의 불가능한 일을 하게 됨
      정상 사이트는 계속 하위 도메인을 바꿀 수 있고, 광고 차단기는 어떤 하위 도메인이 정상 콘텐츠이고 어떤 것이 광고인지 알 방법이 없음. 게다가 같은 도메인에서 콘텐츠가 제공되므로 일부 쿠키 정책을 우회해 사용자를 더 잘 추적할 수도 있음
      이번 업데이트는 해석된 IP를 기준으로 필터링하는 규칙을 설정할 수 있게 해줌
    • 맞음. 광고 및 분석 제공업체들이 서드파티 쿠키 보호를 우회하려고 이 방식을 쓰기 시작했음
  • 이건 Manifest V3가 왜 별로인지를 잘 보여주는 예임. 정의상 이런 일을 할 수 없고, 실행 중 코드 기반 휴리스틱도 불가능함
    광고주와의 확전 경쟁인데, Google은 양쪽에 무기를 파는 딜러임. 사용자가 이기는 데 필요한 것은 주지 않을 것임

    • 선언형 Manifest V3 API가 이런 기능을 제공하지 못할 이유는 없음. 커밋 내용을 제대로 읽은 게 맞다면, 실제 서버로 아무것도 보내기 전에 요청 흐름에 더 잘 통합해서 실제 사용될 IP 주소 기준으로 막는 식으로 더 잘 동작할 수도 있음
      물론 이 모든 건 브라우저 공급업체, 즉 Google이 이 API를 추가하고 싶어 하느냐에 달려 있음. “실행 중 코드”로 명령형 처리를 할 수 있으면 브라우저 제작자가 내장 지원을 넣기 전에 사용자 영역에서 혁신할 수 있음
    • 기술적으로 Manifest V3 자체는 브라우저가 확장에 제공하는 API와 별개임. Firefox에서는 Manifest V3가 차단형 웹 요청[1]과 함께 지원되는데, 이는 “Manifest V3” 이전의 필터링 API임
      따라서 특정 기능이 “정의상” 불가능하다는 말은 틀렸음
      [1] https://blog.mozilla.org/addons/2022/05/18/manifest-v3-in-fi...
    • Chrome을 버리고 Firefox를 받아들이면 됨
  • CNAME 클로킹 예를 들면, SaaS 제공업체 A가 회사 Q에 멋진 광고 추적 소프트웨어를 제공하려 한다고 하자
    예전 방식이라면 A는 https://q-company.example에 있는 회사 Q 웹사이트에 예컨대 https://A-ads-tracking.example의 스크립트를 삽입하라고 했을 것임
    그러면 uBlock Origin이 쓰는 차단 목록에는 “A-ads-tracking.example 도메인으로 가는 요청을 막아라” 같은 규칙이 생기고, 광고가 차단됨
    CNAME 클로킹은 SaaS 제공업체 A가 광고 추적 서비스를 A-ads-tracking.example 도메인이 아니라 예컨대 29.1.2.3 같은 특정 IP 주소에 두는 방식임. 그리고 중요한 부분은, SaaS A가 회사 Q에게 q-company.example의 하위 도메인을 만들고 그 CNAME 레코드가 23.1.2.3을 가리키게 하라고 요구한다는 점임. media.q-company.example 같은 그럴듯한 이름을 붙임
    Q 회사가 그 CNAME을 설정한 뒤 웹사이트에 media.q-company.example 스크립트 태그를 추가하면, SaaS A는 그 사이트의 모든 사용자를 추적할 수 있음. 이런 우회 계층 때문에 Q 회사 소유자와 공개 차단 목록 사이에 사실상 무한한 고양이와 쥐 게임이 생김
    이 문제를 피하려면 uBlock Origin 같은 확장을 구동하는 소프트웨어가 브라우저 요청의 대상 도메인뿐 아니라 그 도메인의 실제 IP 주소도 볼 수 있어야 함. 이 커밋은 그 동작을 가능하게 하거나, 적어도 그 코드가 더 잘 동작하도록 하는 것과 관련 있어 보임

    • 정확히는 조금 다름. 이름 그대로 CNAME을 쓰며, IP를 가리키는 A 레코드가 아니라 다른 레코드를 가리키는 레코드임
      예를 들어 media.q-company.exampleq-company.ads-tracking.example을 가리키는 CNAME이고, 그다음 q-company.ads-tracking.example이 IP를 주는 A 레코드를 갖는 식임
      브라우저가 중간 DNS 이름을 확장에 제공하는지는 모르겠음. 그래서 uBlock 같은 것은 IP 목록에 의존해야 할 수도 있지만, pihole 같은 DNS 기반 필터링은 ads-tracking.example에 대한 규칙으로 그냥 막을 수 있음
      어쨌든 브라우저 기반과 DNS 기반 악성 차단기를 둘 다 쓰는 게 좋음
    • 이래서 uBlock 고급 모드에서 모든 JavaScript를 차단하고, 사이트가 제대로 동작할 때까지 보이는 스크립트를 천천히 허용 목록에 넣는 게 좋은 이유가 됨
      느리고 실수하기 쉽지만 익숙해지면 수월하고, 이런 종류의 헛짓에는 완전히 면역이 됨
  • Chrome이 uBO를 막을 예정인가? 최신 상황을 늘 따라가지는 못함
    서드파티 쿠키는 이제 허용한다고 알고 있어서, 어쩌면 가능성이 있을지도 모르겠음

    • uBO 자체를 막는 게 아니라, 새 플러그인 API인 Manifest V3를 내면서 uBO가 동작하게 해주던 브라우저 기능을 제거하는 것임
      uBO가 로드하면 안 되는 것을 식별하고, 그다음 로드하지 않도록 만드는 데 필요한 핵심 API를 없애고 있음
      Google은 이를 “성능”이나 “보안” 때문이라고 주장함. 물론 실제로 크게 영향받는 유일한 “성능”이나 “보안”은 유해하거나 광고 관련 다운로드가 시작되기 전에 식별하고 가로채고 중단하는 능력임
    • 브라우저를 업데이트하지 않는 것도 위험함. Firefox로 전환해서 업데이트도 받고 uBO도 완전히 지원받는 편이 훨씬 낫다
    • 브라우저 독점에 대한 나쁜 여론이 한꺼번에 터지는 걸 피하려고 오랜 기간에 걸쳐 천천히 단계적으로 제거하고 있음. 하지만 그 일정은 이미 6월부터 시작됐음
      https://developer.chrome.com/docs/extensions/develop/migrate...
      https://www.bleepingcomputer.com/news/google/google-chrome-w...
    • 현재로서는 Manifest V2를 지원하는 Chromium 브라우저용으로 Chrome Web Store에 uBlock Origin이 아직 있음
      Manifest V3만 지원하는 Chromium 버전을 쓰면 숨겨짐
    • 솔직히 미국이 노골적인 독점 기업을 법정에 세우려는 행정부를 계속 유지하느냐에 달렸을 가능성이 큼
  • 일부 DNS 서버에는 서버가 해석한 CNAME처럼 동작하는 기능이 있지 않나? 관리자가 다른 DNS 이름을 가리키는 레코드를 넣지만, 클라이언트는 그냥 A 또는 AAAA 레코드만 보는 방식 말임

    • ALIAS 레코드를 말하는 것 같음
  • uBO에는 이 기능이 꽤 전부터 있었음. 1.34.0부터였고, 고급 설정에서는 1.25.0부터였음
    https://github.com/gorhill/uBlock/wiki/Dashboard:-Settings#u...
    대략 2021년쯤으로 기억함

  • Brave, Edge, Opera에서 uBO 상태는 어떤가?

    • 언급한 두 독점 브라우저에는 관심 없지만, Brave는 가능한 한 오래 Manifest V2를 부분적으로 지원하고 uBO 호환성을 유지할 예정임
      https://brave.com/blog/brave-shields-manifest-v3/
      다만 꼭 필요하진 않음. Brave에는 자체 내장 광고 차단기가 꽤 강력하게 들어 있고, 마지막으로 확인했을 때는 네이티브 코드로 컴파일되어 uBO보다 성능도 높았으며 같은 광고 목록도 완전히 지원했음