Score:0

"ให้" IP สาธารณะของอินเทอร์เฟซแก่โฮสต์อื่นที่มี IP ในเครื่อง

ธง in

ฉันมีเครื่อง (ใช้งาน openSUSE Leap 15.3) ที่มีที่อยู่ IP สาธารณะหลายแห่งซึ่งทำหน้าที่เป็นเกตเวย์สำหรับโฮสต์เพิ่มเติมสองสามแห่ง ฉันต้องทำให้ IP สาธารณะตัวใดตัวหนึ่งบนเกตเวย์ทำงานเหมือนกับว่าเป็นของหนึ่งในเครื่องที่เชื่อมต่ออยู่ (ทราฟฟิกถูกส่งต่ออย่างโปร่งใส)

ของฉัน iptables-บันทึก ขณะนี้เอาต์พุตเป็นดังนี้ (รวมกฎ Docker ที่ไม่เกี่ยวข้องบางข้อ แต่ส่วนที่ละเอียดอ่อนจะถูกแก้ไข):

# สร้างโดย iptables-save v1.8.7
*กรอง
: ยอมรับอินพุต [9747976:4527721149]
:ส่งต่อ ยอมรับ [12638879:4423560060]
: ยอมรับเอาต์พุต [8913992:2531503118]
:นักเทียบท่า - [0:0]
:DOCKER-ISOLATION-STAGE-1 - [0:0]
:DOCKER-ISOLATION-STAGE-2 - [0:0]
:นักเทียบท่า-ผู้ใช้ - [0:0]
-A ไปข้างหน้า -j นักเทียบท่า-ผู้ใช้
-A ส่งต่อ -j DOCKER-ISOLATION-STAGE-1
-A FORWARD -o docker0 -m conntrack --ctstate ที่เกี่ยวข้อง ก่อตั้ง -j ยอมรับ
-A ไปข้างหน้า -o นักเทียบท่า 0 -j นักเทียบท่า
-A ไปข้างหน้า -i docker0 ! -o นักเทียบท่า 0 -j ยอมรับ
-A ไปข้างหน้า -i docker0 -o docker0 -j ยอมรับ
-A DOCKER-ISOLATION-STAGE-1 -i docker0 ! -o docker0 -j DOCKER-ISOLATION-STAGE-2
-A DOCKER-ISOLATION-STAGE-1 -j ผลตอบแทน
-A DOCKER-ISOLATION-STAGE-2 -o docker0 -j DROP
-A DOCKER-ISOLATION-STAGE-2 -j ผลตอบแทน
-A นักเทียบท่า-ผู้ใช้ -j ผลตอบแทน
ให้สัญญา
# สมบูรณ์
# สร้างโดย iptables-save v1.8.7
*แนท
: ยอมรับ [480085:188100350]
: ยอมรับอินพุต [62951:4107383]
: ยอมรับเอาต์พุต [150:9857]
:หลังยอมรับ [0:0]
:นักเทียบท่า - [0:0]
-A PREROUTING -d <REDACTED_FORWARDING_IP>/32 -i eth0 -j DNAT --to-destination 10.125.0.2
-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
-A เอาท์พุท ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
-A โพสต์ -s 172.17.0.0/16 ! -o docker0 -j สวมหน้ากาก
-A โพสต์ -j MASQUERADE
-A นักเทียบท่า -i นักเทียบท่า 0 -j ผลตอบแทน
ให้สัญญา
# สมบูรณ์

ส่วนที่เกี่ยวข้องเท่านั้นเท่าที่ฉันรู้คือ:

-A PREROUTING -d <REDACTED_FORWARDING_IP>/32 -i eth0 -j DNAT --to-destination 10.125.0.2
-A โพสต์ -j MASQUERADE

สิ่งนี้ยังคงมีปัญหาหลายประการ:

  • เมื่อเครื่องภายในเริ่มการเชื่อมต่อขาออก IP จะถูก NATed เป็นที่อยู่หลักของเกตเวย์ ไม่ใช่ที่อยู่ที่ฉันพยายามให้
  • เมื่อได้รับการเชื่อมต่อ ดูเหมือนว่าจะมาจาก IP ภายในเครื่องของเกตเวย์ ไม่ใช่ IP ดั้งเดิม (ควรมีวิธีแก้ไขเนื่องจากเป็นเกตเวย์เริ่มต้น)
  • หากบริการกำลังฟังอยู่ 0.0.0.0 บนเกตเวย์ การเชื่อมต่อบนพอร์ตนั้นจะไม่ถูกเปลี่ยนเส้นทาง แต่จะไปที่บริการนั้น

ฉันพยายามรวมคำตอบสำหรับคำถามอื่น ๆ เช่น:

แต่เนื่องจากฉันขาดประสบการณ์ด้าน iptables อย่างมาก ฉันจึงไม่สามารถแก้ปัญหาของฉันได้ หรือแก้ไขเพียงบางส่วนเพื่อให้ผู้อื่นปรากฏขึ้น

ใครช่วยแนะนำกฎบางอย่างเพื่อให้บรรลุผลนี้ได้บ้าง หรืออาจมีวิธีการทำเช่นนี้โดยไม่ต้องใช้ iptables?

Nikita Kipriyanov avatar
za flag
โปรดแนบเอาต์พุต `iptables-save` ที่สมบูรณ์ลงใน quesiton ปัญหาทั้งหมดอาจเกี่ยวข้องกับการตั้งค่ากฎ SNAT ของคุณ อธิบายวิธีที่คุณสร้างการเชื่อมต่อที่แสดงปัญหา 2 และ 3 (ที่อยู่ต้นทางคืออะไร อินเทอร์เฟซขาเข้าคืออะไร) ฉันสงสัยว่าคุณกำลัง SNATing มากเกินไป ในขณะที่การจับคู่กฎ DNAT อาจมีข้อจำกัดน้อยกว่า
user9123 avatar
in flag
@NikitaKipriyanov ฉันแนบเอาต์พุต `iptables-save` ตามที่ร้องขอ การเชื่อมต่อทั้งหมดดำเนินไปแม้ว่าเกตเวย์จะแสดงปัญหาที่ 2 และ 3 พวกเขาไปถึงเกตเวย์ที่ `eth0:0` ซึ่งเป็นส่วนต่อประสานกับ IP ที่ฉันพยายามส่งต่อ ไม่ว่าในกรณีใด วิธีแก้ปัญหาของฉันน่าจะมีข้อบกพร่องอย่างมาก เนื่องจากฉันขาดประสบการณ์ดังกล่าวข้างต้น ดังนั้นจึงเป็นการดีที่สุดที่จะไม่ใช้คำตอบเป็นหลัก ส่วนใหญ่ฉันแนบมันเพื่อแสดงว่าฉันได้พยายามทำด้วยตัวเอง
Score:1
ธง za

เมื่อเครื่องภายในเริ่มการเชื่อมต่อขาออก IP ของเครื่องจะเป็น NAT เป็นที่อยู่หลักของเกตเวย์ ไม่ใช่ที่อยู่ที่ฉันพยายาม ให้มัน.

สิ่งนี้ควรแก้ไขด้วย:

iptables -t nat -I โพสต์ 1 -s 10.125.0.2 -o eth0 -j SNAT --to-source <FORWARD_IP>

มันถูกเพิ่มเข้าที่ด้านหน้า ดังนั้นมันจึงเริ่มทำงานก่อน ตรวจหาแพ็กเก็ตนั้นมาจากระบบนี้และแปลเป็น IP ที่ระบุ แทนที่จะเลือกที่อยู่จากอินเทอร์เฟซ

เมื่อได้รับการเชื่อมต่อ ดูเหมือนว่าพวกเขาจะมาจาก IP ภายในของเกตเวย์ ไม่ใช่ IP ดั้งเดิม (ควรมีวิธีแก้ไข เนื่องจากเป็นเกตเวย์เริ่มต้น)

ปัญหานี้เชื่อมโยงกับกฎ SNAT ต่อไปนี้:

iptables -t nat -A โพสต์ -j MASQUERADE

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

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

กรองด้วย อย่างน้อย ที่อยู่ต้นทาง (เช่น ที่ ที่อยู่สำหรับการแปลแหล่งที่มา):

iptables -t nat -A โพสต์ -s 10.125.0.0/24 -j MASQUERADE

หากคุณมีเครือข่ายส่วนตัวหลายเครือข่าย ให้เพิ่มกฎประเภทนี้

ฉันคิดว่าเป็นการดีกว่าที่จะสร้างกฎเฉพาะสำหรับอินเทอร์เฟซสาธารณะแต่ละรายการ ดังนั้นแพ็กเก็ตที่ส่งออกผ่านอินเทอร์เฟซส่วนตัวจึงไม่สามารถแปลแหล่งที่มาได้ไม่ว่าจะมีที่อยู่ต้นทางใดก็ตาม เช่น iptables -t nat -A โพสต์ -s 10.125.0.0/24 -o eth0 -j MASQUERADE และอื่น ๆ ด้วยวิธีนี้แพ็กเก็ตตั้งแต่ 10.x.x.x ถึง 172.x.x.x จะไม่ได้รับการแปลด้วย และบริการของคุณในทั้งสองเครือข่ายจะเห็น IP ของกันและกันโดยตรง โดยยังคงเหลือความเป็นไปได้ในการเลือกกรองข้อมูลเหล่านี้ในห่วงโซ่ตัวกรอง FORWARD

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

