อ่าน DNS ของ Android ให้ถูก: ตามเครือข่าย ไม่ใช่ใน resolv.conf
แอป Android ของคุณแก้ชื่อผ่าน resolver ตามแต่ละเครือข่าย ไม่ใช่ผ่าน resolv.conf ที่คุณเพิ่งอ่าน ตรวจ LinkProperties การผูก socket และ Private DNS ก่อน
คุณได้ shell บนอุปกรณ์ อ่าน /etc/resolv.conf หรือขุดค่า net.dns1 เก่าขึ้นมา แล้วได้ที่อยู่หนึ่งรายการ แอปที่อยู่ตรงหน้าคุณกลับแก้ชื่อผ่านอีกอย่างหนึ่งโดยสิ้นเชิง ใน Android รุ่นปัจจุบัน resolver ทำงานตามเครือข่าย ระบบเก็บนโยบายไว้สำหรับแต่ละ Network และใช้กับ socket ที่ส่งคำขอ ไฟล์และพร็อพเพอร์ตี้เก่าเป็นเพียงเศษที่เหลือ และไม่มีอันใดอธิบายเส้นทางที่คำถามของคุณเดินจริง
ช่องว่างนี้ปรากฏตอนติดตั้ง split-tunnel และ Private DNS ซึ่งแอปสองตัวบนโทรศัพท์เครื่องเดียวกันเห็นคำตอบต่างกันได้อย่างชอบธรรม คู่มือนี้เริ่มจากการแก้ชื่อที่ผิดหรือหายไป แล้วย้อนกลับไปยังคอนฟิกูเรชันที่เป็นเจ้าของมัน
resolver เป็นของเครือข่าย ไม่ใช่อุปกรณ์
การแก้ชื่อบน Android 9 และใหม่กว่าเดินผ่าน resolver ของระบบซึ่งอิงกับ Network ที่ socket ผูกอยู่ แต่ละเครือข่ายมี LinkProperties ของตัวเอง และพร็อพเพอร์ตี้เหล่านั้นเก็บรายการเซิร์ฟเวอร์ DNS โดเมนค้นหา และสถานะ Private DNS สำหรับเครือข่ายนั้นเท่านั้น ไม่มีสิ่งใดในแบบจำลองนั้นตรงกับรายการเดียวทั้งอุปกรณ์ที่คุณอ่านได้จากไฟล์
VPN ทำให้การแยกชัดเจน เมื่ออุโมงค์ขึ้น แอป VPN จะให้เซิร์ฟเวอร์ DNS ที่ลงทะเบียนบนเครือข่ายของ VPN เอง แอปที่เส้นทางผ่าน VPN จึงแก้ชื่อกับเซิร์ฟเวอร์เหล่านั้น ขณะที่แอปที่ถูกยกเว้นยังใช้เครือข่ายข้างใต้ อุปกรณ์เดียว สองเส้นทางคำตอบ ไม่มีความขัดแย้ง
อ่านสแนปช็อตจากภายในแอปที่ได้รับผลกระทบ
ถามแอปเอง เมธอดที่มี Context และสิทธิ์ android.permission.ACCESS_NETWORK_STATE ตามปกติสามารถอ่านสแนปช็อตได้โดยไม่แตะพร็อพเพอร์ตี้ของระบบ
val cm = getSystemService(ConnectivityManager::class.java) ?: return
val network = cm.activeNetwork
val links = network?.let { cm.getLinkProperties(it) }
val dnsServers = links?.dnsServers
val privateDnsActive = links?.isPrivateDnsActive
val privateDnsName = links?.privateDnsServerNameactiveNetwork คือเครือข่ายเริ่มต้นของโปรเซสคุณ ไม่ใช่เครือข่ายเดียวบนอุปกรณ์ และอาจเป็น null เมื่อผู้เรียกไม่มีค่าเริ่มต้นที่ใช้ได้ VPN เริ่มต้นที่ถูกบล็อกคือสาเหตุปกติ isPrivateDnsActive บอกว่าคำถามบนเครือข่ายนั้นวิ่งผ่าน TLS ไปยัง resolver ที่มีชื่อหรือไม่ ซึ่งเปลี่ยนสิ่งที่การตรวจ UDP 53 อย่างง่ายจะแสดง LinkProperties มีเอกสาร API กำกับ และทุกค่าในนั้นเป็นสแนปช็อตของคอนฟิกูเรชัน ไม่ใช่หลักฐานว่าคำถามหนึ่งไปถึงเซิร์ฟเวอร์หนึ่งจริง
เมื่อเครือข่ายเริ่มต้นไม่ใช่เครือข่ายที่ทำงาน
สแนปช็อตตอบเฉพาะค่าเริ่มต้น แอปสามารถผูกโปรเซสหรือ socket เดียวกับเครือข่ายอื่นได้ แล้วการแก้ชื่อจะตามการเลือกนั้น ขณะที่การวินิจฉัยของคุณยังรายงานค่าเริ่มต้น เบราว์เซอร์ที่นำ resolver DNS-over-HTTPS ของตัวเองมาไม่เคยถามรายการของระบบเลย คำตอบของมันจึงไม่บอกอะไรเกี่ยวกับส่วนที่เหลือของอุปกรณ์ แอปโปรไฟล์งานทำงานภายใต้ผู้ใช้อีกคนที่มีนโยบายของตัวเอง ตรวจการผูกก่อนโทษเซิร์ฟเวอร์
การรวม VPN คืออีกครึ่งหนึ่ง dhcp-option DNS ในโปรไฟล์ OpenVPN และการลงทะเบียนที่อยู่นั้นบนเครือข่าย VPN ของ Android เป็นสองขั้นตอนแยกกัน และเส้นทางที่ขาดไปยังเซิร์ฟเวอร์ล้มเหลวเงียบเท่ากับที่อยู่ผิด จากเครื่องพัฒนา adb shell dumpsys connectivity พิมพ์พร็อพเพอร์ตี้ลิงก์เดียวกันตามเครือข่ายเมื่อ build อนุญาต ซึ่งยืนยันรายการโดยไม่ต้องเขียนโค้ด
เทียบคอนฟิกูเรชันกับการแก้ชื่อหนึ่งครั้งที่คุณได้รับอนุญาตให้ทำ
เลือกชื่อที่ต้องแก้ได้ในเนมสเปซส่วนตัวและชื่อสาธารณะหนึ่งชื่อ แล้วบันทึกผลทั้งสองข้างสแนปช็อต เครือข่าย เซิร์ฟเวอร์ที่ตั้งไว้ สถานะ Private DNS และข้อความข้อผิดพลาดที่แน่นอน การถามตรงไปยังเซิร์ฟเวอร์ที่มีชื่อพิสูจน์ว่าเซิร์ฟเวอร์นั้นตอบคุณ ไม่ได้พิสูจน์ว่าการแก้ชื่อปกติของแอปเลือกมัน คำตอบจากแคชไม่ใช่การทดสอบใหม่ จึงล้างแคชหรือใช้ชื่อที่วันนี้ยังไม่มีใครถาม
ถ้า resolver ให้บริการเฉพาะไคลเอนต์จากเครือข่ายเข้าถึงหนึ่ง สิ่งที่มันเห็นหลังออกจาก VPN อาจชี้ขาดผลลัพธ์ และนี่เป็นคำถามเชิงนโยบายสำหรับผู้ดูแลมัน ไม่ใช่หลักฐานว่าผู้ให้บริการบล็อก UDP 53 ที่ Private DNS ทำงานอยู่ ชื่อโฮสต์ที่ไม่สมบูรณ์อาจถูกปฏิเสธตามการออกแบบ ขณะที่เซิร์ฟเวอร์เดียวกันตอบชื่อสาธารณะตามปกติ การอ่านพร็อพเพอร์ตี้บอกว่าโหมดใดบังคับใช้ คุณจึงเลิกเดาตัวกรองแพ็กเก็ต
แก้ชั้นที่เป็นเจ้าของความไม่ตรงกัน
ทำงานขึ้นไปแทนการแก้สถานะส่วนกลาง ถ้าแอปผูกกับเครือข่ายผิด ให้แก้การผูก ถ้าโปรไฟล์ให้ตัวเลือก DNS ผิด ให้แก้โปรไฟล์ ถ้า Private DNS เข้มงวดบนเครือข่ายที่ resolver ของมันให้บริการโซนส่วนตัวของคุณไม่ได้ นั่นเป็นการตัดสินใจของผู้ดูแลอุปกรณ์ ไม่ใช่เหตุผลปิดฟีเจอร์ทุกที่
การยัด resolver สาธารณะเข้า DHCP hook หรือพร็อพเพอร์ตี้ของระบบคือการซ่อมที่ก่อเหตุซ้ำแล้วซ้ำเล่า ชื่อส่วนตัวหยุดแก้ ชื่อเปลี่ยนอยู่ได้นานกว่าเซสชัน VPN และคนถัดไปบนอุปกรณ์เจอที่อยู่ค้างเก่าที่ไม่มีเจ้าของ เก็บการเปลี่ยนแปลงไว้ใน VPN แอป หรือชั้นการจัดการที่เป็นเจ้าของความไม่ตรงกัน แล้วอ่านสแนปช็อตอีกครั้งเพื่อยืนยันว่ารายการเซิร์ฟเวอร์เปลี่ยนจริง
สุดท้ายสิ่งที่คุณต้องการคือคำขอของแอปหนึ่งครั้งที่ผูกกับเครือข่ายหนึ่ง รายการ resolver และสถานะ Private DNS เมื่อคุณแสดงห่วงโซ่นั้นได้ ที่อยู่คุ้นเคยในไฟล์ก็เลิกเป็นหลักฐานของสิ่งใด