ทำไมบริการ Linux สาธารณะของคุณจึงตอบกลับผ่าน VPN
บริการภายในเครื่องสามารถรับบน eth0 และตอบกลับผ่าน VPN แบบอุโมงค์เต็มรูปแบบ กฎตามแหล่งที่มาพร้อมตาราง WAN ที่สมบูรณ์จะทำให้การตอบกลับเหล่านั้นอยู่บนเส้นทางเดิม
ไม่มีสิ่งใดในซ็อกเก็ตที่จดจำได้ว่าอินเทอร์เฟซใดพาคำขอมา ดังนั้นเส้นทางเริ่มต้นของ VPN แบบอุโมงค์เต็มรูปแบบอาจดักจับการตอบกลับที่เป็นของ WAN บริการไม่ได้เพิกเฉยต่ออินเทอร์เฟซขาเข้า Linux จะกำหนดเส้นทางการตอบกลับที่สร้างขึ้นภายในเครื่องตามปลายทางและนโยบายแหล่งที่มา กฎที่อิงแหล่งที่มาสามารถส่งเฉพาะการตอบกลับของบริการผ่านตาราง WAN ที่สมบูรณ์ โดยปล่อยให้การออกปกติอยู่บนอุโมงค์ พอร์ตยังคงเปิดอยู่ขณะที่การตอบกลับออกไปตามเส้นทางที่ผิด นั่นคือเหตุผลที่อาการดูเหมือนเกิดขึ้นเพียงด้านเดียว
ความเข้าใจผิด: การตอบกลับเป็นไปตามอินเทอร์เฟซที่มันมาถึง
ดูสมเหตุสมผลที่แพ็กเก็ตที่มาถึงบน eth0 ควรออกไปบน eth0 ตัวกรองแพ็กเก็ตแบบไร้สถานะเขียนแบบนั้นได้ และ tcpdump ฝั่งขาเข้าจะแสดงคำขอตรงตำแหน่งที่คาดไว้ การกำหนดเส้นทางไม่ได้ทำงานแบบนั้นสำหรับทราฟฟิกที่โฮสต์สร้างขึ้นเอง
เมื่อบริการยอมรับการเชื่อมต่อ การตอบกลับของมันคือแพ็กเก็ตใหม่ที่สร้างขึ้นภายในเครื่อง เคอร์เนลจะตรวจสอบกฎการกำหนดเส้นทางสำหรับปลายทางและแหล่งที่มาของการตอบกลับ และเส้นทางเริ่มต้นของ VPN ก็เป็นคำตอบที่ถูกต้องสมบูรณ์ ไม่มีสิ่งใดในซ็อกเก็ตที่จดจำได้ว่าอินเทอร์เฟซใดพาคำขอมา
นั่นคือเหตุผลที่อาการดูเหมือนเกิดขึ้นเพียงด้านเดียว คำขอเข้ามาแต่การตอบกลับหายไป นั่นก็เป็นเหตุผลที่การเพิ่มกฎไฟร์วอลล์สำหรับพอร์ตขาเข้าไม่เปลี่ยนแปลงอะไร แพ็กเก็ตไม่ได้ถูกบล็อกตอนเข้ามา แต่ถูกกำหนดเส้นทางไปที่อื่นตอนออกไป ติดตามการตอบกลับด้วยการค้นหาที่ระบุแหล่งที่มา แล้วเส้นทางอ้อมจะปรากฏให้เห็น
สิ่งที่เคอร์เนลกำหนดเส้นทางจริง: ที่อยู่ต้นทาง
จุดยึดที่คุณต้องใช้คือที่อยู่ภายในเครื่องที่บริการใช้สำหรับการตอบกลับ บนโฮสต์ที่มีที่อยู่ eth0 ตัวอย่าง 192.0.2.10/24 และเกตเวย์ 192.0.2.1 ที่อยู่นั้นมีอยู่บนอินเทอร์เฟซ บน VM ในคลาวด์ ที่อยู่สาธารณะอาจถูกแปลที่ต้นน้ำและหายไปจากเครื่องลูก ดังนั้นให้ใช้ที่อยู่ที่โฮสต์มีอยู่จริง
ตรวจสอบสถานะปัจจุบันก่อนที่จะจองหมายเลขตารางหรือลำดับความสำคัญของกฎ กฎนโยบายที่มีอยู่แล้วอาจบดบังกฎใหม่ และตารางเก่าที่มีหมายเลขเดียวกันอาจมีเส้นทางที่ไม่เกี่ยวข้องอยู่แล้ว:
ip -4 addr show dev eth0
ip -4 rule show
ip -4 route show table all
จากนั้นเลือกตารางตามแหล่งที่มา กฎนี้ตรงกับการตอบกลับที่มี 192.0.2.10 อยู่แล้ว ซึ่งก็คือทราฟฟิกที่สิ้นสุดภายในเครื่องที่คุณต้องการยกเว้น ทราฟฟิกที่ส่งต่อและแพ็กเก็ตจากที่อยู่ภายในเครื่องอื่นจะไม่ตรงกัน
สร้างตารางขากลับที่สมบูรณ์ ไม่ใช่เส้นทางเริ่มต้นเพียงครึ่งเดียว
ตารางที่มีเพียงเส้นทางเริ่มต้นไม่เพียงพอ เคอร์เนลยังต้องแก้ไขเกตเวย์ และการแก้ไขนั้นต้องใช้คำนำหน้าที่เชื่อมต่ออยู่ในตารางเดียวกัน ตารางที่ขาดคำนำหน้านั้นจะล้มเหลวในการแก้ไขเกตเวย์แม้ว่าเส้นทางเริ่มต้นดูถูกต้องก็ตาม เพิ่มทั้งสองอย่าง แล้วชี้กฎแหล่งที่มาไปยังตาราง:
ip -4 route add table 100 192.0.2.0/24 dev eth0 src 192.0.2.10
ip -4 route add table 100 default via 192.0.2.1 dev eth0
ip -4 rule add priority 1000 from 192.0.2.10/32 lookup 100
ใช้คำนำหน้าและเกตเวย์จริงแทนการคัดลอกตัวอย่าง อินเทอร์เฟซคลาวด์ที่กำหนดค่าเป็น /32 พร้อมเกตเวย์บนลิงก์ต้องใช้เส้นทางที่เชื่อมต่อต่างออกไป และตารางที่สร้างจากคำนำหน้าที่ผิดจะล้มเหลวที่ฮอปแรก แอตทริบิวต์ src ระบุแหล่งที่มาที่ต้องการสำหรับเส้นทางนั้น มันไม่ได้แทนที่กฎแหล่งที่มา
ลำดับก็สำคัญเช่นกัน กฎที่กว้างและมีหมายเลขลำดับความสำคัญต่ำกว่าจะถูกประเมินก่อน ดังนั้นกฎแหล่งที่มาต้องไปถึงก่อนกฎใด ๆ ที่จะส่งทราฟฟิกนี้กลับไปยังตารางหลัก ตรวจสอบลำดับความสำคัญด้วย ip rule show หลังจากเพิ่มแล้ว ไม่ใช่แค่ตอนบูต
ตรวจสอบด้วยการค้นหาที่ระบุแหล่งที่มา
ขอให้เคอร์เนลกำหนดเส้นทางไปยังปลายทางทดสอบจากที่อยู่ของบริการ คำตอบควรระบุ eth0 และเกตเวย์ WAN ไม่ใช่อุโมงค์:
ip -4 route get 198.51.100.25 from 192.0.2.10
จากนั้นสร้างการเชื่อมต่อที่ได้รับอนุญาตใหม่และสังเกตทั้งสองทิศทาง การค้นหาที่เลือกตารางถูกต้องแต่การเชื่อมต่อจริงยังล้มเหลวชี้ไปที่การกรองเส้นทางย้อนกลับหรือกฎไฟร์วอลล์ ไม่ใช่ตาราง ตรวจสอบมาตรการเหล่านั้นก่อนปิดใช้งานอะไรในระดับสากล
วางเส้นทางสุดท้ายและกฎไว้ใต้ตัวจัดการเครือข่ายที่เป็นเจ้าของอินเทอร์เฟซ การเปลี่ยนที่อยู่ การต่ออายุ DHCP และการเชื่อมต่อ VPN ใหม่ล้วนเขียนสถานะเคอร์เนลใหม่ และกฎที่เพิ่มด้วยมือจะหายไปหรือชี้ไปยังเกตเวย์ที่ล้าสมัยหลังเหตุการณ์ถัดไป
ข้อยกเว้นนี้สิ้นสุดตรงไหน
กฎนี้ยกเว้นทราฟฟิกที่สิ้นสุดภายในเครื่องจากที่อยู่ต้นทางหนึ่งแห่ง มันไม่ครอบคลุมพอร์ตที่ Docker เผยแพร่ DNAT หรือบริการที่ส่งต่อผ่านโฮสต์ เพราะแพ็กเก็ตเหล่านั้นถูกกำหนดเส้นทางเป็นทราฟฟิกที่ส่งต่อและไม่เคยพาแหล่งที่มาภายในเครื่องของโฮสต์ในลักษณะเดียวกัน การออกแบบเช่นนั้นมักต้องใช้เครื่องหมายที่ตั้งไว้ตอนขาเข้าและกฎที่ตรงกับเครื่องหมายนั้น
มันไม่ได้ทำให้ที่อยู่สาธารณะของโฮสต์ปรากฏบนอินเทอร์เฟซด้วย เมื่อ NAT ต้นน้ำเป็นเจ้าของที่อยู่นั้น การตอบกลับยังต้องออกไปตามเส้นทางที่ NAT นั้นคาดหวัง นั่นคือเหตุผลที่ตาราง WAN ต้องสะท้อนเกตเวย์และคำนำหน้าต้นฉบับ ไม่ใช่ช่วงสาธารณะที่เดาขึ้นมา
เก็บข้อยกเว้นไว้เป็นเอกสารพร้อมหมายเลขตาราง ลำดับความสำคัญของกฎ และที่อยู่ต้นทางที่แน่นอน การเปลี่ยนแปลงครั้งถัดไปใน VPN หรืออินเทอร์เฟซอาจทำให้มันเสียหายอย่างเงียบ ๆ และบันทึกที่ระบุค่าทั้งสามจะตรวจสอบได้เร็วกว่าการค้นพบอาการซ้ำจากรายงานของลูกค้า
หากบริการยังตอบกลับตามเส้นทางที่ผิดหลังจากการค้นหาที่ระบุแหล่งที่มาสำเร็จ ให้เปรียบเทียบที่อยู่ต้นทางของซ็อกเก็ตจริงกับที่อยู่ในกฎ บริการที่ผูกกับที่อยู่ไวลด์การ์ดอาจเลือกแหล่งที่มาที่ต่างจากที่อยู่ที่คุณทดสอบ และความไม่ตรงกันนั้นคือช่องว่างที่เหลืออยู่