การเลือกเส้นทาง VPN บน Android: กฎนโยบายก่อนตาราง main
Android เลือกตารางเส้นทางด้วยกฎ uid และเครื่องหมายก่อนการค้นหาปลายทางใด ๆ ดังนั้นเส้นทางที่เพิ่มใน main อาจไม่ถูกตรวจสอบเลย
เส้นทางที่เพิ่มเข้าไปในตาราง main บน Android ดูถูกต้องในทุกรายการและยังคงไม่พาทราฟฟิกไปจริง เหตุผลคือตาราง main เป็นเพียงหนึ่งในหลายตัวเลือก และไม่ได้ถูกถามก่อน บริการเครือข่ายของ Android สร้างกฎนโยบายที่เลือกตารางเส้นทางโดยใช้ข้อมูลที่ที่อยู่ปลายทางไม่มี — uid ของแอป เครื่องหมายบนแพ็กเก็ต อินเทอร์เฟซที่มันเข้ามา — และการค้นหาปลายทางเกิดขึ้นหลังจากนั้น ภายในตารางที่กฎเหล่านั้นเลือก
การตัดสินใจสามอย่างในลำดับที่แน่นอน
แพ็กเก็ตขาออกตัดสินใจสามเรื่องแยกกัน อย่างแรก กฎนโยบายกำหนดว่าจะใช้ตารางเส้นทางใด อย่างที่สอง เส้นทางในตารางนั้นกำหนดฮอปถัดไปและอินเทอร์เฟซขาออก อย่างที่สาม ฮุกของ netfilter ตัดสินว่าแพ็กเก็ตจะรอด ถูกแก้ไข หรือถูกเปลี่ยนเส้นทาง
ลำดับสำคัญเพราะแต่ละขั้นตอบได้เพียงคำถามของตัวเอง กฎไฟร์วอลล์ที่ยอมรับแพ็กเก็ตไม่ได้เลือกตาราง และเส้นทางที่เพิ่มเข้าไปในตารางที่ไม่มีกฎใดเลือกก็ไม่มีผล ความสับสนส่วนใหญ่เกี่ยวกับ VPN บน Android มาจากการแก้หนึ่งในสามแล้วไม่เห็นการเปลี่ยนแปลง เพราะความผิดพลาดอยู่ที่อีกอย่างหนึ่ง
| Stage | Selector | What it cannot decide |
|---|---|---|
| Policy rule | uid range, mark, incoming interface | Which route exists inside the table |
| Route lookup | Destination prefix, longest match | Whether the packet is allowed out |
| Netfilter hook | Chain position, match conditions | Which table was selected |
เครื่องหมายเป็นฟิลด์ที่อัดแน่น ไม่ใช่ป้ายที่คุณเป็นเจ้าของ
Android อัดข้อเท็จจริงหลายอย่างไว้ในค่าเครื่องหมายเดียวกัน ได้แก่ เลือกเครือข่ายใด แอปเลือกเครือข่ายอย่างชัดเจนหรือไม่ ซ็อกเก็ตได้รับการปกป้องจาก VPN หรือไม่ และบิตที่เกี่ยวกับสิทธิ์ หัวข้อ fwmark ของ AOSP กำหนดเค้าโครงนั้นสำหรับทรีปัจจุบัน และเค้าโครงเป็นรายละเอียดภายในของแพลตฟอร์มที่เปลี่ยนไประหว่างรุ่น
นั่นคือเหตุผลที่บน Android การเขียนค่าเครื่องหมายทั้งค่าด้วย iptables -j MARK --set-mark เป็นเรื่องอันตราย มันไม่ได้เพิ่มแท็ก แต่แทนที่การเลือกเครือข่ายที่ระบบทำไว้แล้ว แพ็กเก็ตจึงตรงกับกฎอื่น ซึ่งอาจดูเหมือน VPN เริ่มทำงาน หรือดูเหมือนแอปที่ไม่เกี่ยวข้องสูญเสียการเชื่อมต่อ ขึ้นอยู่กับว่าบิตใดถูกเขียนทับ
หากจำเป็นต้องแตะเครื่องหมาย ให้อ่านค่าปัจจุบันก่อนและใช้มาสก์เพื่อให้แก้ไขเฉพาะบิตที่คุณเข้าใจ:
ip rule show
ip route show table all | head -40
ip route get 10.20.4.11เครื่องหมายการเชื่อมต่อเป็นออบเจกต์แยกจากเครื่องหมายแพ็กเก็ต และทั้งสองไม่ใช่เส้นทาง การคืนเครื่องหมายบนแพ็กเก็ตตอบกลับเป็นขั้นตอนแยกจากการเลือกตารางตอนขาออก นั่นคือเหตุผลที่การแก้ทางเดียวทำให้เกิดการเชื่อมต่อที่เปิดแล้วค้าง
ใครเป็นเจ้าของกฎและตาราง
บริการเครือข่ายของ Android คือ netd สร้างกฎและตารางต่อเครือข่าย AOSP RouteController คือที่ที่กฎเหล่านั้นถูกประกอบสำหรับ VPN เครือข่ายกายภาพ และช่วง uid และวงจรชีวิตผูกกับเหตุการณ์เครือข่ายไม่ใช่ไฟล์กำหนดค่า
มีผลตามมาสองประการ อย่างแรก ลำดับความสำคัญและหมายเลขตารางที่คุณพบในเครื่องหนึ่งเป็นรายละเอียดภายในของการบิลด์ ไม่ใช่ส่วนติดต่อ: หมายเลขที่ดูเหมือนกันบน Android อีกรุ่นอาจหมายถึงสิ่งอื่นโดยสิ้นเชิง อย่างที่สอง สถานะถูกสร้างใหม่เมื่อเครือข่ายเปลี่ยน ดังนั้นกฎที่แทรกวันนี้จากเชลล์ root อาจหายไปหลังการสลับ Wi-Fi ครั้งถัดไป
การหายไปนั้นมักถูกรายงานว่าระบบเพิกเฉยต่อเส้นทาง สิ่งที่เกิดขึ้นจริงคือกฎที่เลือกตารางไม่มีอยู่แล้ว และเส้นทางในตารางตอนนี้เข้าถึงไม่ได้จากมุมมองของแพ็กเก็ต ตรวจสอบรายการกฎ ไม่ใช่รายการเส้นทาง เมื่อการกำหนดค่าที่เคยทำงานหยุดทำงานหลังเชื่อมต่อใหม่
คำถามเรื่องลำดับฮุกไม่มีคำตอบสากล
คำถามที่ว่า iptables ทำงานก่อนการเลือกเส้นทาง VPN หรือไม่ตอบไม่ได้หากไม่ระบุเส้นทางของแพ็กเก็ต แพ็กเก็ตที่สร้างในเครื่องผ่านฮุก output ซึ่งการเปลี่ยนเครื่องหมายกระตุ้นการตรวจสอบเส้นทางใหม่ — เป็นการค้นหาครั้งที่สอง ไม่ใช่การแก้ไขย้อนหลังของการค้นหาครั้งแรก แพ็กเก็ตที่มาจากไคลเอนต์ที่ต่อผ่าน tether ผ่านเส้นทาง prerouting และถูกส่งต่อแทน และเชนที่เห็นมันเป็นเชนอื่น
ดังนั้นกฎเดียวกันอาจได้ผลกับทราฟฟิกของแอปและมองไม่เห็นสำหรับทราฟฟิกผ่าน tether และตัวนับที่ค้างที่ศูนย์บอกคุณว่าแพ็กเก็ตไปเส้นทางใด ไม่ใช่บอกว่ากฎผิด ใช้ตัวนับเพื่อยืนยันเส้นทางก่อนเปลี่ยนเงื่อนไขการตรงกันใด ๆ
นี่คือขั้นที่ความผิดพลาดของการเลือกเส้นทางตามนโยบายเห็นได้ยาก การเลือกเส้นทางไปยังตารางที่มีอยู่แต่ไม่มีปลายทางทำให้เกิดเครือข่ายเข้าถึงไม่ได้ซึ่งดูเหมือนไฟร์วอลล์ทิ้งแพ็กเก็ต ขณะที่ไฟร์วอลล์ทิ้งแพ็กเก็ตทำให้เกิดการหมดเวลาซึ่งดูเหมือนหลุมดำของเส้นทาง
วินิจฉัยภายในระบบ หรือปล่อยไว้
สำหรับการตรวจสอบที่ได้รับอนุญาต ให้ยืนยันสี่ข้อก่อนแตะอะไร: uid และโปรไฟล์ของแอป เครือข่ายที่ Android เลือกให้ VPN รวมแอปนั้นหรือไม่ และปัญหามีอยู่ทั้งสองตระกูลที่อยู่ การยกเว้นรายแอปอธิบายรายงาน VPN ใช้งานไม่ได้จำนวนมากโดยไม่มีความผิดพลาดด้านเส้นทางเลย
จากนั้นอ่านกฎ มาสก์ และตารางที่บังคับใช้จริง และเก็บการสลับเครือข่ายไว้ในหน้าต่างสังเกต หากพฤติกรรมเปลี่ยนตลอดการเชื่อมต่อใหม่ คุณกำลังดูวงจรชีวิตที่ถูกจัดการ ไม่ใช่เส้นทางที่หายไป
สำหรับความต้องการทั่วไป ให้ใช้ตัวควบคุมที่รองรับ: การรวมและการยกเว้นรายแอป ในแอป VPN และการเลือกเครือข่ายของแพลตฟอร์มเองสำหรับทุกสิ่งที่ต้องการเส้นทางเฉพาะ หากการผสานรวมที่ได้สิทธิพิเศษต้องร่วมมือกับกลไกเส้นทางจริง ๆ ให้กำหนดเป้าหมายไปที่การใช้งานของ Android รุ่นที่คุณรองรับอย่างแม่นยำ และดูแลวงจรชีวิตผ่านคอมโพเนนต์ที่เป็นเจ้าของ การล้างเชนของแพลตฟอร์มหรือการแทรกกฎที่มีลำดับความสำคัญสูงจะเปลี่ยนการวินิจฉัยให้กลายเป็นตัวจัดการเครือข่ายตัวที่สอง และโทรศัพท์จะทำงานตามนั้น