Score:0

มัลติเกตเวย์ทำงานร่วมกับ HAProxy และ VPN ได้หรือไม่

ธง ae

เรามีสถานการณ์ที่เราจะมีเราเตอร์เกตเวย์จริงสองรายการบนเครือข่าย โดยแต่ละรายการเชื่อมต่อกับ ISP ของตนเอง เนื่องจากข้อกำหนดทางธุรกิจ เราไม่สามารถรวม WAN สองตัวเข้ากับเราเตอร์ตัวเดียวได้ ดังนั้นต้องมีเราเตอร์สองตัว

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

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

การตั้งค่าที่เสนอ: ป้อนคำอธิบายรูปภาพที่นี่

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

การตั้งค่าปัจจุบัน: ป้อนคำอธิบายรูปภาพที่นี่

หมายเหตุเพิ่มเติม เราเตอร์ 2 จะเป็นเราเตอร์ pfSense

Tom Yan avatar
in flag
ไม่คุ้นเคยกับ haproxy / load balancing แต่ความคิดแรกของฉันเกี่ยวกับสถานการณ์ของคุณคือ สิ่งที่คุณต้องการดูเหมือนจะเป็นการตั้งค่า conntrack mark ตามที่อยู่ต้นทาง L2 และการตั้งค่า fwmark (ซึ่งจะจับคู่โดยกฎ ip) สำหรับที่เกี่ยวข้อง การตอบกลับการรับส่งข้อมูล และควรตั้งค่าโดยตรงบนโฮสต์เซิร์ฟเวอร์ ฉันไม่เคยปรับใช้การตั้งค่า "แยกการกำหนดเส้นทาง" ด้วยตัวเอง แต่ฉันคิดว่ามันเป็นไปได้ด้วย nftables บน Linux (ดังนั้นจึงไม่รู้ว่าเว็บเซิร์ฟเวอร์ของคุณมี Windows หรือ BSD)
Zac67 avatar
ru flag
ไม่แน่ใจเกี่ยวกับเราเตอร์ pfSense แต่ด้วยเราเตอร์ที่เหมาะสม คุณควรย้ายเราเตอร์ ISP ออกจากเครือข่าย 'แบน' ของคุณและวางเราเตอร์ระหว่างเราเตอร์กับ LAN ของคุณ เราเตอร์ที่เหมาะสมควรสามารถส่งคืนทราฟฟิกกลับไปยัง ISP ที่ซึ่งมันมาจาก (สำหรับการเชื่อมต่อขาเข้า) และจัดเตรียมรูปแบบของโหลดบาลานซ์ (สำหรับการเชื่อมต่อขาออก) การกำหนดเส้นทางตามนโยบายตามโปรโตคอลหรือที่อยู่ IP ต้นทางอาจทำงานได้ดีเช่นกัน ทั้งหมดนี้ควรใช้งานได้โดยไม่ต้องใช้พร็อกซี (ซึ่งอาจเป็นความเจ็บปวดอย่างมาก)
Tom Yan avatar
in flag
Btw เว้นแต่คุณจะสามารถทำให้เราเตอร์ ISP ของคุณดำเนินการ *source* NAT สำหรับทราฟฟิกจาก *อินเทอร์เน็ต* ได้ ฉันไม่คิดว่าพร็อกซีจะสมเหตุสมผล / สำคัญ เพราะสุดท้ายแล้วจะต้อง "แยกเส้นทาง" ที่ *ตอบกลับ* ตาม ที่อยู่ต้นทาง *MAC* ของทราฟฟิก *ดั้งเดิม* พร็อกซีสามารถส่งต่อการตอบกลับไปยังเราเตอร์ที่เกี่ยวข้องได้ก็ต่อเมื่อ *ที่อยู่ IP ปลายทาง* ของการตอบกลับสามารถ *ระบุ* เราเตอร์ที่พวกเขาควรไป ซึ่งเป็นการเปิดเฉพาะในกรณีที่เราเตอร์ ISP สามารถกำหนดค่าให้ใช้งานแหล่งที่มาที่เล่นโวหารแบบนั้นได้ แนท (นอกจากนี้ยังไม่สามารถปรับขนาดได้ / สมจริงสำหรับการปลอมตัวบนอินเทอร์เน็ต)
Score:0
ธง in

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

