DNS ไม่สามารถแก้ไขได้เมื่อ kill switch ของ VPN บล็อกพอร์ต 53
Kill switch สามารถบล็อก DNS ได้โดยเจตนา เปรียบเทียบการแก้ไขภายในอุโมงค์เท่านั้นกับข้อยกเว้นสำหรับ resolver ภายในเครื่อง แล้วพิจารณาว่าชั้นใดล้มเหลวจริง
เมื่อ kill switch ทำให้อุโมงค์หลุด มันพาเส้นทาง DNS ไปด้วย และ resolver ที่เหลืออยู่ก็ไม่ใช่ตัวที่คุณคาดไว้บ่อยนัก การออกแบบสองแบบจัดการช่วงเวลานั้นต่างกันมาก: บล็อกทุกแพ็กเก็ต DNS ที่ไม่ได้อยู่ในอุโมงค์ หรือ ปล่อยให้ resolver ตัวหนึ่งยืนเป็นข้อยกเว้น ทั้งสองอย่างมีเหตุผล จากแท็บเบราว์เซอร์อาการดูแทบจะเหมือนกัน ดังนั้นงานแรกคือหาว่าคุณใช้งานการออกแบบใดจริง ๆ
ผมเก็บความต่างนี้ไว้ตรงหน้า เพราะการแก้ไขตรงกันข้ามในแต่ละกรณี การออกแบบหนึ่งต้องใช้ข้อยกเว้นที่กว้างกว่า อีกแบบต้องใช้ที่แคบกว่า การเดาทำให้คุณเสียความเป็นส่วนตัวหรือเสียเวลาครึ่งวัน
สองการออกแบบ DNS สำหรับความล้มเหลวเดียวกัน
การออกแบบ A มอง resolver เป็นอีกบริการหนึ่งหลังอุโมงค์ กฎไฟร์วอลล์อนุญาต UDP และ TCP 53 เฉพาะบนอินเทอร์เฟซของอุโมงค์ และที่อยู่ที่ส่งให้ไคลเอนต์คือ resolver ภายในอุโมงค์ เมื่ออุโมงค์หลุด การค้นหาหยุดลง และนั่นคือผลลัพธ์ที่ตั้งใจ ไม่ใช่ข้อบกพร่อง
การออกแบบ B เก็บ resolver ให้เข้าถึงได้บนเครือข่ายท้องถิ่น ปกติคือเราเตอร์ที่ 192.168.1.1 หรือ stub ของระบบปฏิบัติการที่ 127.0.0.53 ด้วยเหตุผลว่าการแก้ชื่อไม่ควรตายไปพร้อมอุโมงค์ บน LAN ในบ้านที่เราเตอร์แก้ชื่อให้ทั้งบ้านก็สะดวก แต่บน Wi-Fi ของโรงแรมหรือสนามบิน ข้อยกเว้นเดียวกันชี้ไปยังเซิร์ฟเวอร์ของคนอื่น และทุกชื่อที่คุณพิมพ์จะถูกเปิดเผย แม้ทราฟฟิกเว็บของคุณยังถูกบล็อกอยู่
เส้นแบ่งคือใครเป็นเจ้าของ resolver ถ้าคุณไว้ใจตัวท้องถิ่น ข้อยกเว้นก็เป็นช่องเล็ก ๆ ที่ซื่อตรง ถ้าไม่ไว้ใจ การออกแบบที่ใช้อุโมงค์เท่านั้นคือสิ่งเดียวที่ยืนได้ และราคาที่ต้องจ่ายคืออุโมงค์ที่หลุดจะพาชื่อทั้งหมดไปด้วย
ทำไมการค้นหาของไคลเอนต์ VPN เองยังใช้ได้
ไคลเอนต์ต้องแก้ชื่อโฮสต์ของเกตเวย์ก่อนที่อุโมงค์จะเกิดขึ้น ดังนั้นการบล็อกแบบเข้มงวดต้องไม่ครอบคลุมเส้นทางบูตของไคลเอนต์ ไคลเอนต์ส่วนใหญ่แคชที่อยู่ปลายทางหรือให้ข้อยกเว้นการบูตที่มีเอกสารกำกับสำหรับโฮสต์เดียวนั้น หากชุดกฎของคุณบล็อกการค้นหานั้น อุโมงค์จะไม่กลับมาอีกและบันทึกจะแสดงไคลเอนต์ที่ไม่สามารถไปถึงเซิร์ฟเวอร์ของตัวเอง นี่คือข้อบกพร่องของนโยบาย ไม่ใช่ของ DNS
DNS แบบแยกส่วนคือที่ที่สองที่สิ่งนี้ปรากฏ ไคลเอนต์ดันโซนภายในไปยัง resolver ส่วนตัวและปล่อยอย่างอื่นทั้งหมดให้ resolver ของระบบ หลังหลุด ชื่อสาธารณะอาจยังแก้ได้ในขณะที่ชื่อภายในหมดเวลา เพราะโซนส่วนตัวไม่มีเส้นทางเหลืออยู่ สำหรับผู้ใช้ นี่คือ "VPN ทำให้อินเทอร์เน็ตพัง"; สำหรับบันทึกของ resolver นี่คือคำถามที่ไม่เคยมาถึง
ภายใต้ systemd-resolved คุณเห็นการแยกได้โดยตรง resolvectl status แสดงรายการเซิร์ฟเวอร์ DNS ต่อลิงก์และโดเมนการกำหนดเส้นทาง และหลังจากอุโมงค์ลง โดเมนภายในยังชี้ไปยังเซิร์ฟเวอร์บนลิงก์ที่ไม่มีอยู่แล้ว stub ที่ 127.0.0.53 ยังรับคำถาม จากนั้นรอต้นน้ำที่จะไม่ตอบ นั่นคือเหตุผลที่ความล้มเหลวใช้เวลาหลายวินาทีแทนที่จะกลับมาทันที
DNS ที่เข้ารหัสไม่สามารถเลี่ยงตัวกรองแพ็กเก็ตได้
DNS over HTTPS และ DNS over TLS เดินทางบน 443 และ 853 ดังนั้นกฎที่บล็อกพอร์ต 53 ไม่ได้พูดอะไรเกี่ยวกับสองตัวนั้น การบล็อก "DNS" ตามพอร์ตเป็นนโยบายเกี่ยวกับพอร์ต ไม่ใช่เกี่ยวกับการแก้ชื่อ หาก kill switch ของคุณบล็อกทราฟฟิกทั้งหมดนอกอุโมงค์ DoH ก็ถูกครอบคลุมโดยบังเอิญ หากคุณเว้นข้อยกเว้นให้ captive portal หรือ resolver สาธารณะ ก็ไม่ถูกครอบคลุม
การควบคุมฝั่งไคลเอนต์เป็นคันโยกที่ถูกกว่า Firefox ทิ้ง resolver DoH ของตนเมื่อชื่อคานารีuse-application-dns.net แก้ไม่ได้ ซึ่งเป็นเหตุผลที่เครือข่ายที่มีการจัดการเผยแพร่โดเมนนั้นเป็น NXDOMAIN; นโยบายองค์กรยังปักหมุดให้ปิดได้อีกด้วย Android Private DNS และ DNS แบบปลอดภัยของ Chrome มีสวิตช์และค่าเริ่มต้นของตัวเอง การปิดสิ่งเหล่านั้นเชื่อถือได้มากกว่าการไล่ล่าที่อยู่ของ resolver เพราะรายการที่อยู่เปลี่ยนและชุดกฎของคุณไม่เปลี่ยน
มีอีกรูปแบบหนึ่งของเรื่องนี้ที่ไม่เกี่ยวกับการรั่วไหลเลย แอปที่มี resolver ปักหมุดไว้ยังต้องมีเส้นทางเครือข่ายเพื่อไปถึงมัน การเข้ารหัสเปลี่ยนว่าใครอ่านคำถามได้ ไม่ได้เปลี่ยนว่าแพ็กเก็ตออกจากเครื่องได้หรือไม่ ดังนั้นการบล็อกทั้งอุปกรณ์จึงเอาชนะการตั้งค่าโดยไม่ต้องแตะมัน
จับคู่อาการกับชั้น
รายงานส่วนใหญ่มาถึงเป็นประโยคเดียว และประโยคนั้นมักระบุชั้นอยู่แล้ว ตารางด้านล่างคือสิ่งที่ผมไล่ดูก่อนแตะกฎ จุดหมายคือตัดสินว่าคำถามถูกบล็อก ถูกส่งผิดทาง หรือไม่เคยถูกส่งเลย
| Symptom | Likely layer | First check |
|---|---|---|
| Every name fails at once, instantly | Resolver answering with a refusal | Query the resolver by address, not by name |
| Lookups hang for seconds, then time out | Packets dropped with no response | Watch port 53 on the physical link |
| Public names resolve, internal ones do not | Split-DNS routing domain | Per-link DNS servers on the tunnel |
| Names resolve, the page still fails | Not DNS: routing or MTU | Connect to the IP directly |
| Only one application fails | Pinned resolver or cached answer | Check that app's DNS setting |
สองแถวแรกคือสิ่งที่ผู้คนวินิจฉัยผิด การหลุดแบบเงียบและการปฏิเสธดูเหมือน "DNS พัง" ทั้งคู่ในเบราว์เซอร์ แต่มีเพียงอย่างเดียวที่หมายความว่า kill switch ของคุณกำลังทำงาน การปฏิเสธหมายความว่ามีบางอย่างตอบมา ดังนั้นการบล็อกไม่ได้อยู่ที่ที่คุณคิด
คืนนโยบายของ resolver แล้วพิสูจน์
แก้ที่การออกแบบ ไม่ใช่อาการ สำหรับการแก้ไขภายในอุโมงค์เท่านั้น อนุญาต 53 บนอินเทอร์เฟซของอุโมงค์ ดัน resolver ภายในไปพร้อมการตั้งค่าอุโมงค์ และปล่อยลิงก์กายภาพไว้โดยไม่มีการอนุญาต DNS ใด ๆ ใน wg-quick บรรทัด DNS = คือบรรทัดที่เขียน resolver ลงในการตั้งค่าอินเทอร์เฟซ ดังนั้นอุโมงค์ที่ละเว้นบรรทัดนี้จะทิ้ง resolver เก่าไว้ที่เดิมและทุกคำถามไปผิดทาง คู่มือ wg-quick อธิบายพฤติกรรมนั้นแยกตามแพลตฟอร์ม
จากนั้นตรวจสอบตามลำดับนี้ บน Linux resolvectl status แสดงลิงก์ที่ใช้งานอยู่dig +short example.com ทดสอบชื่อสาธารณะ dig @10.8.0.1 internal.example.com ทดสอบชื่อภายใน และ sudo tcpdump -ni any port 53 แสดงว่าอินเทอร์เฟซใดที่แพ็กเก็ตใช้ขณะคุณรันทั้งสองคำสั่ง บน Windows Get-DnsClientServerAddress -AddressFamily IPv4 และ Resolve-DnsName example.com ให้ข้อเท็จจริงสองอย่างเดียวกัน คือใครถูกตั้งค่า และใครตอบ
จบด้วยการทดสอบเชิงลบ ตัดการเชื่อมต่ออุโมงค์ ยืนยันว่าชื่อสาธารณะใหม่ล้มเหลว ยืนยันว่าชื่อภายในล้มเหลว และ ยืนยันว่าไม่มีแพ็กเก็ตพอร์ต 53 ใดออกจากอะแดปเตอร์กายภาพ การบล็อกที่ยืนได้เฉพาะคำตอบที่แคชไว้ก็ไม่ยืนเลย
รายการตรวจสอบก่อนปิดตั๋ว:
- resolver ที่ใช้ระหว่างเหตุขัดข้องคือนโยบายที่ตั้งใจไว้
- การค้นหาปลายทางของไคลเอนต์เองยังได้รับอนุญาต ผ่านแคชหรือข้อยกเว้น
- DoH และ DoT ถูกบล็อกครอบคลุมหรือถูกปิดตามนโยบาย
- เมื่ออุโมงค์หายไป โซนส่วนตัวล้มเหลวแบบปิด ไม่ใช่แบบเปิด