Score:0

iptables NETMAP ไม่สามารถปรับซอร์สแอดเดรสของแพ็กเก็ต UDP แบบหลายผู้รับได้อย่างน่าเชื่อถือ

ธง us

ในกรณีการใช้งานแบบฝังตัว/IoT ฉันมีโฮสต์การจัดการที่ใช้ Linux ซึ่งจำเป็นต้องสามารถพูดคุยกับหลายเครือข่ายที่แต่ละเครือข่ายใช้ชุดที่อยู่ IP แบบคงที่ร่วมกัน

สิ่งนี้ใช้งานได้ดีเป็นส่วนใหญ่ รวมถึงการรับส่งข้อมูลแบบหลายผู้รับ UDP ด้วย:

  • ลิงค์เครือข่ายสำหรับเครือข่ายฝังตัวแต่ละเครือข่าย (เรียกว่า eth1, eth2ฯลฯ)
  • เนมสเปซเครือข่าย Linux แยกต่างหากสำหรับเครือข่ายฝังตัวแต่ละเครือข่าย (เรียกว่า ns1, ns2ฯลฯ)
  • เพียร์ลิงก์ระหว่างเนมสเปซแต่ละเครือข่ายและรูทเนมสเปซ (เรียกว่า เพื่อน1, เพียร์2ฯลฯ จากด้านเนมสเปซเครือข่ายและ veth1, veth2ฯลฯ จากด้านเนมสเปซรูท)
  • กฎ NETMAP ของ iptables ในแต่ละเนมสเปซเพื่อแมปซับเน็ต IP แบบคงที่ที่ขัดแย้งกัน (เรียกมันว่า 192.168.0.x) ไปยังชุดเครือข่ายย่อย IP แบบคงที่ที่ไม่ขัดแย้งกัน (เรียกว่า 192.168.1.x, 192.168.2.xฯลฯ)
  • หนึ่ง หัวเราะเยาะ อินสแตนซ์ภายในเนมสเปซแต่ละเครือข่ายเพื่อส่งต่อการลงทะเบียนกลุ่มแบบหลายผู้รับ
  • ที่อยู่ IP แยกต่างหากในซับเน็ตที่แตกต่างกัน (ไม่ใช่ NAT) สำหรับด้านเนมสเปซรูทของลิงก์เพียร์เพื่อแก้ไขหัวข้อของคำถามนี้ (เรียกว่า 192.168.(x+100).1)

หากต้องการลองนึกภาพกระแสการจราจร:

[|root namespace|::veth1] <-> [peer1::(namespace ns1)::eth1] <-> เครือข่ายฝังตัว
[| |::veth2] <-> [peer2::(namespace ns2)::eth2] <-> เครือข่ายฝังตัว
...ฯลฯ...

ns1 ตัวอย่างกฎ NETMAP สำหรับซับเน็ต IP แบบคงที่:

sudo -n ip netns exec ns1 iptables -t nat -A PREROUTING -d 192.168.1.0/24 -i peer1 -j NETMAP --to 192.168.0.0/24
sudo -n ip netns exec ns1 iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -o peer1 -j NETMAP --to 192.168.1.0/24

ns1 ตัวอย่าง หัวเราะเยาะ กฎการกำหนดค่าสำหรับกลุ่มมัลติคาสต์ที่รองรับ:

mgroup จากกลุ่ม eth1 239.255.60.60
mgroup จากกลุ่ม peer1 239.255.60.60
mroute จากกลุ่ม eth1 239.255.60.60 ไปยัง peer1
mroute จากแหล่ง peer1 192.168.101.1 กลุ่ม 239.255.60.60 ถึง eth1

หัวข้อที่แท้จริงของคำถามนี้คือมีความผิดพลาดแปลก ๆ ใน เน็ตแมป การปรับ IP ต้นทางที่ฉันไม่สามารถอธิบายได้ ให้แก้ไขเท่านั้น

พฤติกรรมที่คาดหวังของฉัน:

  • การสมัคร UDP แบบหลายผู้รับภายในเนมสเปซเครือข่ายจะเห็น pre-NETMAP ที่ไม่ได้แก้ไข 192.168.0.x ที่อยู่ต้นทาง
  • การสมัครสมาชิก UDP แบบหลายผู้รับภายในรูทเนมสเปซจะเห็น post-NETMAP ที่แก้ไขแล้ว 192.168.1.x ที่อยู่ต้นทาง