โฮสต์ VM ทำหน้าที่เป็นเว็บเซิร์ฟเวอร์ และ VM สองตัวทำหน้าที่เป็นเราเตอร์ โดยหนึ่งใน VM ทำหน้าที่เป็นเว็บไคลเอนต์จาก "อินเทอร์เน็ต":

ป้อนคำอธิบายรูปภาพที่นี่

การกำหนดค่าบนโฮสต์ VM (เว็บเซิร์ฟเวอร์):

$ ip แสดง dev bridge1
4: บริดจ์ 1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP กลุ่มเริ่มต้น qlen 1000
    ลิงค์/อีเธอร์ 3a:f6:7b:90:aa:bd brd ff:ff:ff:ff:ff:ff
    inet 192.168.254.3/24 ขอบเขตโกลบอลบริดจ์1
       valid_lft ตลอดไป reserved_lft ตลอดไป
    ลิงค์ขอบเขต inet6 fe80::38f6:7bff:fe90:aabd/64 
       valid_lft ตลอดไป reserved_lft ตลอดไป

$ ip แสดง dev bridge2
5: bridge2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP กลุ่มเริ่มต้น qlen 1000
    ลิงค์/อีเธอร์ 1a:6f:58:86:72:55 brd ff:ff:ff:ff:ff:ff
    ลิงค์ขอบเขต inet6 fe80::186f:58ff:fe86:7255/64 
       valid_lft ตลอดไป reserved_lft ตลอดไป

(สะพาน1 ใช้สำหรับจำลอง LAN และ สะพาน2 ใช้สำหรับจำลอง "อินเทอร์เน็ต" ดังนั้นอันหลังจึงไม่ถูกกำหนดที่อยู่ IPv4)

กฎ $ ip
0: จากการค้นหาทั้งหมดในท้องถิ่น
32765: จากทั้งหมด fwmark 0xb iif lo ค้นหา 11
32766: จากหลักการค้นหาทั้งหมด
32767: จากค่าเริ่มต้นการค้นหาทั้งหมด

$ip r แสดงตาราง main dev bridge1
10.10.10.0/24 ผ่าน 192.168.254.1 
192.168.254.0/24 ลิงก์ขอบเขตเคอร์เนลโปรโต src 192.168.254.3 

$iprแสดงตาราง11
10.10.10.0/24 ผ่าน 192.168.254.2 dev bridge1 

(ที่นี่ 192.168.254.1 จะถือว่าเป็นเกตเวย์เริ่มต้น "หลัก" ไอฟ โล เป็นการปรับแต่งที่ทำให้กฎมีผลกับการรับส่งข้อมูลที่มาจากโฮสต์เองเท่านั้น กล่าวคืออาจไม่จำเป็น เว้นแต่โฮสต์เว็บเซิร์ฟเวอร์จะทำหน้าที่เป็นเราเตอร์บางประเภทด้วย)

ชุดกฎรายการ $ sudo nft
ตาราง ip ยุ่งเหยิง {
    อินพุตลูกโซ่ {
        ประเภท ตัวกรอง เบ็ด ลำดับความสำคัญของการป้อนข้อมูล; นโยบายยอมรับ;
        อีเธอร์ saddr 52:54:00:bb:bb:bb ip saddr != 192.168.254.2 ct เครื่องหมายตั้ง 0x0000000b
    }

    เอาต์พุตลูกโซ่ {
        ประเภทเส้นทางเบ็ดลำดับความสำคัญของเอาต์พุต นโยบายยอมรับ;
        เครื่องหมาย ct เครื่องหมายเมตา 0x0000000b ตั้งเครื่องหมาย ct
    }
}

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

นี่คือ tcpdump จับภาพบนโฮสต์ VM / เว็บเซิร์ฟเวอร์ของทั้งสอง ขด ทำงานบนเว็บไคลเอ็นต์ VM:

