ทำไม hook ไฟร์วอลล์ของ VPN จึงเพิ่มกฎเดียวกันสองครั้ง
การเชื่อมต่อใหม่สามารถรัน hook ของคุณอีกครั้ง ดังนั้นออกแบบเพื่อสถานะที่ต้องการ: เชนที่เป็นเจ้าของ การทดสอบก่อนแทรก การเปลี่ยนแปลงที่เรียงลำดับหนึ่งครั้ง และการรื้อถอนที่แคบ
hook ทำงานครั้งแรก และหลังการเชื่อมต่อใหม่สามครั้งเชนก็เก็บสำเนาของกฎเดียวกันสามชุด ไม่มีอะไรล้มเหลวอย่างเสียงดัง สคริปต์เพียงทำตามที่สั่งทุกครั้งที่รัน hook ของ VPN คือการดำเนินการกำหนดค่าที่รันได้มากกว่าหนึ่งครั้ง จึงต้องมีเจ้าของ มีสถานะที่ต้องการ และมีการเปลี่ยนแปลงที่เรียงลำดับ เดินตามลำดับนั้นแล้วความซ้ำจะหยุด
มอบเจ้าของให้กฎก่อนเขียนกฎใด ๆ
ตัดสินใจว่าเชนหรือตารางใดเป็นของส่วนเชื่อมต่อนี้ก่อนเขียนกฎสักข้อ เชนเฉพาะที่ hook สร้างและล้างออกเป็นรูปแบบความเป็นเจ้าของที่ชัดที่สุด เพราะการทำความสะอาดจะลบเชนนั้นได้โดยไม่แตะนโยบายของคนอื่น หากจำเป็นต้องเพิ่มกฎในเชนที่ใช้ร่วมกัน ให้ติดแท็กด้วยคอมเมนต์เพื่อให้การค้นหาภายหลังพบกฎของคุณเท่านั้น ความเป็นเจ้าของทำให้การรื้อถอนปลอดภัย และการรื้อถอนคือส่วนที่ล้มเหลวอย่างเงียบ ๆ
iptables -N VPN_HOOK 2>/dev/null || true
iptables -C INPUT -j VPN_HOOK 2>/dev/null || iptables -I INPUT -j VPN_HOOK
iptables -S VPN_HOOK
คอมเมนต์ที่นี่ไม่ใช่เครื่องประดับ มันคือความแตกต่างระหว่างการลบกฎของคุณกับการลบกฎที่บังเอิญดูคล้ายกัน และมันคงอยู่ในชุดกฎที่บันทึกไว้ เขียนคอมเมนต์ครั้งเดียวในตัวแปรและใช้สตริงเดียวกันในทุกคำสั่งที่เพิ่ม ทดสอบ หรือลบ
ทดสอบสถานะที่ต้องการแทนการเพิ่มซ้ำ
เขียนว่าอะไรควรมีอยู่ขณะอุโมงค์ทำงาน: อินเทอร์เฟซใด แหล่งและปลายทางใด โปรโตคอลใดและพอร์ตใด จากนั้นแสดงแต่ละกฎเป็นการทดสอบตามด้วยการแทรก เพื่อให้การรันครั้งที่สองพบกฎและไม่ทำอะไร คำสั่งตรวจสอบจะจบด้วยศูนย์เมื่อกฎมีอยู่ และนั่นคือสัญญาณที่สคริปต์ต้องการพอดี เอกสารอ้างอิง iptables อธิบายรูปแบบการตรวจสอบ การต่อท้าย และการแทรกที่ใช้ที่นี่
iptables -C VPN_HOOK -i tun0 -p tcp --dport 443 -j ACCEPT ||
iptables -A VPN_HOOK -i tun0 -p tcp --dport 443 -j ACCEPT
ระวังตำแหน่ง การตรวจสอบกฎและแทรกที่หัวอาจ ย้ายการอนุญาตไปก่อนการปฏิเสธโดยเจตนาที่เคยมาก่อน ดังนั้นการรันครั้งที่สองจึงเปลี่ยนพฤติกรรมแม้ไม่ได้เพิ่มอะไร เพิ่มที่ท้ายภายในเชนของคุณเอง และควบคุมลำดับด้วยตำแหน่งของการกระโดดไปยังเชนนั้น หากลำดับภายในเชนสำคัญ ให้สร้างเชนใหม่จากรายการที่รู้จักแทนการปะกฎทีละข้อ
หยุดหากกฎที่ต้องการไม่สามารถแสดงเป็นการทดสอบที่มั่นคงได้ ซึ่งมักหมายความว่าสถานะที่ต้องการยังคลุมเครือ
เรียงลำดับการเปลี่ยนแปลงแทนการหวังว่ามันจะคงอยู่
การเรียก hook สองครั้งสามารถทับซ้อนกันได้ และทั้งคู่อาจเห็นว่ากฎยังไม่มีก่อนที่ฝ่ายใดจะเพิ่ม ตัวเลือกการรอของ xtables ทำให้คำสั่งรอ lock แต่ไม่ได้ทำให้ลำดับตรวจสอบแล้วเพิ่มเป็นอะตอมข้ามสองคำสั่ง จัดลำดับการดำเนินการทั้งหมดด้วย lock ของคุณเอง หรือใช้ตัวจัดการที่ใช้ชุดที่ประกาศไว้เป็นธุรกรรมเดียว nftables ทำอย่างหลังได้ และนั่นเป็นเหตุผลหนึ่งที่ควรเลือกใช้บนโฮสต์ที่มีให้ใช้
flock /run/vpn-hook.lock /usr/local/sbin/vpn-firewall-apply
nft -f /etc/nftables/vpn-hook.nft
ไม่ว่าจะเลือกกลไกใด ให้เก็บส่วนสำคัญให้สั้นและทำให้กลับเข้าได้อีกครั้ง hook ที่ล้มกลางทางควรปลอดภัยที่จะรันซ้ำ บันทึกผลลัพธ์เพื่อให้การรันซ้ำมองเห็นได้ใน journal แทนการอนุมานจากจำนวนกฎ หากผู้ดูแลสองรายต่างกันเรียก hook ได้ ให้แก้เรื่องนั้นก่อน ไม่มี lock ใดซ่อมเจ้าของสองรายได้
รื้อเฉพาะสิ่งที่คุณเป็นเจ้าของ
การรื้อถอนต้องแยกการเชื่อมต่อแบบแทนที่ออกจากการเชื่อมต่อที่มันปลดระวาง และต้องอยู่รอดจากเหตุการณ์ที่ไม่เคยได้รับการทำความสะอาดอย่างเรียบร้อย ลบด้วยตัวระบุชุดเดียวกับที่ใช้เพิ่ม และอย่าล้างเชนที่ใช้ร่วมกันเพื่อทำให้การทำความสะอาดง่ายขึ้น หลังจากหยุดแบบแข็ง ให้รันรอบกระทบยอดเมื่อเริ่มครั้งถัดไปแทนการถือว่า hook ขาลงได้รันแล้ว
iptables -D VPN_HOOK -i tun0 -p tcp --dport 443 -j ACCEPT
iptables -F VPN_HOOK
ip -brief link show type tun
อายุการใช้งานของอินเทอร์เฟซก็เป็นส่วนหนึ่งของการออกแบบ การเชื่อมต่อใหม่อาจสร้างอุปกรณ์ที่มีชื่อต่างกัน ดังนั้นกฎที่ฝังชื่ออุโมงค์ที่สองแบบตายตัวจะล้าสมัยในขณะที่ยังดูใช้ได้ ควรใช้อัตลักษณ์ที่การเชื่อมต่อเปิดเผยเอง และอ่านใหม่ทุกครั้งที่รัน ทดสอบสามเหตุการณ์แยกกัน: การเชื่อมต่อซ้ำ การเชื่อมต่อแทนที่ และการปิดเครื่อง การรับส่งที่ได้รับอนุญาตควรผ่านทั้งสามโดยไม่ซ้ำ และบริการที่ไม่เกี่ยวข้องควรไม่ถูกแตะต้อง
การเดินจะจบเมื่อ hook มีเจ้าของ มีการทดสอบสำหรับทุกกฎที่เพิ่ม มีเส้นทางที่เรียงลำดับหนึ่งเส้นทาง และมีการรื้อถอนที่ลบเฉพาะสถานะของตัวเอง hook ที่ปลอดภัยต่อการรันสองครั้งมีค่ามากกว่า hook ที่ฉลาดเพียงครั้งเดียว