นั่นไม่ใช่สิ่งที่เกิดขึ้นแม้ว่า ผู้สมัครสมาชิกในเนมสเปซทั้งสองจะเห็นที่อยู่ต้นทางก่อน NETMAP 192.168.0.x หรือมิฉะนั้นจะเห็นที่อยู่หลัง NETMAP 192.168.1.x

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

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

เป้าหมายของการถามคำถามคือการช่วยให้ทราบว่าข้อใดต่อไปนี้ใช้ได้:

  • สิ่งนี้ไม่คาดว่าจะทำงาน การชดเชยที่เลเยอร์แอปพลิเคชันเป็นสิ่งที่ดีที่สุดที่สามารถทำได้ (ซึ่งดูเหมือนว่าไม่น่าเป็นไปได้เนื่องจากการใช้เนมสเปซเครือข่ายในสภาพแวดล้อมคอนเทนเนอร์ของ Linux)
  • มีอย่างอื่นที่ต้องกำหนดค่า (หรือไม่ได้กำหนดค่า) ในเคอร์เนล iptables หรือ smcroute เพื่อป้องกันไม่ให้พฤติกรรมที่ไม่เหมาะสมเกิดขึ้น

(หมายเหตุ: คำถามนี้เป็นคำถามที่ลึกลับซับซ้อนมาก ดังนั้นฉันจึงสงสัยว่า Network Engineering อาจเหมาะสมกว่าหรือไม่ แต่ https://networkengineering.stackexchange.com/questions/64744/linux-local-multicast-egress-follows-forward-chain-when-smcroute-is-active ทำให้ชัดเจนว่ามีไว้สำหรับทำงานกับเราเตอร์เชิงพาณิชย์ ฯลฯ ไม่ใช่สำหรับการกำหนดค่าเนมสเปซเครือข่าย Linux ฉันไม่ชัดเจนเกี่ยวกับขอบเขตระหว่าง Server Fault และ Unix & Linux stack exchange เมื่อพูดถึงการกำหนดค่าเซิร์ฟเวอร์ Linux)

Score:1
ธง tr

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

มีรายงานปัญหาที่คล้ายกันมากใน ตัวติดตามปัญหา SMCRouteสิ่งเดียวที่แตกต่างจากคุณคือพวกเขาไม่ได้ใช้ 1:1 NAT กับ netmap (ยัง)

ฉันได้ตีขึ้น กรณีทดสอบ เพื่อเตรียมพร้อมสำหรับรุ่นต่อไป (v2.5) ฉันทำการทดสอบทั้งหมดภายในเครื่องและใน GitHub Actions (Azure cloud) โดยใช้:

ทดสอบซีดี/
เลิกแชร์ -mrun ./multi.sh

การทดสอบมีเราเตอร์สองตัวแยกกัน (R1 และ R2) ในเนมสเปซเครือข่ายเฉพาะ โดยมีส่วน LAN ที่ใช้ร่วมกันระหว่างกัน (192.168.0.0/24) ด้านหลังเราเตอร์แต่ละตัวคือ LAN ส่วนตัว (10.0.0.0/24) ซึ่งเหมือนกันสำหรับเราเตอร์ทั้งสอง อินเทอร์เฟซพิเศษ (จำลอง) eth1 ใช้เพื่อกำหนดเส้นทางมัลติคาสต์จากไปยัง LAN ที่ใช้ร่วมกัน (eth0) กฎ NETMAP ใช้โซ่ PREROUTING และ POSTROUTING แปล R1 private LAN เป็น 192.168.10.0/24 และ R2 private LAN เป็น 192.168.20.0/24 ดังที่คุณเห็นด้านล่าง เส้นทางมัลติคาสต์ที่ติดตั้งในเคอร์เนลใช้แอดเดรสแบบ 1:1 ที่แมป (ส่วนกลาง)

>> ตัวปล่อยสตาร์ท ...                                                           
R1[2811708]: ข้อมูลมัลติคาสต์ใหม่จาก 192.168.10.1 ไปยังกลุ่ม 225.1.2.3 บน VIF 1
R1[2811708]: เพิ่ม 192.168.10.1 -> 225.1.2.3 จาก VIF 1
R2[2811709]: ข้อมูลมัลติคาสต์ใหม่จาก 192.168.10.1 ไปยังกลุ่ม 225.1.2.3 บน VIF 0
R2[2811709]: เพิ่ม 192.168.10.1 -> 225.1.2.3 จาก VIF 0
R2[2811709]: ข้อมูลมัลติคาสต์ใหม่จาก 192.168.20.1 ไปยังกลุ่ม 225.1.2.3 บน VIF 1
R2[2811709]: เพิ่ม 192.168.20.1 -> 225.1.2.3 จาก VIF 1
R1[2811708]: ข้อมูลมัลติคาสต์ใหม่จาก 192.168.20.1 ไปยังกลุ่ม 225.1.2.3 บน VIF 0
R1[2811708]: เพิ่ม 192.168.20.1 -> 225.1.2.3 จาก VIF 0
>> เส้นทางมัลติคาสต์ R1 และ 1:1 NAT ...                                             
(192.168.10.1,225.1.2.3) Iif: eth1 Oifs: eth0 State: แก้ไขแล้ว
(192.168.20.1,225.1.2.3) Iif: eth0 Oifs: eth1 State: แก้ไขแล้ว
CHAIN ​​PREROUTING (นโยบายยอมรับ 5 แพ็คเก็ต, 244 ไบต์)
 pkts bytes target prot เลือกใช้ปลายทางต้นทาง         
    0 0 NETMAP ทั้งหมด -- ทุกที่ 192.168.10.0/24 ถึง:10.0.0.0/24

Chain INPUT (นโยบายยอมรับ 1 แพ็กเก็ต 84 ไบต์)
 pkts bytes target prot เลือกใช้ปลายทางต้นทาง         

Chain OUTPUT (นโยบายยอมรับ 4 แพ็กเก็ต 248 ไบต์)
 pkts bytes target prot เลือกใช้ปลายทางต้นทาง         

Chain POSTROUTING (นโยบายยอมรับ 2 แพ็กเก็ต 124 ไบต์)
 pkts bytes target prot เลือกใช้ปลายทางต้นทาง         
    2 124 NETMAP ทั้งหมด -- ใดๆ 10.0.0.0/24 ใดก็ได้ไปที่: 192.168.10.0/24
>> เส้นทางมัลติคาสต์ R2 และ 1:1 NAT ...                                             
(192.168.10.1,225.1.2.3) Iif: eth0 Oifs: eth1 State: แก้ไขแล้ว
(192.168.20.1,225.1.2.3) Iif: eth1 Oifs: eth0 State: แก้ไขแล้ว
CHAIN ​​PREROUTING (นโยบายยอมรับ 4 แพ็คเก็ต, 204 ไบต์)
 pkts bytes target prot เลือกใช้ปลายทางต้นทาง         
    1 84 NETMAP ทั้งหมด -- อะไรก็ได้ 192.168.20.0/24 ถึง:10.0.0.0/24

Chain INPUT (นโยบายยอมรับ 2 แพ็คเก็ต, 168 ไบต์)
 pkts bytes target prot เลือกใช้ปลายทางต้นทาง         

Chain OUTPUT (นโยบายยอมรับ 3 แพ็กเก็ต 164 ไบต์)
 pkts bytes target prot เลือกใช้ปลายทางต้นทาง         

Chain POSTROUTING (นโยบายยอมรับ 1 แพ็กเก็ต 40 ไบต์)
 pkts bytes target prot เลือกใช้ปลายทางต้นทาง         
    2 124 NETMAP ทั้งหมด -- ใดๆ 10.0.0.0/24 ที่ใดก็ได้ถึง:192.168.20.0/24
>>วิเคราะห์...                                                                   
    1 0.000000000 0.000000000 192.168.10.1 â 225.1.2.3 ICMP 98 คำขอ Echo (ping) id=0xe769, seq=1/256, ttl=2
    2 1.000105261 1.000105261 192.168.10.1 â 225.1.2.3 ICMP 98 คำขอ Echo (ping) id=0xe769, seq=2/512, ttl=2
    3 1.000957268 0.000852007 192.168.20.1 â 225.1.2.3 ICMP 98 คำขอ Echo (ping) id=0xe76b, seq=1/256, ttl=2
    4 2.024216212 1.023258944 192.168.10.1 â 225.1.2.3 ICMP 98 คำขอ Echo (ping) id=0xe769, seq=3/768, ttl=2
    5 2.024216229 0.000000017 192.168.20.1 â 225.1.2.3 ICMP 98 คำขอ Echo (ping) id=0xe76b, seq=2/512, ttl=2
    6 3.048426868 1.024210639 192.168.10.1 â 225.1.2.3 ICMP 98 คำขอ Echo (ping) id=0xe769, seq=4/1024, ttl=2
    7 3.048426842 -0.000000026 192.168.20.1 â 225.1.2.3 ICMP 98 คำขอ Echo (ping) id=0xe76b, seq=3/768, ttl=2
    8 4.072270331 1.023843489 192.168.10.1 â 225.1.2.3 ICMP 98 คำขอ Echo (ping) id=0xe769, seq=5/1280, ttl=2
    9 4.072270458 0.000000127 192.168.20.1 â 225.1.2.3 ICMP 98 คำขอ Echo (ping) id=0xe76b, seq=4/1024, ttl=2
   10 5.096430449 1.024159991 192.168.20.1 â 225.1.2.3 ICMP 98 คำขอ Echo (ping) id=0xe76b, seq=5/1280, ttl=2
 => 10 สำหรับกลุ่ม ff04::114 คาดว่า >= 8

อาจอ่านยากสักหน่อย คุณอาจต้องศึกษากรณีทดสอบเพื่อดูรายละเอียด อย่างไรก็ตาม ฉันได้รับผลลัพธ์ที่สอดคล้องกันในการแปล ซึ่ง btw เป็นความรับผิดชอบของ Linux ไม่ใช่ SMCRoute ดังนั้นคุณอาจมีข้อบกพร่องของเคอร์เนลหรือบางอย่าง เวิร์กสเตชันส่วนบุคคลอาจมี Linux Mint พร้อมเคอร์เนล 5.11.0 และเซิร์ฟเวอร์แบ็กเอนด์สำหรับ GitHub Actions เรียกใช้ Ubuntu 20.04 LTS, เคอร์เนล 5.8.0, เคอร์เนล distro ที่ได้รับการแพตช์ค่อนข้างดี แต่อาจเป็นพื้นฐานในการเริ่มต้น

us flag
ขอขอบคุณ! การรู้ว่า *ควร* ใช้งานได้ อย่างน้อยทำให้ฉันรู้ว่าฉันไม่ได้ทำให้การกำหนดค่าเสียหายทั้งหมด :) พฤติกรรมที่ไม่เหมาะสมนั้นถูกระบุใน Debian 9 ซึ่งค่อนข้างโบราณ ณ จุดนี้ ฉันควรมีระบบที่มีเคอร์เนล 5.14.x เพื่อทดสอบในอนาคตอันใกล้ แต่ฉันจะสแกนบันทึกการเปลี่ยนแปลงเคอร์เนล 4.9 LTS เพื่อดูว่ามีรายงานข้อผิดพลาดที่เกี่ยวข้องหรือไม่
us flag
เรียกดูผ่าน https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/log/?qt=grep&q=multicast ฉันเริ่มสงสัยว่ามีบางสิ่งที่ฉันละเว้นจากคำอธิบายสถานการณ์หรือไม่ การพยายามอธิบายให้ง่ายขึ้นนั้นสำคัญมากในการกระตุ้นให้เกิดปัญหา: เครือข่ายแบบฝังไม่ได้แยกจากกัน แต่เป็น VLAN ที่แตกต่างกันบนการเชื่อมต่อหลัก VLAN ที่ติดแท็ก นั่นทำให้การจัดการมัลติคาสต์บริดจ์ของเคอร์เนลเข้ามาเล่นนอกเหนือไปจากสิ่งอื่นใด :(
us flag
ดังนั้น สมมติฐานเบื้องต้นขึ้นอยู่กับคำตอบนี้และการเรียกดูเคอร์เนลสองสามปีที่ผ่านมาส่งข้อความที่กล่าวถึง "มัลติคาสต์": อาจมีปัญหาในเคอร์เนลรุ่นเก่าที่ได้รับการแก้ไขโดยการอัปเดตต่างๆ ของบริดจ์และการจัดการมัลติคาสต์ของ macvlan ในเวอร์ชันใหม่กว่า เมล็ด ขั้นตอนต่อไปคือการดูว่าปัญหาสามารถทำซ้ำได้ด้วยเคอร์เนล 4.9.283 (เวอร์ชัน LTS ล่าสุดสำหรับ Debian 9) หรือเคอร์เนล 5.8.0+ ที่ใหม่กว่า

โพสต์คำตอบ

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