Score:3

Tcpdump แสดงพอร์ตการเปลี่ยนเส้นทางที่แตกต่างกันหลังจากเพิ่มกฎ REDIRECT ใน iptables

ธง us

ฉันกำลังพยายามส่งทราฟฟิกไคลเอ็นต์ไปยัง NodePort คลัสเตอร์ kubernetes ที่ฟังอยู่ 192.168.1.100.30000.

ความต้องการของลูกค้าในการร้องขอ 192.168.1.100.8000 ดังนั้นฉันจึงเพิ่มกฎ REDIRECT ต่อไปนี้ใน iptables:

iptables -t nat -I PREROUTING -p tcp --dst 192.168.1.100 --dport 8000 -j REDIRECT --to-port 30000

แล้วทำการม้วนผมให้เป็นลอน 192.168.1.100:8000 อย่างไรก็ตามใน tcpdump ฉันเห็นพอร์ตอื่น:

# tcpdump -i lo -nnvvv โฮสต์ 192.168.1.100 และพอร์ต 8000
tcpdump: กำลังฟัง lo, ประเภทลิงก์ EN10MB (Ethernet), ขนาดการดักจับ 262144 ไบต์
[อินเทอร์เฟซ: lo] 20:39:22.685968 IP (tos 0x0, ttl 64, id 20590, offset 0, flag [DF], proto TCP (6), ความยาว 40)
[อินเทอร์เฟซ: lo] 192.168.1.100.8000 > 192.168.1.100.49816: ค่าสถานะ [R.], cksum 0xacda (ถูกต้อง), seq 0, ack 3840205844, ชนะ 0, ความยาว 0
[อินเทอร์เฟซ: lo] 20:39:37.519256 IP (tos 0x0, ttl 64, id 34221, offset 0, flag [DF], proto TCP (6), ความยาว 40)

ฉันคาดหวังว่า tcpdump จะแสดงสิ่งที่ต้องการ

192.168.1.100.8000 > 192.168.1.100.30000

อย่างไรก็ตาม กำลังแสดงและทำให้เกิดข้อผิดพลาดการเชื่อมต่อถูกปฏิเสธ เนื่องจากไม่มีกระบวนการแสดงรายการอยู่ 192.168.1.100.49816.

192.168.1.100.8000 > 192.168.1.100.49816

ฉันใช้สภาพแวดล้อมการทดสอบ ดังนั้นฉันจึงไม่สามารถเข้าถึงอุปกรณ์ระยะไกลได้ นั่นคือเหตุผลที่ฉันใช้ ขด เพื่อทดสอบเส้นทาง REDIRECT ของ iptables

มีเหตุผลว่าทำไมการเพิ่มกฎ REDIRECT ทำให้ tcpdump เปลี่ยนเส้นทางการรับส่งข้อมูลไปยังพอร์ตอื่นนอกเหนือจากที่ระบุ

แก้ไข:

หลังจากที่ @A.B. คำแนะนำเพิ่มกฎ OUTPUT ต่อไปนี้:

iptables -t nat -I OUTPUT -d 192.168.1.100 -p tcp --dport 8000 -j REDIRECT --to-port 30000

และ curl ดำเนินการต่อไป จำนวนแพ็กเก็ตสำหรับเชน OUTPUT จะเพิ่มขึ้น (แพ็กเก็ตเชน PREROUTING REDIRECT ไม่เพิ่มขึ้น):

2 10 600 REDIRECT tcp -- * * 0.0.0.0/0 192.168.1.100 tcp dpt:8000 พอร์ต redir 30000

อย่างไรก็ตาม ได้รับข้อผิดพลาดต่อไปนี้:

