กฎไฟร์วอลล์ตาม SSID หยุดกรองหลังสลับ Wi-Fi
ไฟร์วอลล์ที่ผูกกับ SSID ล้มเหลวแบบเปิดเมื่อ Android ส่งชื่อเครือข่ายที่ไม่รู้จักกลับมา แยกตัวตนออกจากการบังคับใช้และให้สถานะที่ไม่รู้จักมีนโยบายของตัวเอง
กฎนั้นง่าย: กรองทราฟฟิกเฉพาะขณะที่โทรศัพท์เชื่อมต่อกับ Wi-Fi ของออฟฟิศ มันคงอยู่มาหลายเดือน แล้วเช้าวันหนึ่งโทรศัพท์ก็อยู่บน SSID เดิมพร้อมไอคอนกุญแจเดิม แต่การกรองหยุดไปแล้ว ไม่มีอะไรเปลี่ยนในเครือข่าย สิ่งที่เปลี่ยนคือแอปมองเห็นชื่อเครือข่ายได้หรือไม่ บน Android «ฉันอยู่บน Wi-Fi ไหน» กับ «บล็อกทราฟฟิกนี้» เป็นงานสองอย่างที่แยกกัน และไฟร์วอลล์ที่หลอมสองอย่างนี้เข้าด้วยกันจะล้มเหลวแบบเปิดพอดีตอนที่ชื่อนั้นใช้ไม่ได้
อาการ: ตัวตนหายไปและนโยบายตามมา
กฎ SSID อ่านค่าหนึ่งค่าแล้วเลือกสาขา เมื่อการอ่านไม่คืนอะไรที่มีประโยชน์ โค้ดต้องทำอะไรสักอย่าง และค่าตั้งต้นที่พบบ่อยคือ «ไม่ใช่เครือข่ายที่คาดไว้ จึงไม่กรอง» ค่าตั้งต้นนั้นเปลี่ยนปัญหาสิทธิ์ให้กลายเป็นการรั่วของทราฟฟิก ไอคอนกุญแจยังเห็นได้เพราะบริการ VPN ยังทำงานอยู่ มันเพียงบังคับใช้สาขาอื่น
ดูลำดับของเหตุการณ์ ไม่ใช่ดูเครือข่าย กล่องขอสิทธิ์ที่ถูกปฏิเสธ การอัปเดตระบบที่ย้ายการเข้าถึง SSID ไปไว้หลังสิทธิ์อื่น บริการตำแหน่งที่ปิดอยู่ หรือการเปลี่ยนนโยบายโปรไฟล์งาน ล้วนให้ผลลัพธ์เดียวกันได้ในขณะที่โทรศัพท์ยังอยู่ที่จุดเชื่อมต่อเดิม
ทำไมชื่อจึงกลับมาเป็นค่าที่ไม่รู้จัก
WifiInfo.getSSID() คืนค่าตัวระบุชุดบริการของเครือข่ายปัจจุบัน และ Android ระบุว่าการเข้าถึงฟิลด์ที่อ่อนไหวต่อตำแหน่งนั้นขึ้นอยู่กับสิทธิ์ เมื่อไม่มีการเข้าถึง การเรียกจะคืน UNKNOWN_SSID แทนที่จะล้มเหลวเสียงดัง ค่าที่ว่างหรือไม่รู้จักจึงไม่ใช่หลักฐานว่าโทรศัพท์ออกจาก Wi-Fi แต่เป็นหลักฐานว่าแอปจำแนกเครือข่ายไม่ได้
การตรวจสองอย่างแยกกรณีเหล่านี้ออก ตรวจสอบว่าโทรศัพท์เชื่อมต่ออยู่และดูว่าระบบรายงานอะไร แล้วตรวจสอบว่าแอปมีสิทธิ์ที่จำเป็นบน Android เวอร์ชันนี้จริง:
adb shell cmd wifi status
adb shell dumpsys package <your.app> | grep -i -E "ACCESS_FINE_LOCATION|NEARBY_WIFI_DEVICES"
ถ้าแถบสถานะแสดงเครือข่ายที่เชื่อมต่ออยู่แต่แอปเห็นชื่อที่ไม่รู้จัก ปัญหาของคุณคือสิทธิ์หรือระดับ API ไม่ใช่ปัญหา Wi-Fi แก้ไขก่อนแตะกฎไฟร์วอลล์ เพราะทุกกฎที่ตามมาถูกประเมินเทียบกับค่าที่แอปอ่านไม่ได้
การกรองทำงานที่ไหนจริง ๆ
ไฟร์วอลล์ Android ภายในเครื่องมักใช้โมเดล VpnService โดยไม่ส่งทราฟฟิกไปยังเซิร์ฟเวอร์ระยะไกล: มันรับอินเทอร์เฟซเสมือน ใช้กฎของตัวเองและส่งต่อสิ่งที่อนุญาต แพลตฟอร์มอนุญาตบริการ VPN ที่ใช้งานอยู่ได้หนึ่งบริการต่อโปรไฟล์ผู้ใช้ และตัวที่สองจะแทนที่ตัวแรกแทนที่จะซ้อนทับกัน แอปไฟร์วอลล์แยกและ VPN งานแยกจึงไม่เป็นห่วงโซ่สองชั้น หนึ่งในนั้นชนะ
เรื่องนี้สำคัญกับกฎ SSID เพราะจุดบังคับใช้และจุดสังเกตเป็นส่วนประกอบคนละส่วน VpnService ตัดสินว่าอะไรออกจากอุปกรณ์ ส่วน API ของ Wi-Fi เป็นเพียงผู้ให้ป้ายกำกับ แอปบังคับใช้ถูกแต่จำแนกผิดได้ และนั่นคือความล้มเหลวในบทความนี้
ให้สถานะที่ไม่รู้จักมีนโยบายของตัวเอง
มองตัวตนของเครือข่ายเป็นสามสถานะ และเขียนนโยบายของแต่ละสถานะก่อนปล่อยกฎ สถานะที่สามคือสถานะที่ถูกลืม และเป็นที่ที่ผู้โจมตีหรือการกำหนดค่าผิดจะวางคุณไว้
| Observation | Policy to specify |
|---|---|
| Expected SSID is readable | The explicit filtering policy you designed |
| A different SSID is readable | The default policy for untrusted networks |
| Unknown, changing or unreadable | Fail closed until classification is reliable |
การล้มเหลวแบบปิดหมายความว่าสถานะที่ไม่รู้จักสืบนโยบายที่เข้มงวดสมเหตุสมผลที่สุด ไม่ใช่ที่สะดวกที่สุด ถ้าทำให้โทรศัพท์ใช้ไม่ได้บนเครือข่ายใหม่ ทางแก้ที่ถูกคือข้อยกเว้นที่ตั้งใจและมองเห็นได้ ไม่ใช่การตัดสินใจไว้วางใจแบบเงียบที่ซ่อนอยู่ในการตรวจค่าที่ว่าง
SSID ที่คุ้นเคยเป็นเพียงป้าย ไม่ใช่หลักฐานของผู้ให้บริการเครือข่าย ใครก็ตั้งจุดเชื่อมต่อด้วยชื่อออฟฟิศได้ การตรงกันของชื่อจึงไม่ควรเป็นสิ่งเดียวที่กั้นระหว่างเซสชันที่ละเอียดอ่อนกับเซกเมนต์ที่ไม่น่าเชื่อถือ
ทดสอบการเปลี่ยนผ่าน ไม่ใช่สภาวะคงที่
การทดสอบในสภาวะคงที่ผ่านบนเครือข่ายที่คุณสร้างกฎ ความล้มเหลวอาศัยอยู่ในการเปลี่ยนผ่าน: สิทธิ์ถูกปฏิเสธ, Wi-Fi ไปมือถือ, SSID หนึ่งไปอีกอัน, บริการ VPN เริ่มใหม่ และแอป VPN อื่นเข้ายึดอินเทอร์เฟซ สำหรับแต่ละกรณี ให้ตัดสินว่าการเชื่อมต่อที่มีอยู่ถูกพิจารณาใหม่หรือไม่ และทราฟฟิกที่ป้องกันยังถูกบล็อกอยู่หรือไม่ขณะสถานะยังไม่รู้จัก
เขียนผลลัพธ์เป็นสามประโยค: เงื่อนไขที่สังเกตได้ ส่วนประกอบที่บังคับใช้การตัดสินใจ และทางถอยที่ตั้งใจ ถ้าขาดอย่างใดอย่างหนึ่งในสามข้อ กฎนั้นยังไม่ใช่นโยบาย มันคือการเดาที่บังเอิญใช้ได้บนเครือข่ายออฟฟิศ