שאילתות ותשובות של 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.
- ב-POST, כתובת ה-URL היא רק
API בפורמט JSON –
https://dns.google/resolve{?name}{&type,cd,do,…}
- פרטים נוספים של פרמטרים של GET מתוארים
הדף API בפורמט JSON.
נדרש רק הפרמטר
name
.
- פרטים נוספים של פרמטרים של GET מתוארים
הדף API בפורמט JSON.
נדרש רק הפרמטר
לקוחות
יש כמה אפליקציות לקוח שמשתמשות ב-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:
- שליחת שם המארח dns.google כ-SNI לחיבורים ציבוריים של Google שירותי DNS DoT או DoH.
- אם אין שם מארח זמין (לדוגמה, באפליקציה שמפעילה מצופים אקראיים), עדיף לשלוח את כתובת ה-IP ב-SNI במקום לשלוח מאשר להשאיר את השדה ריק.
- כתובות IPv6 צריכות להופיע בפורמט סוגריים מרובע
[2001:db8:1234::5678]
ב- את הכותרתHost
, אבל בלי סוגריים ב-SNI.
חיתוך של תגובת DNS
למרות שה-DNS הציבורי של Google בדרך כלל לא מקצר תשובות ל-DoT ול-DoH. יש שתי נסיבות שבהן הוא כן:
אם לא ניתן לקבל תשובות מלאות ולא קטועות מה-DNS הציבורי של Google שרתי שמות מהימנים, הוא מגדיר את הדגל של השקיפות וההסכמה בתגובה.
במקרים שבהם תגובת ה-DNS (בתבנית של הודעת DNS בינארית) תחרוג מהמגבלה של 64KiB להודעות DNS של TCP, ה-DNS הציבורי של Google עשוי להגדיר את סימון TC (חיתוך) אם תקני RFC מחייבים זאת.
עם זאת, במקרים כאלה אין צורך שהלקוחות ינסו שוב באמצעות TCP פשוט או כל אמצעי אחר, מכיוון שהתוצאה תהיה זהה.