$ sudo tcpdump -eni bridge1 tcp พอร์ต 80
tcpdump: เอาต์พุต verbose ถูกระงับ ใช้ -v[v]... สำหรับการถอดรหัสโปรโตคอลแบบเต็ม
กำลังฟังบนบริดจ์ 1 ประเภทลิงก์ EN10MB (อีเธอร์เน็ต) ความยาวสแน็ปช็อต 262144 ไบต์
16:54:43.602105 52:54:00:aa:aa:aa > 3a:f6:7b:90:aa:bd, ethertype IPv4 (0x0800), ความยาว 74: 10.10.10.3.33132 > 192.168.254.3.80: ค่าสถานะ [S], seq 2320058647, ชนะ 64240, ตัวเลือก [mss 1460,sackOK,TS val 3412464375 ecr 0,nop,wscale 7], ความยาว 0
16:54:43.602185 3a:f6:7b:90:aa:bd > 52:54:00:aa:aa:aa, ethertype IPv4 (0x0800), ความยาว 74: 192.168.254.3.80 > 10.10.10.3.33132: ค่าสถานะ [S.], seq 3987984937, ack 2320058648, win 65160, options [mss 1460,sackOK,TS val 3768307023 ecr 3412464375,nop,wscale 7], ความยาว 0
16:54:43.603460 52:54:00:aa:aa:aa > 3a:f6:7b:90:aa:bd, ethertype IPv4 (0x0800), ความยาว 66: 10.10.10.3.33132 > 192.168.254.3.80: ค่าสถานะ [.], ack 1, ชนะ 502, ตัวเลือก [nop,nop,TS val 3412464377 ecr 3768307023], ความยาว 0
16:54:43.604003 52:54:00:aa:aa:aa > 3a:f6:7b:90:aa:bd, ethertype IPv4 (0x0800), ความยาว 140: 10.10.10.3.33132 > 192.168.254.3.80: ค่าสถานะ [P.], seq 1:75, ack 1, win 502, ตัวเลือก [nop,nop,TS val 3412464377 ecr 3768307023], ความยาว 74: HTTP: GET / HTTP/1.1
16:54:43.604054 3a:f6:7b:90:aa:bd > 52:54:00:aa:aa:aa, ethertype IPv4 (0x0800), ความยาว 66: 192.168.254.3.80 > 10.10.10.3.33132: ค่าสถานะ [.], ack 75, ชนะ 509, ตัวเลือก [nop,nop,TS val 3768307025 ecr 3412464377], ความยาว 0
16:54:43.604238 3a:f6:7b:90:aa:bd > 52:54:00:aa:aa:aa, ethertype IPv4 (0x0800), ความยาว 329: 192.168.254.3.80 > 10.10.10.3.33132: ค่าสถานะ [P.], seq 1:264, ack 75, win 509, options [nop,nop,TS val 3768307025 ecr 3412464377], ความยาว 263: HTTP: HTTP/1.1 200 OK
16:54:43.604636 52:54:00:aa:aa:aa > 3a:f6:7b:90:aa:bd, ethertype IPv4 (0x0800), ความยาว 66: 10.10.10.3.33132 > 192.168.254.3.80: ค่าสถานะ [.], ack 264, ชนะ 501, ตัวเลือก [nop,nop,TS val 3412464378 ecr 3768307025], ความยาว 0
16:54:43.605112 52:54:00:aa:aa:aa > 3a:f6:7b:90:aa:bd, ethertype IPv4 (0x0800), ความยาว 66: 10.10.10.3.33132 > 192.168.254.3.80: ค่าสถานะ [F.], seq 75, ack 264, win 501, options [nop,nop,TS val 3412464379 ecr 3768307025], ความยาว 0
16:54:43.605133 3a:f6:7b:90:aa:bd > 52:54:00:aa:aa:aa, ethertype IPv4 (0x0800), ความยาว 66: 192.168.254.3.80 > 10.10.10.3.33132: ค่าสถานะ [F.], seq 264, ack 76, win 509, option [nop,nop,TS val 3768307026 ecr 3412464379], ความยาว 0
16:54:43.605270 52:54:00:aa:aa:aa > 3a:f6:7b:90:aa:bd, ethertype IPv4 (0x0800), ความยาว 66: 10.10.10.3.33132 > 192.168.254.3.80: ค่าสถานะ [.], ack 265, ชนะ 501, ตัวเลือก [nop,nop,TS val 3412464379 ecr 3768307026], ความยาว 0

