ไคลเอนต์ VPN สองตัวสามารถออกผ่านที่อยู่ IPv4 สาธารณะที่แตกต่างกันสองที่ได้ และกฎที่ทำเช่นนั้นสั้นกว่าที่คนส่วนใหญ่คาดไว้ สิ่งที่ทำให้มันทำงานไม่ใช่ไวยากรณ์ของ iptables แต่เป็นสถานะของแพ็กเก็ตเมื่อไปถึงเชนขาออก: ที่อยู่ต้นทางตรงนั้นยังต้องแยกไคลเอนต์ออกจากกันได้ ถ้า masquerade ก่อนหน้ารวมทั้งสองไว้บนที่อยู่เดียวแล้ว กฎต่อไคลเอนต์ใดก็กู้ความแตกต่างนั้นคืนไม่ได้ ต้องตัดสินคำถามนี้ก่อนแล้วจึงเขียนการแปล

อัตลักษณ์ใดอยู่รอดไปถึงเกตเวย์

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

iptables -t nat -S POSTROUTING

อ่านรายการนั้นจากด้านบน กฎ masquerade ใกล้ด้านบนเขียนที่อยู่ต้นทางใหม่สำหรับทุกโฟลว์ที่ตรงกัน และรายการต่อไคลเอนต์ที่วางไว้หลังจากนั้นจะจับคู่กับที่อยู่ที่ไม่มีอยู่แล้ว เมื่ออุปกรณ์ LAN สองเครื่องแชร์อุโมงค์เดียวและมาถึงเป็นที่อยู่ภายในเดียว การออกแบบต้องเปลี่ยนก่อนไฟร์วอลล์: แยกช่วงต้นทางของทั้งสองไว้หรือให้แต่ละเครื่องมีที่อยู่ภายในของตัวเอง

ผูกการกำหนดที่อยู่ภายในกับไคลเอนต์ที่ผ่านการตรวจสอบแล้ว การให้ที่อยู่นั้นแก่อุปกรณ์อื่นก็มอบนโยบายขาออกไปด้วย และการแปลต้นทางไม่ใช่หลักฐานอัตลักษณ์โดยตัวมันเอง

การแปลไม่สามารถสร้างที่อยู่ขึ้นมาเอง

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

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

แทรกก่อน masquerade ทั่วไป

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

ip -4 route show default
iptables -t nat -L POSTROUTING -n -v --line-numbers

คำสั่งแรกบอกชื่ออินเทอร์เฟซที่แพ็กเก็ตไปอินเทอร์เน็ตออกจริง คำสั่งที่สองพิมพ์เชนพร้อมหมายเลขบรรทัด รายการ masquerade ทั่วไปคือบรรทัดที่ต้องอยู่เหนือ

iptables -t nat -I POSTROUTING 1 -s 10.88.4.20/32 -o ens3 -j SNAT --to-source 198.51.100.77
iptables -t nat -I POSTROUTING 1 -s 10.88.4.21/32 -o ens3 -j SNAT --to-source 198.51.100.78

สองกฎข้างต้นจับคู่ที่อยู่ภายในอย่างละหนึ่งที่ จำกัดการจับคู่ที่อินเทอร์เฟซขาออก และกำหนดต้นทางอย่างชัดเจน แทรกแทนที่จะต่อท้าย: ที่ตำแหน่ง 1 กฎเหล่านี้ถูกประเมินก่อนบรรทัด masquerade ลำดับระหว่างสองกฎไม่สำคัญเพราะต้นทางต่างกัน แทนที่ ens3 ด้วยสิ่งที่คำสั่ง route รายงาน และกันผู้จัดการไฟร์วอลล์อื่นออกจากฮุกเดียวกัน เพราะเครื่องมือสองตัวเขียนตารางเดียวคือสาเหตุปกติที่กฎที่ถูกต้องไม่มีผล

พิสูจน์ต้นทางด้วยโฟลว์ใหม่

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

conntrack -L -s 10.88.4.20 -p tcp --dport 443

อ่านทิศทางตอบกลับของรายการนั้น: ปลายทางคือที่อยู่ที่ปลายทางไกลมองเห็นเป็นต้นทาง เปรียบเทียบกับที่อยู่สาธารณะที่คุณตั้งใจ และถือรายการที่พกที่อยู่เก่าว่าเป็นหลักฐานของโฟลว์ที่เริ่มเร็วเกินไป ไม่ใช่กฎที่เสีย ขอให้ไคลเอนต์เปิดการเชื่อมต่อใหม่แล้วทำคำค้นซ้ำ การล้างตารางติดตามทั้งหมดเพื่อบังคับการทดสอบจะขัดจังหวะเซสชันอื่นทั้งหมดบนเกตเวย์

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

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