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

การเข้าถึงเกตเวย์ไม่เหมือนกับการส่งต่อ

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

บันทึกว่าแพ็กเก็ตของไคลเอนต์มาที่อินเทอร์เฟซใดและเส้นทางต่อไปออกผ่านอินเทอร์เฟซใด ทั้งสองอยู่ในเนมสเปซเดียว และการตั้งค่าที่สำคัญอยู่ในเนมสเปซนั้น

อ่านค่าที่ที่แพ็กเก็ตอยู่จริง

บนเกตเวย์ที่เราเตอร์ในเนมสเปซของโฮสต์ คำสั่งเดียวตอบคำถามได้: sysctl net.ipv4.ip_forward เมื่อเส้นทางเข้าและเส้นทางต่อไปอยู่ในเนมสเปซที่มีชื่อ ให้ถามเนมสเปซนั้น: ip netns exec vpn-gw sysctl net.ipv4.ip_forward ค่าของโฮสต์ไม่ใช่ตัวแทนของค่าเนมสเปซ และการเป็นหนึ่งบนโฮสต์ไม่ใช่หลักฐานของสิ่งใด

ไม่ใช่ทุกบริบทการเราเตอร์จะมีป้ายที่คุณส่งให้ ip netns ได้ สภาพแวดล้อมรันไทม์ของคอนเทนเนอร์และบริการสร้างเนมสเปซที่ไม่เคยลงทะเบียนภายใต้ชื่อที่เป็นมิตร และสำหรับสิ่งเหล่านั้นคุณใช้เครื่องมือตรวจสอบของสภาพแวดล้อมรันไทม์ แทนที่ vpn-gw ด้วยชื่อจริง หรือกลไกของสภาพแวดล้อมที่ไปถึงบริบทเดียวกัน และเลิกเดาในระดับโฮสต์

ให้การตั้งค่ามีเจ้าของเพียงหนึ่งเดียว

บนเกตเวย์โฮสต์ systemd ทั่วไป รูปแบบที่คงทนคือไฟล์ drop-in ที่มีชื่อซึ่งผู้ดูแลระบบเลือก เช่น /etc/sysctl.d/60-vpn-forwarding.conf ซึ่งมี net.ipv4.ip_forward = 1 อยู่ เขียนไฟล์แล้วโหลดไฟล์เฉพาะนั้นเพื่อให้สถานะที่กำลังทำงานเปลี่ยนด้วย: sudo sysctl -p /etc/sysctl.d/60-vpn-forwarding.conf ตามด้วยการอ่านกลับ ตัวอย่างชื่อไฟล์เป็นเพียงตัวอย่าง ไม่ใช่เส้นทาง VPN ที่สงวนไว้ และตัวเลขนำหน้าสำคัญเพราะไฟล์ที่เรียงลำดับภายหลังเป็นผู้ชนะ

ลำดับความสำคัญคือจุดที่ความคงทนแตกสลายอย่างเงียบ ๆ ตรวจทั้งตัวโหลดของการกระจายและ drop-in ของคุณเอง เพราะ procps sysctl --system อ่าน /etc/sysctl.conf ตอนท้ายด้วย ขณะที่ลำดับ sysctl.d ของ systemd เป็นลำดับที่ต่างออกไปทั้งหมด การกำหนดภายหลังสามารถใส่คีย์เดิมกลับได้ทันที ทำให้ไฟล์ของคุณถูกแต่ค่าที่มีผลจริงผิด อย่าเขียนทับไฟล์ผู้ดูแลระบบที่มีอยู่เพื่อชนะการโต้แย้งนั้น ให้หาเจ้าของแล้วแก้ที่นั่น

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

รู้ต้นทุนของสวิตช์ก่อนจะพลิกมัน

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

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

พิสูจน์ความคงทน แล้วทดสอบเส้นทางที่เหลือ

อ่านค่ากลับในสี่จังหวะ: ทันทีหลังการเปลี่ยนแปลง หลังอินเทอร์เฟซ VPN ปรากฏ หลังเชื่อมต่อใหม่ และหลังรีสตาร์ตที่วางแผนไว้ ค่าที่ย้อนกลับ ณ จุดใดจุดหนึ่งเหล่านี้มีเจ้าของคนที่สอง และการเขียนแบบครั้งเดียวอีกครั้งเพียงซ่อนมันไว้จนกว่าจะรีบูตครั้งต่อไป

การส่งต่อที่เปิดใช้ยังเหลือสามสิ่งให้ตรวจสอบ ไคลเอนต์ต้องการเส้นทางไปยังปลายทาง เกตเวย์ต้องการเส้นทางต่อไปพร้อมสิทธิ์ใช้งาน และปลายทางต้องการเส้นทางกลับมายังที่อยู่ทันเนลของไคลเอนต์ LAN ส่วนตัวที่เราเตอร์ไม่ได้ต้องการ NAT โดยอัตโนมัติ ดังนั้นอย่าเพิ่ม masquerading ก่อนจะรู้ว่าขาดข้อใดในสามข้อ และทดสอบจากไคลเอนต์ที่ตั้งใจ ไม่ใช่จากเกตเวย์เอง เพราะคำขอที่เกิดบนเกตเวย์ไม่เคยแตะเส้นทางส่งต่อที่คุณเพิ่งเปิดใช้ IPv6 มีนโยบายการส่งต่อและการเราเตอร์ของตัวเอง การทดสอบ IPv4 ที่ผ่านจึงไม่บอกอะไรเกี่ยวกับมัน

เก็บเส้นทาง drop-in เจ้าของเนมสเปซ และคำสั่งอ่านกลับไว้ด้วยกันใน runbook ใครก็ตามที่รับช่วงต่อไปควรอ่านค่าได้ เห็นว่าใครเป็นเจ้าของ และตัดสินใจได้ภายในหนึ่งนาทีว่าปัญหาคือความคงทนหรือเส้นทางที่เหลือ

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