העברות מאובטחות ל-DNS

שאילתות ותשובות של DNS מסורתי נשלחות באמצעות UDP או TCP ללא הצפנה, והם כפופים למעקב, זיוף וסינון אינטרנט מבוסס-DNS. תגובות ללקוחות ממקודדים ציבוריים כמו Google Public DNS פגיעות לכך, מכיוון שהודעות עלולות לעבור דרך רשתות רבות, בין מקודדים רקורסיביים לשרתי שמות מהימנים הגנות נוספות.

כדי לטפל בבעיות האלה, בשנת 2016 השקנו את DNS-over-HTTPS (שנקרא עכשיו DoH) שמציעים רזולוציית DNS מוצפנת עם אימות DNSSEC ב-HTTPS וב-QUIC. ובשנת 2019, הוספנו תמיכה בתקן DNS over TLS (DoT) שמשמש את באמצעות התכונה DNS פרטי ב-Android.

DoH ו-DoT משפרות את הפרטיות והאבטחה בין הלקוחות למקודדים, השלמת אימות ה-DNSSEC של Google Public DNS כדי לספק ניתוח מקצה לקצה DNS מאומת לדומיינים עם חתימת DNSSEC. עם ה-DNS הציבורי של Google, מחויב לספק רזולוציית DNS מהירה, פרטית ומאובטחת גם עבור DoH וגם לקוחות DoT.

גרסאות TLS וסוויטות קריפטו נתמכות

ה-DNS הציבורי של Google תומך ב-TLS 1.2 וב-TLS 1.3 גם ל-DoH וגם ל-DoT; לא מוקדם יותר יש תמיכה בגרסאות TLS או SSL. רק סטים של אלגוריתמים להצפנה (cipher suite) עם אבטחה קדימה ובהצפנה מאומתת עם נתונים נוספים (AEAD) תהיה תמיכה. ב-Qualys SSL Labs מוצגת הקבוצה הנוכחית של סטים נתמכים של אלגוריתמים להצפנה (cipher suite).

נקודות קצה (endpoints)

ה-DNS הציבורי של Google משתמש בנקודות הקצה הבאות ל-DoH ול-DoT:

DoT (יציאה 853) dns.google

תבניות URI של DoH (יציאה 443)

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

    • ב-POST, כתובת ה-URL היא רק https://dns.google/dns-query וגוף בקשת ה-HTTP היא מטען ייעודי (payload) של DNS בינארי ב-UDP עם סוג התוכן application/dns-message.
    • עבור GET, הערך הוא https://dns.google/dns-query?dns=BASE64URL_OF_QUERY.
  • API בפורמט JSON – https://dns.google/resolve{?name}{&type,cd,do,…}

    • פרטים נוספים של פרמטרים של GET מתוארים הדף API בפורמט JSON. נדרש רק הפרמטר name.

לקוחות

יש כמה אפליקציות לקוח שמשתמשות ב-DoT או ב-DoH

  • התכונה 'גלישה פרטית' ב-Android 9 (Pie) – נקודה
  • Intra (אפליקציה ל-Android) – DoH

באתר dnsprivacy.org יש רשימה של כמה לקוחות נוספים ל-DoT ול-DoH, אבל בדרך כלל הן מצריכות הגדרה טכנית בינונית.

דוגמאות לשורת הפקודה

הדוגמאות הבאות של שורת הפקודה לא מיועדות לשימוש אצל לקוח בפועל. והם רק איורים שמשתמשים בכלי אבחון נפוצים.

DoT

לפקודות הבאות נדרשים Knot DNS kdig 2.3.0 ואילך; עם 2.7.4 או מאוחר יותר, מבטלים את התגובה ל-+tls‑sni כדי לשלוח SNI כנדרש על ידי TLS 1.3.

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

המחרוזת המקודדת של Base64Url בפקודה הזו היא הודעת ה-DNS שנשלחת על ידי dig +noedns example.test A כשהשדה של מזהה ה-DNS מוגדר לאפס, בהתאם להמלצה לפי 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

המחרוזת המקודדת של Base64Url בפקודה הזו היא הודעת ה-DNS שנשלחת על ידי dig +noedns example.com A מחליפים בשדה של מזהה ה-DNS. במקרה הזה כדאי מועברת במפורש בכתובת ה-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

הפעולה הזו משתמשת ב-API בפורמט JSON ל-DoH.

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":[]}

TLS 1.3 ו-SNI לכתובות URL של כתובות IP

כדי להשתמש ב-TLS 1.3 נדרשים לקוחות לספק זיהוי של שם שרת (SNI).

התוסף SNI מציין שפרטי ה-SNI הם דומיין DNS (ולא כתובת IP):

שם מארח מכיל את שם המארח המלא של השרת, ה-DNS כפי שהלקוח מבין. שם המארח מיוצג כמחרוזת של בייטים באמצעות קידוד ASCII ללא נקודה בסוף. כך אפשר לתמוך שמות דומיין בינלאומיים באמצעות שימוש בתוויות A המוגדרים RFC5890. שמות מארחים של DNS הם לא תלויי-רישיות. האלגוריתם להשוואה שמות המארחים מתוארים ב-RFC5890, סעיף 2.3.2.4.

לא ניתן להשתמש בכתובות IPv4 ו-IPv6 מילוליות ב-'HostName'.

לפעמים קשה לעמוד בדרישות האלה באפליקציות ל-DoH או ל-DoT שרוצים לנצל את שיפורי האבטחה ב-TLS 1.3. ה-DNS הציבורי של Google כרגע מקבל חיבורי TLS 1.3 שאינם מספקים SNI, אבל ייתכן שנצטרך לשנות. מסיבות תפעוליות או אבטחה בעתיד.

אלה ההמלצות שלנו לאפליקציות ל-DoT או ל-DoH בנוגע ל-SNI:

  1. שליחת שם המארח dns.google כ-SNI לחיבורים ציבוריים של Google שירותי DNS DoT או DoH.
  2. אם אין שם מארח זמין (לדוגמה, באפליקציה שמפעילה מצופים אקראיים), עדיף לשלוח את כתובת ה-IP ב-SNI במקום לשלוח מאשר להשאיר את השדה ריק.
  3. כתובות IPv6 צריכות להופיע בפורמט סוגריים מרובע [2001:db8:1234::5678] ב- את הכותרת Host, אבל בלי סוגריים ב-SNI.

חיתוך של תגובת DNS

למרות שה-DNS הציבורי של Google בדרך כלל לא מקצר תשובות ל-DoT ול-DoH. יש שתי נסיבות שבהן הוא כן:

  1. אם לא ניתן לקבל תשובות מלאות ולא קטועות מה-DNS הציבורי של Google שרתי שמות מהימנים, הוא מגדיר את הדגל של השקיפות וההסכמה בתגובה.

  2. במקרים שבהם תגובת ה-DNS (בתבנית של הודעת DNS בינארית) תחרוג מהמגבלה של 64KiB להודעות DNS של TCP, ה-DNS הציבורי של Google עשוי להגדיר את סימון TC (חיתוך) אם תקני RFC מחייבים זאת.

עם זאת, במקרים כאלה אין צורך שהלקוחות ינסו שוב באמצעות TCP פשוט או כל אמצעי אחר, מכיוון שהתוצאה תהיה זהה.