สวิตช์ตัดการเชื่อมต่อ pf ของ macOS สำหรับ OpenVPN: กฎที่ปิดเมื่อล้มเหลว
ชุดกฎ pf บล็อกทราฟฟิกโดยตรงขณะที่อุโมงค์ลงอยู่ รักษาเส้นทางของไคลเอนต์ไปยังเซิร์ฟเวอร์ แล้วพิสูจน์การบล็อกด้วยการปิดอุโมงค์
บน macOS สวิตช์ตัดการเชื่อมต่อจะดีได้เพียงเท่ากับนโยบายตัวกรองแพ็กเก็ตที่อยู่เบื้องหลัง และ pf คือส่วนที่บังคับใช้นโยบายนั้น นโยบายต้องทำสองสิ่งตรงข้ามกันพร้อมกัน คือปล่อยให้ไคลเอนต์ไปถึงเซิร์ฟเวอร์ของตนเพื่อให้มีอุโมงค์ได้ และหยุดทุกอย่างอื่นไม่ให้ออกไปโดยตรง ชุดกฎที่เผยแพร่ส่วนใหญ่ทำข้อที่สองได้และลืมข้อแรก เครื่องจึงสูญเสียการเชื่อมต่อแทนที่จะได้การป้องกัน เวอร์ชันที่ใช้ได้จะระบุจุดปลาย ตัวแก้ชื่อ และอุโมงค์ และไม่มากกว่านั้น
ตัวกรองแพ็กเก็ตตัดสินใจอะไรได้ และอะไรไม่ได้
pf ดูอินเทอร์เฟซ ที่อยู่ หมายเลขโปรโตคอล และพอร์ต แล้วหยุดอยู่แค่นั้น มันไม่เคยรู้ว่ากระบวนการใดเปิดซ็อกเก็ต ดังนั้นสิทธิ์ที่เขียนไว้สำหรับโปรแกรมหนึ่งจึงกลายเป็นสิทธิ์ของทุกโปรแกรมที่เข้าถึงพอร์ตเดียวกันได้ นี่คือวิธีที่ข้อยกเว้น UDP ที่ใจกว้างเปลี่ยนสวิตช์ตัดการเชื่อมต่อกลับเป็นเครือข่ายธรรมดา การบล็อกที่ตระหนักถึงแอปพลิเคชันเป็นของไคลเอนต์หรือส่วนขยายระบบ ไม่ใช่ไฟล์นี้
ตัวกรองไม่ได้สร้างเส้นทางเช่นกัน เมื่อไคลเอนต์ล้ม เส้นทางเริ่มต้นอาจยังชี้ไปยังอุโมงค์ที่ตายแล้ว และ pf เปลี่ยนสิ่งนั้นเป็นแพ็กเก็ตที่ถูกบล็อกแทนที่จะถอยกลับไปใช้ Wi-Fi อย่างเงียบ ๆ การบล็อกคือผลลัพธ์ที่ตั้งใจ ไม่ใช่ความผิดพลาดที่ต้องอ้อม
ลำดับตัดสินผลลัพธ์บ่อยกว่าข้อความของกฎ หากไม่มี quick pf จะประเมินต่อหลังการจับคู่ และกฎที่ตรงกันสุดท้ายจะชนะ ดังนั้นการผ่านแบบกว้างใกล้ด้านล่างจะลบล้างข้อยกเว้นที่ระวังไว้ด้านบน การทำเครื่องหมายการผ่านด้วย quick ทำให้การจับคู่ครั้งแรกเป็นที่สิ้นสุด ซึ่งเป็นสิ่งที่ผู้เขียนนโยบายมักหมายถึง
อ่านข้อเท็จจริงของอินเทอร์เฟซและจุดปลายก่อน
อินเทอร์เฟซไร้สายไม่ได้ถูกกำหนดหมายเลขเหมือนกันในทุก Mac และอุปกรณ์อุโมงค์ได้หมายเลขที่อาจเปลี่ยนได้ระหว่างการบูต กฎที่ระบุอุปกรณ์ที่ไม่มีอยู่จะล้มเหลวตอนแยกวิเคราะห์ ซึ่งเสียงดังและจับได้ง่าย ส่วนกฎที่ระบุอุปกรณ์ที่มีอยู่ผิดจะแยกวิเคราะห์ได้สะอาดและอนุญาตทราฟฟิกที่คุณต้องการหยุด
เก็บข้อเท็จจริงขณะที่ไคลเอนต์เชื่อมต่ออยู่ เพราะอุปกรณ์อุโมงค์มีอยู่เฉพาะตอนนั้น คุณต้องมีอินเทอร์เฟซที่ถือเส้นทางเริ่มต้น อุปกรณ์ที่ไคลเอนต์สร้างขึ้น และที่อยู่กับพอร์ตของเซิร์ฟเวอร์ที่มันเรียก ค่านั้นคือค่าที่ชุดกฎส่วนใหญ่ละไว้ และการละไว้คือสาเหตุที่ชุดกฎที่คัดลอกมาบล็อกอุโมงค์ของตัวเอง
route -n get default
ifconfig -l
scutil --nc list
คำสั่งแรกระบุอินเทอร์เฟซที่ชนะอยู่ตอนนี้ คำสั่งที่สองแสดงอุปกรณ์ทุกชิ้นที่เคอร์เนลรู้จัก และคำสั่งที่สามแสดงการกำหนดค่า VPN ที่ระบบเริ่มได้ จดคำตอบเหล่านั้น แล้วอ่านที่อยู่และพอร์ตของเซิร์ฟเวอร์จากการกำหนดค่าของไคลเอนต์เอง
เขียนชุดกฎรอบเส้นทางของอุโมงค์
ไฟล์ด้านล่างปฏิเสธโดยค่าเริ่มต้นและรับกลับห้าอย่าง คือ loopback อุปกรณ์อุโมงค์ เส้นทางของไคลเอนต์ไปยังเซิร์ฟเวอร์ ตัวแก้ชื่อที่ใช้ก่อนมีอุโมงค์ และการแลกเปลี่ยนสองอย่างที่ทำให้ลิงก์ไร้สายยังใช้ได้ ชื่ออินเทอร์เฟซและที่อยู่เซิร์ฟเวอร์มาจากเครื่องของคุณ ดังนั้นแทนที่ค่าที่คุณยืนยันแล้ว หมายเลขอุโมงค์ก็จะไม่ตรงกับของคุณเช่นกัน
set skip on lo0
block all
pass out quick on utun0
# maintain this line when the server address changes
pass out quick on en1 inet proto udp to 203.0.113.10 port 1194
# only the resolver the client uses before the tunnel exists
pass out quick on en1 inet proto udp to 192.0.2.53 port 53
pass out quick on en1 inet proto udp from any port 68 to any port 67
pass out quick on en1 inet proto udp to 224.0.0.251 port 5353
บรรทัด DHCP มีอยู่เพราะ Mac ขอที่อยู่ก่อนจะมีที่อยู่ คำขอจึงออกจากพอร์ต 68 ไปยังพอร์ต 67 โดยไม่มีที่อยู่ต้นทางที่ใช้ได้ บรรทัดมัลติแคสต์ให้ระบบตัดสินว่าลิงก์ไร้สายคุ้มค่าที่จะใช้หรือไม่ และการเอาออกจะทำให้เครื่องรายงานว่าไม่มีการเชื่อมต่อบนเครือข่ายที่ทำงานอยู่ บรรทัดจุดปลายคือสิ่งที่ OpenVPN ใช้ไปถึงเซิร์ฟเวอร์ของตนได้เลย หากไม่มี block all จะทิ้งแฮนด์เชกชั้นนอกและอุโมงค์จะไม่ขึ้น บรรทัดตัวแก้ชื่อแคบกว่าสิทธิ์ DNS ทั่วไป เพราะระบุที่อยู่หนึ่งและพอร์ตหนึ่งแทนทุกคำถามที่เครื่องทำ
ข้อยกเว้นจุดปลายและตัวแก้ชื่อนั้นคือสองอย่างที่ต้องมี ทุกอย่างอื่นยังถูกบล็อก หากไคลเอนต์เรียกที่อยู่แบบตรงตัว ให้ลบบรรทัดตัวแก้ชื่อและเก็บบรรทัดจุดปลายไว้ หากที่อยู่เซิร์ฟเวอร์เปลี่ยน ให้อัปเดตบรรทัดนั้นก่อนเชื่อมต่อครั้งถัดไป หรือเติมตาราง pf จากฮุกของไคลเอนต์เองแล้วจับคู่ตารางแทน
ปลดอุโมงค์ลง แล้วรีบูต
แยกวิเคราะห์ก่อนโหลด เพราะข้อผิดพลาดทางไวยากรณ์นั้นถูกในการทดลองแห้งและแพงในเซสชันระยะไกล จากนั้นโหลดไฟล์ เปิดตัวกรองหากปิดอยู่ และอ่านกลับว่าอะไรมีผลจริง การอ่านกลับไม่ใช่พิธีกรรม แอ็งเกอร์อื่นอาจเพิ่มกฎที่คุณไม่ได้เขียน ดังนั้นเปรียบเทียบชุดที่พิมพ์กับไฟล์ของคุณ
sudo pfctl -n -v -f /etc/pf.conf
sudo pfctl -f /etc/pf.conf
sudo pfctl -e
sudo pfctl -s rules
sudo pfctl -s Anchors
sudo pfctl -a <anchor> -s rules
sudo pfctl -s info
เมื่อโหลดกฎแล้ว ให้ปลดอุโมงค์ลงและลองโหลดหน้าเว็บ ทราฟฟิกปกติควรหยุด และควรยังหยุดอยู่หลังเครื่องหลับและตื่น เพราะการเปลี่ยนสถานะนั้นคือจุดที่สถานะเก่าไหลกลับมา เชื่อมต่อใหม่และยืนยันว่าทราฟฟิกกลับมาโดยไม่แตะชุดกฎ หากเบราว์เซอร์ยังทำงานได้ทั้งที่ปลดอุโมงค์แล้ว แสดงว่ากฎบางข้อกว้างกว่าที่คุณคิด และการอ่านกลับมักระบุได้
การรีบูตคือส่วนที่คนข้าม macOS อ่าน /etc/pf.conf ตอนบูต แต่การอ่านไฟล์ไม่เหมือนกับการเปิดใช้ตัวกรอง ดังนั้น ชุดกฎที่ทำงานอยู่ตอนนี้อาจไม่ทำงานหลังรีสตาร์ต ให้รัน sudo pfctl -s info หลังจากนั้นและยืนยันว่าบรรทัดสถานะรายงานว่าตัวกรองเปิดอยู่
รักษาทางออกและเส้นทางรีสตาร์ตให้ซื่อตรง
ชุดกฎที่บล็อกทุกอย่างอาจล็อกคุณออกจากเครื่องที่คุณดูแลจากระยะไกลได้เช่นกัน แก้ไขจากเซสชันในเครื่องเมื่อทำได้ เก็บไฟล์ก่อนหน้าไว้ข้างไฟล์ใหม่ และรู้วิธีกลับก่อนที่คุณจะต้องใช้ มักใช้คำสั่งด้านล่างเพื่อปิดตัวกรองและโหลดสำเนาที่คุณเก็บไว้ซ้ำ และนั่นคือลำดับที่ควรรันจากคอนโซล ไม่ใช่ผ่านอุโมงค์ที่คุณเพิ่งตัด การย้อนกลับในห้าวินาทีชนะกฎฉลาดทุกครั้ง
sudo pfctl -d
sudo pfctl -f /etc/pf.conf.previous
sudo pfctl -s rules
ความคงทนต้องใช้ launch daemon ที่รัน pfctl -e และโหลดไฟล์ของคุณตอนบูต ปฏิบัติต่อมันเหมือนงานที่ได้สิทธิพิเศษอื่น ๆ คือพาธแบบสัมบูรณ์ ล็อกที่อ่านได้ภายหลัง และการทดสอบบนเครื่องที่คุณเข้าถึงได้จริง ไดมอนที่ล้มเหลวอย่างเงียบ ๆ จะทิ้งเครื่องไว้โดยไม่มีการป้องกันและดูเป็นปกติ
บันทึกช่องโหว่ เริ่มจากไคลเอนต์ VPN ตัวที่สองที่สร้างอุปกรณ์อุโมงค์ของตัวเอง กฎของคุณระบุอินเทอร์เฟซอุโมงค์เพียงหนึ่ง ดังนั้นตัวที่สองจะยังถูกบล็อกหรือถูกกฎกว้างที่เพิ่มภายหลังจับ อินเทอร์เฟซแบบ tethering และฮอตสปอตปรากฏเพียงบางครั้งและสมควรได้บันทึกเดียวกัน ไม่มีช่องโหว่ใดเป็นเหตุให้ข้ามนโยบาย พวกมันคือเงื่อนไขที่ยังคงใช้ได้