DNS용 보안 전송

기존 DNS 쿼리 및 응답은 암호화 없이 UDP 또는 TCP를 통해 전송되며 감시, 스푸핑 및 DNS 기반 인터넷 필터링의 대상이 됩니다. Google Public DNS와 같은 공개 리졸버의 클라이언트에 대한 응답은 메시지가 많은 네트워크를 통과할 수 있는 반면, 재귀 리졸버와 권한 있는 네임 서버 사이에는 종종 추가 보호 조치가 제공됩니다.

Google은 이 문제를 해결하기 위해 2016년에 DNS over HTTPS (현재 DoH라고 함)를 출시하였습니다. HTTPS 및 QUIC를 통한 암호화된 DNSSEC 검사 DNS 변환 제공 또한 2019년에는 DNS over TLS (DoT) 표준에 대한 지원을 추가하여 Android 비공개 DNS 기능입니다.

DoH와 DoT는 클라이언트와 리졸버 간의 개인 정보 보호 및 보안을 강화합니다. DNSSEC의 Google Public DNS 검증을 보완하여 DNSSEC 서명 도메인의 인증된 DNS입니다. Google Public DNS를 통해 DoH와 기업 모두에 빠르고 안전한 비공개 DNS 변환을 제공하기 위해 DoT 클라이언트

지원되는 TLS 버전 및 암호화 묶음

Google Public DNS는 DoH와 DoT 모두에 TLS 1.2 및 TLS 1.3을 지원합니다. 이전 지원되는 것은 아닙니다 정방향 보안을 사용하는 암호화 스위트만 추가 데이터를 사용한 인증 암호화 (AEAD)가 지원됩니다. Qualys SSL Labs에 현재 지원되는 암호화 제품군이 표시됩니다.

엔드포인트

Google Public DNS는 DoH 및 DoT에 다음 엔드포인트를 사용합니다.

DoT (포트 853) dns.google

DoH (포트 443) URI 템플릿

  • RFC 8484: https://dns.google/dns-query{?dns}

    • POST의 경우 URL은 https://dns.google/dns-query이고 본문입니다. HTTP 요청은 콘텐츠 유형이 있는 바이너리 UDP DNS 페이로드입니다. application/dns-message.
    • GET의 경우 https://dns.google/dns-query?dns=BASE64URL_OF_QUERY입니다.
  • JSON API: https://dns.google/resolve{?name}{&type,cd,do,…}

    • GET 매개변수에 대해 자세히 알아보려면 JSON API 페이지 name 매개변수만 필요합니다.

클라이언트

DoT 또는 DoH를 사용하는 여러 클라이언트 애플리케이션이 있습니다.

  • Android 9 (Pie) '시크릿 브라우징' 기능 – DoT
  • Intra (Android 앱) – DoH

dnsprivacy.org 웹사이트에는 DoT 및 DoH에 대한 다른 여러 클라이언트가 나열되어 있지만, 일반적으로 적당한 기술적 구성이 필요합니다.

명령줄 예시

다음 명령줄 예시는 실제 클라이언트에서 사용하기 위한 것이 아닙니다. 일반적으로 사용 가능한 진단 도구를 사용한 그림일 뿐입니다.

DoT

다음 명령어를 사용하려면 Knot DNS kdig 2.3.0 이상이 필요합니다. 2.7.4 또는 나중에 +tls‑sni의 주석 처리를 삭제하여 TLS 1.3에서 요구하는 SNI를 전송합니다.

kdig -d +noall +answer @dns.google example.com \
  +tls-ca +tls-hostname=dns.google # +tls-sni=dns.google
