ทำให้ ip rule อยู่รอดหลังเชื่อมต่อใหม่กับ systemd-networkd
กฎ ip ที่สร้างจากเชลล์จะหายไปเมื่อเกิดเหตุการณ์ลิงก์ครั้งถัดไป ประกาศกฎ ตาราง และเส้นทางของมันใน systemd-networkd เพื่อให้สร้างนโยบายขึ้นใหม่
เพิ่มกฎนโยบายด้วย ip rule และมันทำงานจนกว่าลิงก์จะหายไป เมื่อถึงตอนนั้นมันก็หายไปเฉย ๆ ไม่มีอะไรล้มเหลวเสียงดัง สถานะของเคอร์เนลเปลี่ยนไป และไม่มีเจ้าของการกำหนดค่าใดรู้ว่ากฎนี้ควรมีอยู่ นั่นคือความแตกต่างทั้งหมดระหว่างกฎที่อยู่รอดกับกฎที่ไม่อยู่รอด บนโฮสต์ที่ใช้ systemd-networkd ทางแก้คือให้กฎมีเจ้าของ ไม่ใช่รันคำสั่งซ้ำหลังการเชื่อมต่อใหม่ทุกครั้ง
กฎจะมีอยู่ก็ต่อเมื่อมีคนเป็นเจ้าของ
นโยบายการกำหนดเส้นทางของเคอร์เนลเป็นสถานะ ไม่ใช่การกำหนดค่า มันอยู่ในระบบที่กำลังทำงาน และสิ่งใดก็ตามที่รื้ออินเทอร์เฟซที่มันพึ่งพาอยู่ก็พามันไปด้วยได้ คำสั่งในเชลล์เปลี่ยนสถานะนั้นและไม่เหลือบันทึกเจตนาไว้
ตัวจัดการเครือข่ายทำงานตรงกันข้าม พวกมันอ่านการกำหนดค่า นำไปใช้ และนำไปใช้อีกครั้งเมื่อเหตุการณ์ลิงก์ทำให้สถานะเดิมใช้ไม่ได้ กฎที่ประกาศไว้ในการกำหนดค่าของพวกมันจะถูกสร้างใหม่ ขณะที่กฎที่เพิ่มไว้ข้าง ๆ เป็นวัตถุแปลกปลอมที่ไม่มีเจ้าของ
ความแตกต่างนั้นมีชื่อใน networkd และคุ้มค่าที่จะอ่านก่อนเปิดใช้อะไรก็ตาม ในเวอร์ชันใหม่กฎแปลกปลอมจะถูกลบโดยค่าเริ่มต้น ซึ่งทำให้คนที่คาดว่ารายการที่ทำด้วยมือจะคงอยู่ต้องประหลาดใจ
อ่านเวอร์ชันก่อนที่จะเชื่อถือการตั้งค่า
พฤติกรรมความเป็นเจ้าของถูกควบคุมด้วยการตั้งค่าใน networkd.conf และการตั้งค่านั้นไม่มีใน systemd รุ่นเก่า ตรวจสอบเวอร์ชันที่ติดตั้งก่อนออกแบบโดยอิงมัน เพราะโฮสต์รุ่นเก่าทำงานต่างจากเอกสารที่คุณอ่านอยู่
มีสองค่าที่สำคัญ ค่าหนึ่งตัดสินว่าจะลบกฎที่ไม่ได้ประกาศในการกำหนดค่าของ networkd หรือไม่ อีกค่าทำเช่นเดียวกันกับเส้นทาง ทั้งคู่เกี่ยวกับความเป็นเจ้าของไม่ใช่เนื้อหาของนโยบาย และทั้งคู่เลือกพฤติกรรมที่เข้มงวดกว่าโดยค่าเริ่มต้นในรุ่นปัจจุบัน การปิดทั้งสองทั่วทั้งระบบจะทำให้กฎแปลกปลอมทุกรายการยังมีชีวิต ซึ่งเป็นการตัดสินใจที่กว้างกว่าการประกาศนโยบาย VPN เพียงข้อเดียวมาก
systemctl --version | head -1
networkctl --version | head -1
grep -R "ManageForeign" /etc/systemd/ /usr/lib/systemd/ 2>/dev/null
grep นั้นบอกคุณว่าอะไรถูกตั้งไว้ในเครื่องและค่าเริ่มต้นของผู้จำหน่ายคืออะไร การไม่มีอยู่ก็เป็นข้อมูลเช่นกัน เพราะหมายความว่าค่าเริ่มต้นที่คอมไพล์ไว้มีผล เขียนค่าเริ่มต้นลงในบันทึกของคุณเพื่อให้คนต่อไปไม่ต้องค้นพบมันอีก
ประกาศกฎและตารางที่มันชี้ไป
กฎในไฟล์ .network ระบุชื่อตาราง และชื่อก็ทำได้เพียงเท่านั้น มันไม่ได้สร้างเส้นทางภายในตารางนั้นและไม่ได้ตรวจว่าสมเหตุสมผลหรือไม่ การประกาศกฎโดยไม่มีเส้นทางจะได้นโยบายที่จับคู่ทราฟฟิกแล้วทิ้งมันไป
ประกาศเส้นทางในไฟล์เดียวกัน โดยมีฮอปถัดไปที่เข้าถึงได้และตารางที่ถูกต้อง คงลำดับความสำคัญไว้ในกฎที่ประกาศเพื่อให้มันไปอยู่ในตำแหน่งที่คุณคาดหวังในรายการที่เรียงแล้ว กฎที่ไปถึงตารางผิดเร็วกว่าที่ตั้งใจจะเปลี่ยนทราฟฟิกมากกว่าบริการที่คุณอยากซ่อม อ่านส่วนด้านล่างเป็นรูปทรงไม่ใช่ไฟล์ที่สมบูรณ์ เพราะความเป็นเจ้าของอินเทอร์เฟซและส่วนที่เหลือของการเชื่อมต่อยังต้องมีอยู่
[RoutingPolicyRule]
Family=ipv4
IPProtocol=tcp
SourcePort=443
Table=100
Priority=1000
[Route]
Destination=10.80.0.0/24
Gateway=10.80.0.1
Table=100
จากนั้นโหลดใหม่และอ่านสถานะของเคอร์เนลแทนไฟล์ การกำหนดค่าที่แยกวิเคราะห์อย่างสะอาดก็ยังอาจสร้างกฎที่คุณไม่ได้ตั้งใจ และมุมมองทั้งสองจะตรงกันก็ต่อเมื่อการประกาศครบถ้วน
เลือกเจ้าของหนึ่งรายสำหรับอินเทอร์เฟซ
ผู้จัดการสองรายบนอุโมงค์เดียว ก่อให้เกิดการต่อสู้ที่ดูเหมือนบั๊กในทั้งสอง การนำการตั้งค่า wg-quick ที่มีอยู่เข้ามาใน networkd เป็นการย้ายไม่ใช่การเพิ่ม และการรันทั้งสองทำให้อินเทอร์เฟซและกฎของมันอยู่ใต้เจ้าของสองราย
ทำการย้ายในครั้งเดียว หยุดยูนิตเก่า ปิดใช้งาน ประกาศอินเทอร์เฟซและเส้นทางของมันใน networkd แล้วโหลดใหม่ ตรวจสอบว่ายูนิตเก่าไม่สามารถกลับมาเมื่อบูต ยูนิตที่หลงเหลือและกลับมาทำงานหลังรีบูตจะเขียนทับสถานะที่คุณเพิ่งประกาศ เก็บไฟล์การกำหนดค่าเก่าไว้จนกว่าไฟล์ใหม่จะผ่านการเชื่อมต่อใหม่หนึ่งครั้ง แล้วจึงปลดระวาง
ความเป็นเจ้าของเครื่องหมายสมควรได้รับการดูแลเช่นเดียวกัน หากกฎตรงกับเครื่องหมายของไฟร์วอลล์ ต้องมีบางอย่างตั้งเครื่องหมายนั้น กฎที่อ้างถึงเครื่องหมายที่ไม่มีใครตั้งเป็นการกำหนดค่าที่ตายแล้วซึ่งดูเหมือนตั้งใจ
ฝึกซ้อมเหตุการณ์ในวงจรชีวิต
การกำหนดค่าดีได้เพียงเท่าพฤติกรรมของมันตลอดเหตุการณ์ต่าง ๆ หยุดลิงก์ ยกขึ้นใหม่ รีสตาร์ตบริการ และต่ออายุที่อยู่ หลังจากแต่ละอย่าง ให้อ่านรายการกฎและเนื้อหาในตาราง
sudo networkctl reload
ip rule show
ip route show table 100
sudo systemctl restart systemd-networkd
ผลลัพธ์ที่ตั้งใจคือนโยบายเดิมที่มีเจ้าของถูกสร้างใหม่และสถานะเก่าถูกปลดระวาง ซึ่งคงทนกว่าการเพิ่มกฎในเชลล์ซ้ำหลังการเชื่อมต่อใหม่ทุกครั้ง เก็บหนึ่งบรรทัดในบันทึกการเปลี่ยนแปลงที่ระบุไฟล์ที่เป็นเจ้าของกฎและเวอร์ชันที่รองรับมัน จากนั้นวิศวกรคนต่อไปจะหานโยบายได้โดยไม่ต้องค้นประวัติเชลล์ กฎที่ไม่มีใครเป็นเจ้าของคือกฎที่จะหายไปอีกครั้ง