Score:2

Conntrack ล้มเหลวในการ NAT แพ็กเก็ต TCP ของตัวเองจาก VRF อื่น

ธง us

ฉันพบปัญหายุ่งยากเกี่ยวกับ NAT ต้นทางเมื่อใช้ VRF หลายตัวบนเราเตอร์ที่ใช้เดเบียน มันค่อนข้างซับซ้อนที่จะอธิบาย ดังนั้นฉันจะพยายามอธิบายให้ชัดเจน แต่จะไม่สั้นเกินไป ขออภัยด้วย ปัญหาควรง่ายต่อการทำซ้ำแม้ว่า

เพื่อแยกส่วน "การจัดการ" ของเราเตอร์ (ssh และบริการอื่นๆ) ออกจากงานเราเตอร์ (แพ็กเก็ตการกำหนดเส้นทางและ NATing) ฉันพยายามตั้งค่า VRF "mgmt" ใน VRF เริ่มต้น (จัดการกับซ็อกเก็ตบริการได้ง่ายกว่า) และ การกำหนดเส้นทางหนึ่งใน VRF ที่เรียกว่า "ไฟร์วอลล์"

สามารถสรุปไดอะแกรมได้ดังนี้

แผนภาพเครือข่าย

เครือข่าย "การจัดการ" คือ 192.168.100.0/24 และกำหนดเส้นทางโดยสวิตช์ L3 ซึ่งมี L3 ที่มี VRF "ไฟร์วอลล์" ของเราเตอร์ผ่านเครือข่าย 10.254.5.0/24 อินเทอร์เฟซเราเตอร์ตัวที่สามคืออินเทอร์เฟซ "อินเทอร์เน็ต" และแพ็กเก็ตที่ผ่านอินเทอร์เฟซนั้นเป็น NATed ต้นทาง การตั้งค่านี้ใช้งานได้ค่อนข้างดีสำหรับทุกอย่างในเครือข่ายย่อย mgmt ยกเว้นแพ็กเก็ตของเราเตอร์ซึ่งเป็นสาเหตุของการรบกวน

เกี่ยวกับกฎ iptables:

# ตัวกรองตาราง

#ห่วงโซ่อินพุต
-A INPUT -m conntrack --ctstate ที่เกี่ยวข้อง ก่อตั้ง -j ยอมรับ
(กฎ INPUT บางข้อสำหรับ ssh, snmp เป็นต้น)
-A อินพุต -j DROP

#โซ่ส่งต่อ
-A FORWARD -m conntrack --ctstate ที่เกี่ยวข้อง ก่อตั้ง -j ยอมรับ
-A FORWARD -m conntrack --ctstate ไม่ถูกต้อง -j DROP
-A ส่งต่อ -o eth2 -j ยอมรับ
-A ส่งต่อ -j DROP

#โต๊ะแนท

# ห่วงโซ่โพสต์
-A POSTROUTING -o eth2 -j SNAT --to-source 192.168.122.100

เกี่ยวกับตารางเส้นทาง:

# VRF เริ่มต้น
ค่าเริ่มต้นผ่าน 192.168.100.1 dev eth0 proto static metric 20 
192.168.100.0/24 dev eth0 ลิงก์ขอบเขตเคอร์เนลโปรโต src 192.168.100.90

# ไฟร์วอลล์ VRF
ค่าเริ่มต้นผ่าน 192.168.122.1 dev eth2 proto static metric 20
10.254.5.0/24 dev eth1 ลิงก์ขอบเขตเคอร์เนลโปรโต src 10.254.5.2
192.168.100.0/24 โปรโต bgp เมตริก 20 nexthop ผ่าน 10.254.5.10 dev eth1 น้ำหนัก 1 
192.168.122.0/24 dev eth2 ลิงก์ขอบเขตเคอร์เนลโปรโต src 192.168.122.100 

