เหตุผลที่ชัดเจนดูเหมือนiptables -t nat -A PREROUTING -d 192.168.12.87 -p tcp --dport 80 -j DNAT --to-destination 192.168.12.77
จะไม่ทำงานเป็นวิธีการที่แพ็กเก็ตกลับจะถูกกำหนดเส้นทาง
คุณสามารถตั้งค่ากฎที่จะทำให้แพ็กเก็ตส่งไปที่ 192.168.12.87 เพียงแค่ NATted ไปที่ 192.168.12.77 แต่ 192.168.12.77 จะส่งคำตอบกลับไปยังลูกค้าโดยตรง คำตอบเหล่านั้นจะไม่ผ่านโฮสต์ที่กฎ iptables ของคุณกำลังทำ NAT ดังนั้นแพ็กเก็ตในทิศทางเดียวจะถูกแปล แต่แพ็กเก็ตในทิศทางอื่นจะไม่
มีสามวิธีในการแก้ปัญหานี้
- ในโฮสต์แรกไม่เพียง แต่ทำ DNAT แต่ยังทำ SNAT เพื่อให้ทราฟฟิกที่ส่งคืนจะถูกส่งกลับผ่านโฮสต์แรก กฎอาจมีลักษณะเหมือน
iptables -t NAT -A POSTROUTING -d 192.168.12.77 -p tcp --dport 80 -j SNAT --to-source 192.168.12.87
- รับแรงบันดาลใจจากการทำโหลดบาลานซ์ DSR และ DNAT แพ็กเก็ตที่เลเยอร์ Ethernet แทนที่จะเป็นที่เลเยอร์ IP โดยการแทนที่ MAC ปลายทางของแพ็กเก็ตด้วย MAC ของ 192.168.12.77 และส่งไปยังอีเธอร์เน็ตโดยไม่ต้องสัมผัสเลเยอร์ IP จากนั้น 192.168.12.77 อาจมี 192.168.12.87 ตั้งค่าบนอินเทอร์เฟซแบบจำลองและทำให้สามารถยุติการเชื่อมต่อ TCP ได้ กับเซิร์ฟเวอร์ IP ที่ลูกค้ารู้จัก
- ใช้โซลูชันไร้เดียงสา (แต่ไม่ทำงาน) บนโฮสต์แรก จากนั้นจัดการแพ็กเก็ตคืนบนโฮสต์ที่สองโดยทำ SNAT กับทราฟฟิกที่ส่งคืน กฎอาจมีลักษณะเช่น
iptables -t nat -A OUTPUT -p tcp --sport 80 -j SNAT --to-source 192.168.12.87
แต่ละวิธีแก้ปัญหาทั้งสามนั้นมีข้อเสียดังนั้นคุณต้องพิจารณาอย่างรอบคอบหากคุณต้องการส่งต่อโดยเฉพาะอย่างยิ่ง
- การใช้ SNAT จะสูญเสีย IP ของไคลเอ็นต์ดังนั้นโฮสต์หมายเลข 2 จะคิดว่าการเชื่อมต่อทั้งหมดมาจาก 192.168.12.87 นอกจากนี้คุณจะใช้แบนด์วิดท์ผ่านหมายเลขโฮสต์ 1 สำหรับแพ็กเก็ตตอบกลับทั้งหมดซึ่งจะใช้เส้นทางตรงมากขึ้นด้วยวิธีการอื่น
- วิธี DSR จะหยุดการสื่อสารอื่น ๆ ทั้งหมดระหว่างสองโหนด วิธี DSR นั้นจะเหมาะสมก็ต่อเมื่อที่อยู่เซิร์ฟเวอร์ไม่ใช่ IP หลักของโฮสต์ใด ๆ แต่ละโฮสต์ต้องมี IP หลักซึ่งไม่ใช่ IP DSR
- การใช้การติดตามการเชื่อมต่อกับโฮสต์หนึ่งเพื่อแปลในทิศทางเดียวและการติดตามการเชื่อมต่อกับโฮสต์อื่นเพื่อแปลในทิศทางอื่นนั้นน่าเกลียดและมีหลายวิธีที่อาจแตกหักได้ ตัวอย่างเช่นถ้าหมายเลขพอร์ตถูกแก้ไขโดย NAT บนโฮสต์ใด ๆ ไม่มีวิธีการสร้างใหม่ การติดตามการเชื่อมต่อนั้นจะทำงานได้อย่างถูกต้องหากแพ็กเก็ตแรกที่เห็นคือ SYN-ACK แทนที่จะเป็น ACK
ในสามวิธีที่ฉันคิดว่าวิธีแรกคือแนวทางที่มีโอกาสมากที่สุดที่จะทำงาน ดังนั้นหากคุณไม่จำเป็นต้องรู้ที่อยู่ IP ของไคลเอนต์นั่นคือที่ฉันอยากจะแนะนำ
คุณยังสามารถเลือกที่จะลืม NAT ทั้งหมดและไม่พยายามแก้ไขปัญหาในเลเยอร์ MAC หรือ IP คุณสามารถไปจนถึงเลเยอร์ HTTP และค้นหาวิธีแก้ไขที่นั่น ในกรณีนั้นการแก้ปัญหาที่คุณจะพบคือ HTTP proxy หากคุณติดตั้งพร็อกซี HTTP ใน 192.168.12.87 และกำหนดค่าอย่างเหมาะสมคุณสามารถส่งต่อคำขอไปที่ 192.168.12.77 และส่งต่อคำตอบกลับ นอกจากนี้ยังสามารถแทรกส่วนหัว X-Forwarded-For เพื่อรักษา IP ไคลเอ็นต์ดั้งเดิม เซิร์ฟเวอร์บน 192.168.12.77 ต้องถูกกำหนดค่าเพื่อเชื่อถือส่วนหัว X-Forwarded-For จาก 192.168.12.87