กฎนั้นง่าย: กรองทราฟฟิกเฉพาะขณะที่โทรศัพท์เชื่อมต่อกับ 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 เป็นเพียงผู้ให้ป้ายกำกับ แอปบังคับใช้ถูกแต่จำแนกผิดได้ และนั่นคือความล้มเหลวในบทความนี้

ให้สถานะที่ไม่รู้จักมีนโยบายของตัวเอง

มองตัวตนของเครือข่ายเป็นสามสถานะ และเขียนนโยบายของแต่ละสถานะก่อนปล่อยกฎ สถานะที่สามคือสถานะที่ถูกลืม และเป็นที่ที่ผู้โจมตีหรือการกำหนดค่าผิดจะวางคุณไว้

ObservationPolicy to specify
Expected SSID is readableThe explicit filtering policy you designed
A different SSID is readableThe default policy for untrusted networks
Unknown, changing or unreadableFail closed until classification is reliable

การล้มเหลวแบบปิดหมายความว่าสถานะที่ไม่รู้จักสืบนโยบายที่เข้มงวดสมเหตุสมผลที่สุด ไม่ใช่ที่สะดวกที่สุด ถ้าทำให้โทรศัพท์ใช้ไม่ได้บนเครือข่ายใหม่ ทางแก้ที่ถูกคือข้อยกเว้นที่ตั้งใจและมองเห็นได้ ไม่ใช่การตัดสินใจไว้วางใจแบบเงียบที่ซ่อนอยู่ในการตรวจค่าที่ว่าง

SSID ที่คุ้นเคยเป็นเพียงป้าย ไม่ใช่หลักฐานของผู้ให้บริการเครือข่าย ใครก็ตั้งจุดเชื่อมต่อด้วยชื่อออฟฟิศได้ การตรงกันของชื่อจึงไม่ควรเป็นสิ่งเดียวที่กั้นระหว่างเซสชันที่ละเอียดอ่อนกับเซกเมนต์ที่ไม่น่าเชื่อถือ

ทดสอบการเปลี่ยนผ่าน ไม่ใช่สภาวะคงที่

การทดสอบในสภาวะคงที่ผ่านบนเครือข่ายที่คุณสร้างกฎ ความล้มเหลวอาศัยอยู่ในการเปลี่ยนผ่าน: สิทธิ์ถูกปฏิเสธ, Wi-Fi ไปมือถือ, SSID หนึ่งไปอีกอัน, บริการ VPN เริ่มใหม่ และแอป VPN อื่นเข้ายึดอินเทอร์เฟซ สำหรับแต่ละกรณี ให้ตัดสินว่าการเชื่อมต่อที่มีอยู่ถูกพิจารณาใหม่หรือไม่ และทราฟฟิกที่ป้องกันยังถูกบล็อกอยู่หรือไม่ขณะสถานะยังไม่รู้จัก

เขียนผลลัพธ์เป็นสามประโยค: เงื่อนไขที่สังเกตได้ ส่วนประกอบที่บังคับใช้การตัดสินใจ และทางถอยที่ตั้งใจ ถ้าขาดอย่างใดอย่างหนึ่งในสามข้อ กฎนั้นยังไม่ใช่นโยบาย มันคือการเดาที่บังเอิญใช้ได้บนเครือข่ายออฟฟิศ

บทความที่เกี่ยวข้อง