ดังนั้น เมื่อแพ็กเก็ตจาก VRF เริ่มต้นพยายามเข้าถึงอินเทอร์เน็ต แพ็กเก็ตจะออกจาก eth0 ถูกกำหนดเส้นทางโดยสวิตช์ L3 ป้อนไฟร์วอลล์ VRF ด้วย eth1 และถูกกำหนดเส้นทางและ NATed ผ่าน eth2 เนื่องจากฉันติดตามการเชื่อมต่อ INPUT และ FORWARD ทำให้ conntrack สับสนเล็กน้อยเมื่อแพ็กเก็ตกลับมา และไม่สามารถรู้ได้ว่าจะทำอย่างไรกับแพ็กเก็ต

ฉันสามารถแก้ไขปัญหานี้สำหรับ ICMP และ UDP โดยใช้โซน conntrack ในตารางดิบ

#โต๊ะดิบ
#โซ่PREOUTING
-A PREROUTING -i eth0 -j CT --โซน 5
#เชนเอาท์พุต
-A OUTPUT -o eth0 -j CT --โซน 5

ด้วยกฎเหล่านี้ แพ็กเก็ตที่มาจากเราเตอร์และผ่านไป eth0 เป็นแท็ก โซน 5 และเมื่อแพ็คเก็ตเข้า eth0 พวกเขายังติดแท็ก โซน 5.

ด้วยการ ping ไปที่ 8.8.8.8 ดูเหมือนว่านี้ (ด้วยคำสั่ง คอนแทรค -E):

    [ใหม่] icmp 1 30 src=192.168.100.90 dst=8.8.8.8 type=8 code=0 id=1999 [UNREPLIED] src=8.8.8.8 dst=192.168.100.90 type=0 code=0 id=1999 zone=5
    [ใหม่] icmp 1 30 src=192.168.100.90 dst=8.8.8.8 type=8 code=0 id=1999 [UNREPLIED] src=8.8.8.8 dst=192.168.122.100 type=0 code=0 id=1999
 [อัพเดท] icmp 1 30 src=192.168.100.90 dst=8.8.8.8 type=8 code=0 id=1999 src=8.8.8.8 dst=192.168.122.100 type=0 code=0 id=1999
 [อัพเดท] icmp 1 30 src=192.168.100.90 dst=8.8.8.8 type=8 code=0 id=1999 src=8.8.8.8 dst=192.168.100.90 type=0 code=0 id=1999 zone=5

เราจะเห็นที่นี่เป็นที่แรก ใหม่ การเชื่อมต่อถูกสร้างขึ้นเมื่อแพ็กเก็ตผ่านไป eth0 กับ โซน=5 แท็ก แล้วใหม่เมื่อเข้าสู่ไฟร์วอลล์ VRF ผ่าน eth1 โดยไม่ต้องแท็ก เมื่อคำตอบมาถึง การเชื่อมต่อที่สองจะได้รับการอัปเดตก่อน (เนื่องจากเป็นการเชื่อมต่ออินเทอร์เน็ต) และการเชื่อมต่อครั้งแรก

สิ่งนี้ใช้ได้กับ UDP เช่น กับการสืบค้น DNS เป็น 8.8.8.8

    [ใหม่] udp 17 30 src=192.168.100.90 dst=8.8.8.8 sport=53369 dport=53 [ไม่ได้ตอบกลับ] src=8.8.8.8 dst=192.168.100.90 sport=53 dport=53369 zone=5
    [ใหม่] udp 17 30 src=192.168.100.90 dst=8.8.8.8 sport=53369 dport=53 [ไม่ได้ตอบ] src=8.8.8.8 dst=192.168.122.100 sport=53 dport=53369
 [อัพเดท] udp 17 30 src=192.168.100.90 dst=8.8.8.8 sport=53369 dport=53 src=8.8.8.8 dst=192.168.122.100 sport=53 dport=53369
 [อัพเดท] udp 17 30 src=192.168.100.90 dst=8.8.8.8 sport=53369 dport=53 src=8.8.8.8 dst=192.168.100.90 sport=53 dport=53369 zone=5