;; DEBUG: Querying for owner(example.com.), class(1), type(1), server(dns.google), port(853), protocol(TCP)
;; DEBUG: TLS, imported 312 system certificates
;; DEBUG: TLS, received certificate hierarchy:
;; DEBUG:  #1, C=US,ST=California,L=Mountain View,O=Google LLC,CN=dns.google
;; DEBUG:      SHA-256 PIN: lQXSLnWzUdueQ4+YCezIcLa8L6RPr8Wgeqtxmw1ti+M=
;; DEBUG:  #2, C=US,O=Google Trust Services,CN=Google Internet Authority G3
;; DEBUG:      SHA-256 PIN: f8NnEFZxQ4ExFOhSN7EiFWtiudZQVD2oY60uauV/n78=
;; DEBUG: TLS, skipping certificate PIN check
;; DEBUG: TLS, The certificate is trusted.

;; ANSWER SECTION:
example.com.            2046    IN      A       93.184.216.34
kdig -d +noall +answer @dns.google example.com \
  +tls-pin=f8NnEFZxQ4ExFOhSN7EiFWtiudZQVD2oY60uauV/n78= \
  # +tls-sni=dns.google
;; DEBUG: Querying for owner(example.com.), class(1), type(1), server(dns.google), port(853), protocol(TCP)
;; DEBUG: TLS, received certificate hierarchy:
;; DEBUG:  #1, C=US,ST=California,L=Mountain View,O=Google LLC,CN=dns.google
;; DEBUG:      SHA-256 PIN: lQXSLnWzUdueQ4+YCezIcLa8L6RPr8Wgeqtxmw1ti+M=
;; DEBUG:  #2, C=US,O=Google Trust Services,CN=Google Internet Authority G3
;; DEBUG:      SHA-256 PIN: f8NnEFZxQ4ExFOhSN7EiFWtiudZQVD2oY60uauV/n78=, MATCH
;; DEBUG: TLS, skipping certificate verification

;; ANSWER SECTION:
example.com.            5494    IN      A       93.184.216.34

DoH

RFC 8484 POST

이 명령어의 Base64Url로 인코딩된 문자열은 권장되는 대로 DNS ID 입력란이 0으로 설정된 dig +noedns example.test A (RFC 8484 섹션 4.1 참조) 셸 명령어는 해당 DNS 쿼리를 바이너리 데이터 본문 콘텐츠(Content-Type application/dns-message 사용)

echo AAABAAABAAAAAAAAB2V4YW1wbGUEdGVzdAAAAQAB | base64 --decode |
 curl -is --data-binary @- -H 'content-type: application/dns-message' \
   https://dns.google/dns-query
HTTP/2 200
strict-transport-security: max-age=31536000; includeSubDomains; preload
access-control-allow-origin: *
date: Wed, 29 May 2019 19:37:16 GMT
expires: Wed, 29 May 2019 19:37:16 GMT
cache-control: private, max-age=19174
content-type: application/dns-message
server: HTTP server (unknown)
content-length: 45
x-xss-protection: 0
x-frame-options: SAMEORIGIN
alt-svc: quic=":443"; ma=2592000; v="46,44,43,39"

RFC 8484 GET

이 명령어의 Base64Url로 인코딩된 문자열은 DNS ID 필드가 0으로 설정된 dig +noedns example.com A 이 경우에는 URL에 명시적으로 전달됩니다.

curl -i https://dns.google/dns-query?dns=AAABAAABAAAAAAAAB2V4YW1wbGUDY29tAAABAAE
HTTP/2 200
strict-transport-security: max-age=31536000; includeSubDomains; preload
access-control-allow-origin: *
date: Wed, 29 May 2019 19:37:16 GMT
expires: Wed, 29 May 2019 19:37:16 GMT
cache-control: private, max-age=19174
content-type: application/dns-message
server: HTTP server (unknown)
content-length: 45
x-xss-protection: 0
x-frame-options: SAMEORIGIN
alt-svc: quic=":443"; ma=2592000; v="46,44,43,39"

JSON 가져오기

DoH용 JSON API가 사용됩니다.