# curl -vk https://192.168.1.100:8000/v1/api
* กำลังจะเชื่อมต่อ() กับพอร์ต 192.168.1.100 8000 (#0)
* ลอง 192.168.1.100...
* เชื่อมต่อกับพอร์ต 192.168.1.100 (192.168.1.100) 8000 (#0)
* เริ่มต้น NSS ด้วย certpath: sql:/etc/pki/nssdb
* ข้อผิดพลาด NSS -12263 (SSL_ERROR_RX_RECORD_TOO_LONG)
* SSL ได้รับบันทึกที่เกินความยาวสูงสุดที่อนุญาต
* ปิดการเชื่อมต่อ 0
curl: (35) SSL ได้รับบันทึกที่เกินความยาวสูงสุดที่อนุญาต

นอกจากนี้ ลองเพิ่มรีโมตซิสเต็มเน็ต คราวนี้จำนวนแพ็กเก็ต PREROUTING REDIRECT CHAIN ​​เพิ่มขึ้นหลังจากดำเนินการ รีโมตซิสเต็มขด ... (แต่ OUTPUT CHAIN ​​ไม่เพิ่มขึ้น):

2 34 2040 REDIRECT tcp -- * * 0.0.0.0/0 172.16.128.1 tcp dpt:8000 พอร์ต redir 30000

ข้อผิดพลาด:

# ip netns exec remotesystem curl -vk https://192.168.1.100:8000/v1/api
* กำลังจะเชื่อมต่อ() กับพอร์ต 192.168.1.100 8000 (#0)
* ลอง 192.168.1.100...
* หมดเวลาการเชื่อมต่อ
* ไม่สามารถเชื่อมต่อกับ 192.168.1.100:8000; หมดเวลาการเชื่อมต่อ
* ปิดการเชื่อมต่อ 0
curl: (7) ไม่สามารถเชื่อมต่อกับ 192.168.1.100:8000; หมดเวลาการเชื่อมต่อ
A.B avatar
cl flag
A.B
กฎของคุณใช้ไม่ได้กับการทดสอบจากโฮสต์ ทดสอบอีกครั้งจากระบบรีโมต ไม่ใช่จากระบบไปยังตัวเอง
tiger_groove avatar
us flag
ทำไมมันไม่ทำงาน คุณช่วยอธิบายได้ไหม มีวิธีทำให้มันทำงานจากโฮสต์ด้วยอินเทอร์เฟซย้อนกลับหรือไม่?
A.B avatar
cl flag
A.B
ก่อนอื่น โปรดเพิ่มบริบทให้กับคำถาม: คุณบอกว่าคุณกำลังทำอะไรอยู่ แต่ฉันอยากทราบว่าทำไมคุณถึงทำสิ่งนี้ก่อน (เพื่อแก้ปัญหาในทางปฏิบัติที่ทำให้คุณใช้สิ่งนี้)
tiger_groove avatar
us flag
เพิ่มในโพสต์
A.B avatar
cl flag
A.B
ไม่สามารถบอกเหตุผลสำหรับการใช้ระบบโลคัล (แทนที่จะเป็นรีโมต) ได้ แต่คำตอบจะไม่ต้องการในที่สุด
tiger_groove avatar
us flag
ฉันใช้สภาพแวดล้อมการทดสอบดังนั้นฉันจึงไม่สามารถเข้าถึงอุปกรณ์ระยะไกลได้ นั่นคือสาเหตุที่ฉันใช้ `curl` เพื่อทดสอบเส้นทาง REDIRECT ของ iptables คุณหมายความว่าอย่างไรคำตอบไม่ต้องการมันอยู่แล้ว?
jcaron avatar
co flag
โปรดทราบว่า `192.168.1.100.8000 > 192.168.1.100.49816` ไม่ได้หมายความว่า "เปลี่ยนเส้นทางจากพอร์ต 8000 ไปยังพอร์ต 49816" แต่หมายถึง "แพ็กเก็ตถูกส่งจากพอร์ต 8000 ไปยังพอร์ต 49816" ซึ่งเป็นเพียงพอร์ตที่ใช้ โดยไคลเอ็นต์ (ในเครื่อง) ของคุณ และแพ็กเก็ตคือ TCP RST ("การเชื่อมต่อถูกปฏิเสธ") คุณควรมีแพ็กเก็ตก่อนหน้าตั้งแต่ 49816 ถึง 8000 ก่อนหน้านั้น (คำขอเชื่อมต่อ TCP SYN) และการเชื่อมต่อถูกปฏิเสธไม่ใช่เพราะไม่มีอะไรฟังใน 49816 แต่ไม่มีอะไรฟังใน 8000
Score:4
ธง cl
A.B

เพื่อให้ชัดเจน: การทดสอบของ OP นั้นทำจากระบบ 192.168.1.100 ถึงตัวมันเอง ไม่ใช่จากระบบรีโมต และนั่นคือสาเหตุของปัญหา พอร์ตไม่ได้ถูกเปลี่ยนในกรณีนี้ เนื่องจากไม่มีกฎ NAT ที่ตรงกัน ในขณะที่พอร์ตจะตรงกันหากดำเนินการจากระบบรีโมต

แผนผังด้านล่างแสดงลำดับการดำเนินการในแพ็กเก็ต:

แพ็กเก็ตโฟลว์ใน Netfilter และ General Networking

เหตุผลคือวิธีการทำงานของ NAT บน Linux: iptables เห็นแพ็คเก็ตใน แนท ตารางสำหรับแพ็กเก็ตแรกของโฟลว์คอนแทร็กใหม่เท่านั้น (ซึ่งอยู่ในสถานะใหม่)

กฎนี้ใช้ได้ดีเมื่อมาจากระบบรีโมต ในกรณีนี้ แพ็กเก็ตแรกที่เห็นจะเป็นแพ็กเก็ตขาเข้า:

ไปยังพอร์ต 8000 -> AF_PACKET (tcpdump) -> conntrack -> nat/PREROUTING (iptables REDIRECT): ไปยังพอร์ต 30000
--> การตัดสินใจกำหนดเส้นทาง --> ... --> กระบวนการโลคัลที่ได้รับบนพอร์ต 30000

แพ็กเก็ตทั้งหมดต่อไปนี้ในโฟลว์เดียวกันจะมีการจัดการคอนโทรลโดยตรงกับการเปลี่ยนแปลงพอร์ต (หรือการกลับพอร์ตสำหรับการตอบกลับ) และจะข้ามกฎ iptables ใดๆ ใน แนท ตาราง (ตามที่เขียนไว้ในแผนผัง: แนท ตารางปรึกษาเท่านั้น ใหม่ เส้นสาย). ดังนั้น (ข้ามส่วนแพ็กเก็ตตอบกลับ) แพ็กเก็ตที่เข้ามาถัดไปจะได้รับสิ่งนี้แทน:

ไปยังพอร์ต 8000 -> AF_PACKET (tcpdump) -> conntrack: ไปยังพอร์ต 30000
--> การตัดสินใจกำหนดเส้นทาง --> ... --> กระบวนการโลคัลที่ได้รับบนพอร์ต 30000

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

ไคลเอนต์กระบวนการท้องถิ่น curl --> การตัดสินใจกำหนดเส้นทาง --> conntrack --> nat/OUTPUT (ไม่มีกฎที่นี่)
--> ตรวจสอบเส้นทางใหม่ --> AF_PACKET (tcpdump) --> ไปที่พอร์ต 8000

และตอนนี้แพ็กเก็ตนี้วนกลับมาที่ แท้จริง มันปรากฏขึ้นอีกครั้งเป็นแพ็กเก็ตซึ่งไม่ใช่แพ็กเก็ตแรกในการเชื่อมต่ออีกต่อไป ดังนั้นตามกรณีที่สองตามด้านบน: conntrack เพียงอย่างเดียวดูแล NAT และไม่เรียก แนท/PREROUTING. ยกเว้นว่าจะไม่ได้รับคำแนะนำในขั้นตอนก่อนที่จะทำ NAT:

ไปที่พอร์ต 8000 -> AF_PACKET (tcpdump) -> conntrack
--> การตัดสินใจกำหนดเส้นทาง --> ... -->ไม่กระบวนการท้องถิ่นที่ได้รับบนพอร์ต8000

เนื่องจากไม่มีสิ่งใดฟังอยู่บนพอร์ต 8000 ระบบปฏิบัติการจึงส่ง TCP RST กลับไป

สำหรับการทำงานบนระบบโลคัล a เปลี่ยนเส้นทาง จะต้องใส่กฎลงใน แนท/เอาท์พุต โซ่:

iptables -t nat -I OUTPUT -d 192.168.1.100 -p tcp --dport 8000 -j REDIRECT --to-port 30000

หมายเหตุเพิ่มเติม

  • หากกรณีนี้มีไว้สำหรับการใช้งานระยะไกล อย่าทดสอบจากระบบโลคัล: กฎที่ทดสอบผ่านจะไม่เหมือนกัน ทำให้ข้อสอบไม่สะท้อนความเป็นจริง

    เพียงใช้เนมสเปซเครือข่ายเพื่อสร้างระบบระยะไกลแบบพกพาในกรณีที่ไม่มีระบบอื่นให้ใช้งาน ตัวอย่างที่ควรทำงานกับระบบที่มี OP เท่านั้น แนท/PREROUTING กฎและการทำ ขด http://192.168.1.100/ (ซึ่งไม่ต้องการ DNS):

    ip netns เพิ่มระบบระยะไกล
    ip link เพิ่มชื่อ vethremote up type veth peer netns remotesystem name eth0
    ที่อยู่ IP เพิ่ม 192.0.2.1/24 dev vethremote
    ip -n ที่อยู่ระบบระยะไกลเพิ่ม 192.0.2.2/24 dev eth0
    ลิงก์ ip -n remotesystem ตั้งค่า eth0 ขึ้น
    เส้นทาง ip -n remotesystem เพิ่ม 192.168.1.100 ผ่าน 192.0.2.1
    ip netns exec remotesystem curl http://192.168.1.100:8000/
    
  • tcpdump และ แนท

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

    อย่าไว้ใจที่อยู่ / พอร์ตที่แสดงโดยสุ่มสี่สุ่มห้า tcpdump เมื่อทำ NAT: ขึ้นอยู่กับกรณีและตำแหน่งที่เกิดการจับภาพ

tiger_groove avatar
us flag
ขอบคุณมากสำหรับคำอธิบายโดยละเอียด ฉันยังมีปัญหาบางอย่างอยู่และได้ใส่ข้อมูลเพิ่มเติมในโพสต์ของฉันแล้ว ดูเหมือนจะไปได้ไกลกว่าเดิมแต่เหมือนมีบางอย่างขวางอยู่
A.B avatar
cl flag
A.B
ฉันสงสัยว่า 1/ กระบวนการในเครื่องไม่ใช่กระบวนการในเครื่อง แต่เป็นคอนเทนเนอร์/พ็อด (เนื่องจากเกี่ยวกับ Kubernetes) ดังนั้นจึงถูกกำหนดเส้นทางหรือกรองเพิ่มเติมด้วย (=> ไม่มีการเชื่อมต่อกับเนมสเปซสุทธิใหม่) ฉันใช้คำตอบตามกฎ iptables เดียวที่มีอยู่ในคำถามและไม่มีสิ่งใดที่ไม่สามารถใช้ได้ ยิ่งกว่านั้นฉันลองสิ่งที่ฉันนำเสนอสำเร็จก่อนที่ฉันจะทำคำตอบ 2/ ตามที่อธิบายไว้ ตัวนับในตาราง nat จะเพิ่มขึ้นสำหรับแพ็กเก็ตแรกเท่านั้น (ในสถานะใหม่): มันจะเพิ่มใน nat/OUTPUT หรือ nat/PREROUTING ไม่ใช่ทั้งสองอย่าง ตารางตัวกรองจะเห็นแพ็กเก็ตทั้งหมด 3/ คำถามเริ่มต้นไม่เกี่ยวกับ https
A.B avatar
cl flag
A.B
ฉันจะไม่เปลี่ยนคำตอบนี้อีก คุณต้องสร้างคำถามใหม่โดยให้บริบททั้งหมดล่วงหน้าและควรสร้างปัญหาที่ไม่ขึ้นอยู่กับ Q/A ปัจจุบันนี้ (ให้ใช้กฎ OUTPUT หรือกับระบบระยะไกลที่ทราบว่าเชื่อมต่อ)
tiger_groove avatar
us flag
ไม่เป็นไร ฉันจะสร้างคำถามใหม่ ขอขอบคุณความช่วยเหลือของคุณจริงๆ!
tiger_groove avatar
us flag
ฉันได้สร้างคำถามใหม่แล้ว โปรดแจ้งให้เราทราบหากคำถามนี้สมเหตุสมผลสำหรับคุณ https://serverfault.com/questions/1097511/iptables-redirect-to-kubernetes-nodeport-causes-request-to-hang
A.B avatar
cl flag
A.B
ปัญหาใหม่ของคุณเกี่ยวกับการขอ curl กับ API ของคุณ ไม่ใช่การหมดเวลา เพราะฉันแนะนำวิธีเปลี่ยนระบบรีโมตที่ไม่ได้ทำงานในการตั้งค่าเฉพาะของคุณ iptables ไม่ควรมีส่วนร่วมเลยในคำถามใหม่ ฉันขอโทษที่ไม่ได้อธิบายอย่างถูกต้องว่าควรเป็นคำถามใหม่อย่างไร
tiger_groove avatar
us flag
มันแปลกเพราะเมื่อฉันทำ curl แบบนี้ `ip netns exec remotesystem curl -vk https://192.168.1.100:30000/v1/flight` มันใช้งานได้ดีและฉันได้รับการตอบกลับเฉพาะเมื่อฉันเปลี่ยนเป็น `192.168 .1.100:8000` มันแฮงค์ ฉันไม่แน่ใจว่าทำไม แต่ดูเหมือนว่ามีบางอย่างไม่ชอบกฎ iptables ของ REDIRECT
A.B avatar
cl flag
A.B
ฉันกำลังพูดถึงกรณีที่มี SSL_ERROR_RX_RECORD_TOO_LONG ซึ่งไม่ค้าง

โพสต์คำตอบ

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