แต่กับ TCP มันใช้ไม่ได้ ข้อความค้นหา telnet ถึง 172.16.10.10 พอร์ต 80 มีลักษณะดังนี้:

    [ใหม่] tcp 6 120 SYN_SENT src=192.168.100.90 dst=172.16.10.10 sport=60234 dport=80 [ไม่ได้ตอบ] src=172.16.10.10 dst=192.168.100.90 sport=80 dport=60234 zone=5
    [ใหม่] tcp 6 120 SYN_SENT src=192.168.100.90 dst=172.16.10.10 sport=60234 dport=80 [ไม่ได้ตอบ] src=172.16.10.10 dst=192.168.122.100 sport=80 dport=60234
 [อัพเดท] tcp 6 58 SYN_RECV src=192.168.100.90 dst=172.16.10.10 sport=60234 dport=80 src=172.16.10.10 dst=192.168.122.100 sport=80 dport=60234
 [อัพเดท] tcp 6 57 SYN_RECV src=192.168.100.90 dst=172.16.10.10 sport=60234 dport=80 src=172.16.10.10 dst=192.168.122.100 sport=80 dport=60234
(บรรทัดสุดท้ายซ้ำหลายครั้ง)

ถ้าฉัน tcpdump eth2 คำตอบอยู่ที่นั่น:

IP 192.168.122.100.60236 > 172.16.10.10.80: ค่าสถานะ [S], seq 4203590660, ชนะ 62720, ตัวเลือก [mss 1460,sackOK,TS val 1511828881 ecr 0,nop,wscale 7], ความยาว 0
IP 172.16.10.10.80 > 192.168.122.100.60236: แฟล็ก [S.], seq 3672808466, ack 4203590661, win 65535, options [mss 1430,sackOK,TS val 2474659117 ecr 1511828881,nop 8,nop ความยาว]
IP 192.168.122.100.60236 > 172.16.10.10.80: ค่าสถานะ [S], seq 4203590660, ชนะ 62720, ตัวเลือก [mss 1460,sackOK,TS val 1511829887 ecr 0,nop,wscale 7], ความยาว 0
IP 172.16.10.10.80 > 192.168.122.100.60236: ค่าสถานะ [S.], seq 3672808466, ack 4203590661, win 65535, options [mss 1430,sackOK,TS val 2474660123 ecr 1511828881,nop 8,nop 80,nop 80,nop 80,nop 80,nop 80,nop 80,nop 80 > 192.168.122.100.60236 > 192.168.122.100.60236

แต่เนื่องจากไม่มีการรับทราบ SIN ACK เราเตอร์จึงส่ง SIN ใหม่ต่อไป

ตอนนี้ถ้าฉัน tcpdump eth1:

IP 192.168.100.90.60238 > 172.16.10.10.80: ค่าสถานะ [S], seq 3124513394, ชนะ 62720, ตัวเลือก [mss 1460,sackOK,TS val 1511928806 ecr 0,nop,wscale 7], ความยาว 0
IP 192.168.100.90.60238 > 172.16.10.10.80: ค่าสถานะ [S], seq 3124513394, ชนะ 62720, ตัวเลือก [mss 1460,sackOK,TS val 1511929823 ecr 0,nop,wscale 7], ความยาว 0
IP 192.168.100.90.60238 > 172.16.10.10.80: ค่าสถานะ [S], seq 3124513394, ชนะ 62720, ตัวเลือก [mss 1460,sackOK,TS val 1511931839 ecr 0,nop,wscale 7], ความยาว 0

เราจะเห็นว่าคำตอบจะไม่ถูกส่งกลับไปที่ 192.168.100.90

ถ้าฉันปิดการติดตามการเชื่อมต่อและอนุญาตทุกอย่างใน iptables มันก็ใช้ได้ ดังนั้นฉันคิดว่า conntrack มีปัญหาในการจัดการการเชื่อมต่อ TCP จากตัวเองไปยังโซนอื่นเมื่อเป็น NAT หากมีอะไรไม่ชัดเจน เรายินดีตอบคำถามเกี่ยวกับเรื่องนี้

Score:1
ธง us

ปัญหานี้พบในเดเบียน 10 ที่มีเคอร์เนล 4.19.0-12-amd64 แต่หลังจากอัปเกรดเป็นเดเบียน 11 ด้วยเคอร์เนล 5.10.0-11-amd64 การทำงานตามที่คาดไว้ แม้แต่สำหรับโฟลว์ TCP

โพสต์คำตอบ

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