DNAT ในคอนเทนเนอร์ VPN: การส่งต่อ ไม่ใช่ INPUT
หลัง DNAT คำขอไปยังที่อยู่ของทันเนลกลายเป็นทราฟฟิกที่ถูกส่งต่อ จำกัดขอบเขตกฎการส่งต่อ อ่านเชนของ Docker และเลือกเส้นทางกลับอย่างตั้งใจ
คำขอมาถึงโดยมีที่อยู่ IP ของทันเนลและออกจากคอนเทนเนอร์เดิมโดยมีที่อยู่ของบริการข้างเคียง ระหว่างสองช่วงเวลานั้น DNAT เขียนปลายทางใหม่ และแพ็กเก็ตก็ไม่ใช่ข้อมูลขาเข้าของคอนเทนเนอร์ VPN อีกต่อไป ตอนนี้มันคือทราฟฟิกที่ถูกส่งต่อ ซึ่งตัดสินด้วยกฎอีกชุดหนึ่ง การเปลี่ยนแปลงนี้อธิบายว่าทำไมกฎไฟร์วอลล์ที่ดูถูกต้องสำหรับที่อยู่ทันเนลจึงไม่มีผลกับการเชื่อมต่อที่แปลแล้ว
ติดตามแพ็กเก็ตหลังการแปล
ใช้พูลไคลเอนต์ 10.90.0.0/24 และที่อยู่ทันเนล 10.90.0.1 คอนเทนเนอร์สองตัวอยู่บนบริดจ์เดียว: 192.0.2.2 รัน VPN และ 192.0.2.3 รันแอปพลิเคชัน ไคลเอนต์เชื่อมต่อกับ 10.90.0.1:8080 และกฎ DNAT ในเนมสเปซของคอนเทนเนอร์ VPN เขียนที่อยู่นั้นใหม่เป็นที่อยู่และพอร์ตจริงของแอปพลิเคชัน จากนั้นเส้นทางหนึ่งส่งแพ็กเก็ตข้ามบริดจ์ ที่อยู่เหล่านี้เป็นเพียงตัวอย่าง ไม่ใช่สูตรการติดตั้ง
พอร์ตที่แอปพลิเคชันฟังจริงอาจแตกต่างจากพอร์ตใด ๆ ที่เผยแพร่บนโฮสต์ อ่านตัวรับฟังภายในคอนเทนเนอร์แทนที่จะสมมติว่าตัวเลขทั้งสองตรงกัน
สิทธิ์เป็นของเส้นทางการส่งต่อ
คอนเทนเนอร์ VPN ต้องการการส่งต่อ IP และการตัดสินใจส่งต่อที่จำกัดเฉพาะพูลไคลเอนต์ ที่อยู่ของแอปพลิเคชัน และพอร์ตที่ตั้งใจไว้ การตอบกลับที่สร้างแล้วต้องมีสิทธิ์ของตัวเอง กฎที่ตรงกับที่อยู่ทันเนลเดิมจะไม่ตรงหลัง DNAT เพราะปลายทางเปลี่ยนไปแล้ว สิทธิ์ INPUT เป็นตะขอที่ผิดสำหรับทราฟฟิกที่ไม่ได้ส่งถึงโฮสต์นี้อีกต่อไป
รักษาขอบเขตให้แคบ: ช่วงต้นทางหนึ่ง ปลายทางหนึ่ง และบริการหนึ่ง กฎการส่งต่อที่ผ่อนปรนเขียนง่ายกว่าและป้องกันตัวได้ยากกว่ามากในภายหลัง
docker exec vpn-container ip route get 192.0.2.3
docker exec vpn-container iptables -t nat -S
docker exec vpn-container iptables -S FORWARD
เชนของ Docker ไม่ใช่เชนของคอนเทนเนอร์คุณ
กฎภายในเนมสเปซของคอนเทนเนอร์ไม่ใช่กฎของโฮสต์ Docker เมื่อทราฟฟิกข้ามจากอินเทอร์เฟซของทันเนลไปยังบริดจ์ ไฟร์วอลล์ของบริดจ์บนโฮสต์อาจตัดสินใจต่างออกไป ด้วยแบ็กเอนด์ iptables ของ Docker เชนการส่งต่อที่อธิบายไว้ในเอกสารและจุดจับคู่หลัง DNAT คือที่ที่การตัดสินใจนั้นปรากฏ
เอกสารอ้างอิงไฟร์วอลล์ของ Docker อธิบายเชนเหล่านั้นและการจับคู่หลัง DNAT อย่าแก้ไขการยอมรับที่ขาดหายด้วยการปิดการจัดการไฟร์วอลล์ของ Docker หรือทำให้ทุกเชนผ่อนปรน เพราะนั่นจะลบขอบเขตที่คุณพยายามใช้
ทำให้เส้นทางกลับเป็นการเลือกที่ตั้งใจ
หากเก็บที่อยู่ต้นทางไว้ แอปพลิเคชันจะเห็น 10.90.0.x และ ต้องส่งการตอบกลับกลับผ่านคอนเทนเนอร์ VPN. มิฉะนั้นเกตเวย์ Docker ปกติของมันจะส่งไปยังโฮสต์ซึ่งไม่ได้เป็นเจ้าของทันเนล ทางเลือกคือการแปลต้นทางแบบแคบที่คอนเทนเนอร์ VPN ซึ่งทำให้การตอบกลับง่ายขึ้นแต่ซ่อนไคลเอนต์จากแอปพลิเคชัน เลือกอย่างตั้งใจและจดไว้ว่าเลือกแบบไหน
ทดสอบการเชื่อมต่อที่ได้รับอนุญาตใหม่จากไคลเอนต์ทั่วไป แล้วยืนยันว่าพอร์ตที่ไม่เกี่ยวข้องยังปิดอยู่ เมื่อแพ็กเก็ตหายไป ให้ตรวจสอบเนมสเปซของ VPN เนมสเปซของแอปพลิเคชัน และล็อกของแอปพลิเคชันเอง ping ไปยังเกตเวย์ของบริดจ์ไม่ใช่การทดสอบการยอมรับสำหรับบริการ
เก็บกฎไว้ในการกำหนดค่าเริ่มต้นที่รองรับของคอนเทนเนอร์ เพราะการแก้ไขแบบอินเทอร์แอกทีฟจะหายไปเมื่อสร้างใหม่ การเผยแพร่พอร์ตบนโฮสต์เป็นเส้นทางการเปิดเผยอีกแบบ และไม่จำเป็นเพียงเพราะบริการเข้าถึงได้ผ่านทันเนล