curl -i 'https://dns.google/resolve?name=example.com&type=a&do=1'
HTTP/2 200
strict-transport-security: max-age=31536000; includeSubDomains; preload
access-control-allow-origin: *
date: Thu, 30 May 2019 02:46:46 GMT
expires: Thu, 30 May 2019 02:46:46 GMT
cache-control: private, max-age=10443
content-type: application/x-javascript; charset=UTF-8
server: HTTP server (unknown)
x-xss-protection: 0
x-frame-options: SAMEORIGIN
alt-svc: quic=":443"; ma=2592000; v="46,44,43,39"
accept-ranges: none
vary: Accept-Encoding

{"Status": 0,"TC": false,"RD": true,"RA": true,"AD": true,"CD": false,"Question":[ {"name": "example.com.","type": 1}],"Answer":[ {"name": "example.com.","type": 1,"TTL": 10443,"data": "93.184.216.34"},{"name": "example.com.","type": 46,"TTL": 10443,"data": "a 8 2 86400 1559899303 1558087103 23689 example.com. IfelQcO5NqQIX7ZNKI245KLfdRCKBaj2gKhZkJawtJbo/do+A0aUvoDM5A7EZKcF/j8SdtyfYWj/8g91B2/m/WOo7KyZxIC918R1/jvBRYQGreDL+yutb1ReGc6eUHX+NKJIYqzfal+PY7tGotS1Srn9WhBspXq8/0rNsEnsSoA="}],"Additional":[]}

IP 주소 URL용 TLS 1.3 및 SNI

TLS 1.3의 경우 클라이언트가 서버 이름 식별 (SNI)을 제공합니다

SNI 확장 프로그램은 SNI 정보가 IP 주소가 아닌 DNS 도메인임을 지정합니다.

'호스트 이름' 에는 서버의 정규화된 DNS 호스트 이름이 포함됩니다. 이해하는 데 도움이 될 수 있습니다 호스트 이름은 바이트 문자열로 표현됨 뒤에 점 없이 ASCII 인코딩을 사용합니다. 이를 통해 국제화된 도메인 이름을 RFC5890 DNS 호스트 이름은 대소문자를 구분하지 않습니다. 비교할 알고리즘입니다. 호스트 이름은 RFC5890, 섹션 2.3.2.4에 설명되어 있습니다.

'HostName'에 리터럴 IPv4 및 IPv6 주소가 허용되지 않습니다.

DoH 또는 DoT 애플리케이션에서는 이러한 요구사항을 TLS 1.3의 보안 향상 기능을 활용하세요. 현재 Google Public DNS SNI를 제공하지 않는 TLS 1.3 연결을 허용하지만 향후 운영 또는 보안상의 이유로 인해 발생할 수 있습니다.

SNI와 관련된 DoT 또는 DoH 애플리케이션에 관한 권장사항은 다음과 같습니다.

  1. Google Public 연결에 사용할 dns.google 호스트 이름을 SNI로 전송합니다. DNS DoT 또는 DoH 서비스입니다.
  2. 호스트 이름을 사용할 수 없는 경우 (예: 편의적 DoT), SNI의 IP 주소를 전송하는 것이 더 낫습니다. 비워 두는 것이 좋습니다
  3. IPv6 주소는 [2001:db8:1234::5678], 대괄호로 묶인 Host 헤더와 같지만 SNI에는 대괄호가 없습니다.

DNS 응답 자르기

Google Public DNS는 일반적으로 DoT 및 DoH에 대한 응답을 자르지 않음 쿼리가 실행되는 경우 두 가지 경우가 있습니다.

  1. Google Public DNS가 응답에서 TC 플래그를 설정합니다.

  2. DNS 응답 (바이너리 DNS 메시지 형식)이 64KiB 한도를 초과하는 경우 Google Public DNS는 RFC 표준에서 요구하는 경우 TC (잘림) 플래그입니다.

그러나 이러한 경우에는 클라이언트가 일반 TCP를 사용하여 다시 시도할 필요가 없습니다. 결과가 같을 것이기 때문입니다.