และสุดท้าย ฉันไม่เข้าใจประเด็นนี้อย่างถ่องแท้ถามในคอมเม้นแล้วคุณไม่ตอบ การเชื่อมต่อใด จากที่ไหน IP ต้นทางคืออะไร

การประมวลผล DNAT เกิดขึ้นก่อนการตัดสินใจกำหนดเส้นทาง นั่นคือเหตุผลที่เชนเรียกว่า "PREROUTING" ไม่เคยตรวจสอบว่ามีกระบวนการในเครื่องที่รับฟังพอร์ตนั้นหรือไม่ วิธีเดียวที่บริการในพื้นที่จะมีโอกาสตอบคือให้แพ็กเก็ตผ่าน INPUT chain สำหรับสิ่งนั้น รหัสเส้นทางจะต้องตัดสินใจว่าปลายทางนั้นไปยังเครื่องโลคัล ดังนั้นจึงต้องไม่มีการแปลอีเธอร์เลยหรือแปลเป็นที่อยู่บางแห่งที่ระบบนี้กำหนดไว้

ตามกฎปัจจุบัน แพ็กเก็ตที่ส่งจากเครือข่ายส่วนตัวไปยัง IP สาธารณะควร ไม่ รับการแปลเพราะพวกเขาไม่ได้เข้ามาทาง eth0. ดังนั้นพวกเขาจึงต้องให้บริการโดยบริการในท้องถิ่น แต่สิ่งนี้ไม่ได้ขึ้นอยู่กับว่าบริการในพื้นที่ทำงานอยู่หรือไม่ หากไม่ใช่คุณจะมี "การเชื่อมต่อถูกปฏิเสธ"

หากคุณต้องการแพ็กเก็ตจาก LAN ไปยัง <FORWARD_IP> เพื่อแปลตามกฎ DNAT เดียวกัน ให้วางแพ็กเก็ตนั้น -i eth0 จับคู่:

iptables -A PREROUTING -d <REDACTED_FORWARDING_IP>/32 -j DNAT --to-destination 10.125.0.2

อย่างไรก็ตาม ฉันไม่เห็นด้วยกับกฎกว้างๆ ในความคิดของฉัน จะดีกว่าหากมีกฎ DNAT ที่รัดกุมที่สุดเท่าที่จะเป็นไปได้ ดังนั้นคุณควรกรองตามโปรโตคอล (tcp/udp) และพอร์ตของบริการที่คุณใช้งานบน 10.125.0.2 หากเป็นเว็บเซิร์ฟเวอร์ ให้ส่งต่อเฉพาะ tcp/80 และ tcp/443 ดังนี้ iptables -A PREROUTING -d <REDACTED_FORWARDING_IP>/32 -p tcp -m หลายพอร์ต --dports 80,443 -j DNAT --to-destination 10.125.0.2.

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

user9123 avatar
in flag
ขอบคุณมากสำหรับคำตอบโดยละเอียดและขออภัยในความล่าช้า เพิ่งมีโอกาสลองวิธีแก้ปัญหาของคุณ ฉันยินดีที่จะบอกว่าปัญหาทั้งหมดได้รับการแก้ไขแล้วซึ่งทำให้ฉันมีความสุขมากเพราะสิ่งนี้ทำให้ฉันรำคาญอย่างมาก ในส่วนที่เกี่ยวกับส่วนที่ 3 หลังจากล้างกฎไฟร์วอลล์และตั้งค่าตามคำตอบของคุณแล้ว ดูเหมือนจะไม่เป็นเช่นนั้นอีกต่อไป ฉันก็สับสนเหมือนกันว่าทำไมถึงเป็นเช่นนั้น แต่บางทีความเหนื่อยล้าจากกฎไฟร์วอลล์ก็ทำให้ฉันดีขึ้น และการทดสอบของฉันก็ผิดพลาด ขอบคุณอีกครั้ง คุณได้ช่วยอย่างมาก :D

โพสต์คำตอบ

คนส่วนใหญ่ไม่เข้าใจว่าการถามคำถามมากมายจะปลดล็อกการเรียนรู้และปรับปรุงความสัมพันธ์ระหว่างบุคคล ตัวอย่างเช่น ในการศึกษาของ Alison แม้ว่าผู้คนจะจำได้อย่างแม่นยำว่ามีคำถามกี่ข้อที่ถูกถามในการสนทนา แต่พวกเขาไม่เข้าใจความเชื่อมโยงระหว่างคำถามและความชอบ จากการศึกษาทั้ง 4 เรื่องที่ผู้เข้าร่วมมีส่วนร่วมในการสนทนาด้วยตนเองหรืออ่านบันทึกการสนทนาของผู้อื่น ผู้คนมักไม่ตระหนักว่าการถามคำถามจะมีอิทธิพลหรือมีอิทธิพลต่อระดับมิตรภาพระหว่างผู้สนทนา