16:54:47.528893 52:54:00:bb:bb:bb > 3a:f6:7b:90:aa:bd, ethertype IPv4 (0x0800), ความยาว 74: 10.10.10.3.49270 > 192.168.254.3.80: ค่าสถานะ [S], seq 1866708541, ชนะ 64240, ตัวเลือก [mss 1460,sackOK,TS val 1196345946 ecr 0,nop,wscale 7], ความยาว 0
16:54:47.528977 3a:f6:7b:90:aa:bd > 52:54:00:bb:bb:bb, ethertype IPv4 (0x0800), ความยาว 74: 192.168.254.3.80 > 10.10.10.3.49270: ค่าสถานะ [S.], seq 1756841838, ack 1866708542, win 65160, options [mss 1460,sackOK,TS val 3768310949 ecr 1196345946,nop,wscale 7], ความยาว 0
16:54:47.530210 52:54:00:bb:bb:bb > 3a:f6:7b:90:aa:bd, ethertype IPv4 (0x0800), ความยาว 66: 10.10.10.3.49270 > 192.168.254.3.80: ค่าสถานะ [.], ack 1, ชนะ 502, ตัวเลือก [nop,nop,TS val 1196345947 ecr 3768310949], ความยาว 0
16:54:47.530535 52:54:00:bb:bb:bb > 3a:f6:7b:90:aa:bd, ethertype IPv4 (0x0800), ความยาว 140: 10.10.10.3.49270 > 192.168.254.3.80: ค่าสถานะ [P.], seq 1:75, ack 1, win 502, ตัวเลือก [nop,nop,TS val 1196345948 ecr 3768310949], ความยาว 74: HTTP: GET / HTTP/1.1
16:54:47.530588 3a:f6:7b:90:aa:bd > 52:54:00:bb:bb:bb, ethertype IPv4 (0x0800), ความยาว 66: 192.168.254.3.80 > 10.10.10.3.49270: ค่าสถานะ [.], ack 75, ชนะ 509, ตัวเลือก [nop,nop,TS val 3768310951 ecr 1196345948], ความยาว 0
16:54:47.530744 3a:f6:7b:90:aa:bd > 52:54:00:bb:bb:bb, ethertype IPv4 (0x0800), ความยาว 329: 192.168.254.3.80 > 10.10.10.3.49270: ค่าสถานะ [P.], seq 1:264, ack 75, win 509, options [nop,nop,TS val 3768310951 ecr 1196345948], ความยาว 263: HTTP: HTTP/1.1 200 OK
16:54:47.531434 52:54:00:bb:bb:bb > 3a:f6:7b:90:aa:bd, ethertype IPv4 (0x0800), ความยาว 66: 10.10.10.3.49270 > 192.168.254.3.80: ค่าสถานะ [.], ack 264, ชนะ 501, ตัวเลือก [nop,nop,TS val 1196345949 ecr 3768310951], ความยาว 0
16:54:47.532994 52:54:00:bb:bb:bb > 3a:f6:7b:90:aa:bd, ethertype IPv4 (0x0800), ความยาว 66: 10.10.10.3.49270 > 192.168.254.3.80: ค่าสถานะ [F.], seq 75, ack 264, win 501, options [nop,nop,TS val 1196345951 ecr 3768310951], ความยาว 0
16:54:47.533092 3a:f6:7b:90:aa:bd > 52:54:00:bb:bb:bb, ethertype IPv4 (0x0800), ความยาว 66: 192.168.254.3.80 > 10.10.10.3.49270: ค่าสถานะ [F.], seq 264, ack 76, win 509, option [nop,nop,TS val 3768310954 ecr 1196345951], ความยาว 0
16:54:47.533925 52:54:00:bb:bb:bb > 3a:f6:7b:90:aa:bd, ethertype IPv4 (0x0800), ความยาว 66: 10.10.10.3.49270 > 192.168.254.3.80: ค่าสถานะ [.], ack 265, ชนะ 501, ตัวเลือก [nop,nop,TS val 1196345951 ecr 3768310954], ความยาว 0
^ซี
จับได้ 20 ซอง
ตัวกรองได้รับ 20 แพ็คเก็ต
0 แพ็คเก็ตลดลงโดยเคอร์เนล

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


เหตุผลของชุดกฎ nftable

เดอะ เครื่องหมาย ct การตั้งค่า ใน อินพุตเบ็ด เชนจะทำให้เครื่องหมายถูกตั้งค่าสำหรับการรับส่งข้อมูลทั้งหมดของ "การเชื่อมต่อ" เดียวกัน (ผมไม่/ไม่สามารถลงลึกขนาดนั้นได้ แต่ถ้าอยากรู้มากกว่านี้ ลองศึกษาเรื่อง "conntrack" ดูครับ) ดังนั้นในส่วนของ เอาต์พุตเบ็ด คุณสามารถ "เลือก" คำตอบที่สอดคล้องกับ เครื่องหมาย ct การจับคู่และดำเนินการ เครื่องหมาย meta ตั้งเครื่องหมาย ct บนพวกเขาซึ่งหมายถึงการตั้งค่า เครื่องหมายเมตา ในการตอบกลับที่มีค่าเท่ากับ the เครื่องหมาย ct (เช่น. 0xbซึ่งเป็นค่าโดยพลการ btw) (คุณสามารถตั้งค่าเป็นค่าอื่นแทนได้เช่นกัน)

เครื่องหมายเมตา สอดคล้องกับ fwmark ในกฎ ip ดังนั้น ตารางเส้นทางพิเศษ (11 ในตัวอย่างซึ่งเป็นค่าที่กำหนดเอง) จะถูกค้นหาสำหรับการเข้าชมด้วย เครื่องหมายเมตา ซึ่งเท่ากับว่า fwmark ในกฎ ก่อน (เนื่องจากค่าลำดับความสำคัญต่ำกว่า) ตารางเส้นทาง หลัก ถูกมองขึ้น

ตั้งแต่ในตารางเส้นทาง 11 มีเส้นทางสำหรับ 10.10.10.0/24 ด้วย Nexthop อื่น (เช่น ทาง) จากตารางเส้นทาง หลักการตอบกลับที่เลือกจะถูกส่งไปยังเราเตอร์ "ถูกต้อง" (ไม่มีการค้นหาเพิ่มเติมเมื่อมีเส้นทางที่ "ครอบคลุม" ที่อยู่ปลายทาง)

แม้ว่า 10.10.10.0/24 จะใช้แทน ค่าเริ่มต้น เรียกอีกอย่างว่า 0.0.0.0/0 และ "เราเตอร์" เชื่อมต่อกับบริดจ์เดียวกันตามโฮสต์เว็บไคลเอ็นต์เพื่อจำลองอินเทอร์เน็ตจริง ไม่ควรขัดขวางการเจาะจากการทำงานในสถานการณ์จริง

Tom Yan avatar
in flag
การเจาะแบบเดียวกันอาจปรับใช้กับโฮสต์เราเตอร์ระดับกลาง ซึ่งในกรณีนี้ควรใช้กฎการตั้งค่า ct และ meta mark กับเชน 'hook prerouting' แต่เราเตอร์ระดับกลางอาจต้องใช้เป็นเน็กซ์ฮอป/เกตเวย์สำหรับซับเน็ต LAN บนเราเตอร์ ISP ทั้งสอง ซึ่งอาจเป็นสิ่งที่ยุ่งยาก/เป็นไปไม่ได้ที่จะทำ (หรือบางทีคุณอาจทำ DNAT / การส่งต่อพอร์ตแบบหลายเลเยอร์ แต่นั่นอาจเป็นสิ่งที่น่ารังเกียจและเป็นปัญหาเช่นกัน ... หากเป็นไปได้เลย)

โพสต์คำตอบ

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