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

ทำไมการทับซ้อนจึงไม่ใช่ปัญหาจริง

WireGuard ส่งต่อตามปลายทาง: AllowedIPs ของ peer เป็นตัวกำหนดว่า peer ใดจะได้รับแพ็กเก็ต peer สองตัวไม่สามารถประกาศ 10.10.7.0/24 พร้อมกันได้โดยที่ตัวหนึ่งไม่ชนะทุกการค้นหา นี่เป็นคุณสมบัติของตาราง peer ไม่ใช่ของอุโมงค์ ดังนั้นวิธีแก้ตรงนี้จึงเป็นแผนที่อยู่ ไม่ใช่กลเม็ดการกำหนดเส้นทาง

แผนคือหยุดประกาศ LAN ทั้งหมด แทนที่จะเป็นเช่นนั้น ให้ประกาศ alias ต่อบริการ หนึ่งที่อยู่ต่อไซต์ และให้เกตเวย์ของแต่ละไซต์แปล alias นั้นเป็นแอปพลิเคชันจริงของตน

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

ให้ alias แก่แต่ละไซต์ที่ผู้ใช้กำหนดเส้นทางได้

เลือกที่อยู่จากช่วงที่ไม่ชนกับสิ่งใดบนเครื่องของผู้ใช้ ฮับ หรือ LAN ทั้งสอง ที่นี่ฮับคือ 10.66.0.1 ผู้ใช้คือ 10.66.0.10 เกตเวย์คือ 10.66.0.21 และ 10.66.0.22 และ alias สองอันคือ 10.77.1.20 และ 10.77.2.20 ฮับเผยแพร่แต่ละ alias ผ่าน peer ที่เป็นเจ้าของ ดังนั้นแพ็กเก็ตขาออกที่ส่งไปยัง alias หนึ่งจึงออกได้ทางไซต์ที่ตรงกันเท่านั้น:

[Interface]
Address = 10.66.0.1/32
ListenPort = 51820
PrivateKey = HUB_KEY

[Peer]
PublicKey = USER_PUBLIC_KEY
AllowedIPs = 10.66.0.10/32

[Peer]
PublicKey = SITE_A_PUBLIC_KEY
AllowedIPs = 10.66.0.21/32, 10.77.1.20/32

[Peer]
PublicKey = SITE_B_PUBLIC_KEY
AllowedIPs = 10.66.0.22/32, 10.77.2.20/32

ฝั่งผู้ใช้ต้องการเพียงสอง alias ซึ่งทำให้การกำหนดค่าของไคลเอนต์ปลอดจากคำนำหน้า LAN ทั้งสอง ไม่มีสิ่งใดในการกำหนดค่านั้นกล่าวถึง LAN จริงเลย:

[Interface]
Address = 10.66.0.10/32
PrivateKey = USER_KEY

[Peer]
PublicKey = HUB_PUBLIC_KEY
Endpoint = hub.example.net:51820
AllowedIPs = 10.77.1.20/32, 10.77.2.20/32
PersistentKeepalive = 25

เกตเวย์แต่ละตัวประกาศฮับและต้นทางของผู้ใช้ ไม่มีอย่างอื่น ดังนั้นไซต์หนึ่งจึงไม่เคยเรียนรู้ LAN ของอีกไซต์ Keepalive รักษาการแมป NAT บนอัปลิงก์ของไซต์ มันไม่ได้ให้สิทธิ์แก่ทราฟฟิก และไฟร์วอลล์ยังคงตัดสินใจว่าอะไรจะถูกยอมรับ การคัดลอกการกำหนดค่าของเกตเวย์หนึ่งไปยังอีกตัวทำได้ตราบใดที่คีย์ส่วนตัว ที่อยู่ของอินเทอร์เฟซ และ alias เปลี่ยนทั้งหมด

ฮับต้องอนุญาตอะไรระหว่าง peer สองตัวของตน

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

กฎด้านล่างอนุญาตให้ผู้ใช้เข้าถึง alias หนึ่งและพอร์ตหนึ่ง และอนุญาตทราฟฟิกขากลับผ่านการติดตามการเชื่อมต่อ มันทิ้งทุกอย่างอื่นบนเส้นทาง forward และนั่นคือประเด็น:

nft add table inet hub_transit
nft add chain inet hub_transit forward '{ type filter hook forward priority 0 ; policy drop ; }'
nft add rule inet hub_transit forward ct state established,related accept
nft add rule inet hub_transit forward iifname wg0 oifname wg0 tcp dport 443 ip saddr 10.66.0.10 ip daddr 10.77.1.20 accept

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

ที่ที่ alias กลายเป็นที่อยู่จริง

ไซต์ A ได้รับคำขอไปยัง 10.77.1.20 เขียนปลายทางใหม่เป็นแอปพลิเคชันจริง และเขียนต้นทางใหม่เป็นที่อยู่ LAN ของตัวเอง เพื่อให้คำตอบกลับมาได้โดยไม่ต้องมีเส้นทางไปยังอุโมงค์ การแปลทั้งสองอย่างในที่เดียวทำให้เครือข่ายที่เหลือไม่รู้เรื่อง alias กฎด้านล่างคือกลไกทั้งหมด:

nft add table ip site_a_nat
nft add chain ip site_a_nat pre '{ type nat hook prerouting priority -100 ; policy accept ; }'
nft add chain ip site_a_nat post '{ type nat hook postrouting priority 100 ; policy accept ; }'
nft add rule ip site_a_nat pre iifname wg0 tcp dport 443 ip saddr 10.66.0.10 ip daddr 10.77.1.20 dnat to 10.10.7.20:443
nft add rule ip site_a_nat post iifname wg0 oifname lan0 tcp dport 443 ip saddr 10.66.0.10 ip daddr 10.10.7.20 snat to 10.10.7.2

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

ไซต์ B ทำซ้ำด้วย alias ของตัวเองและคีย์ของตัวเอง ห้ามใช้คีย์ส่วนตัวของไซต์ A ซ้ำ เพราะ peer สองตัวที่ใช้ตัวตนเดียวกันเป็นการกำหนดค่าที่ผิดพลาดซึ่งเห็นได้ยากและสร้างได้ง่ายด้วยการคัดลอกไฟล์ เก็บเอกสารเกตเวย์ทั้งสองให้เหมือนกันยกเว้นค่าที่ต้องต่างกัน เพื่อให้ความแตกต่างเด่นในการตรวจทาน ไฟล์ที่คัดลอกคือต้นกำเนิดปกติของข้อผิดพลาดนั้น

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

วิธีพิสูจน์ว่าชื่อที่เผยแพร่ทั้งสองตอบสนอง

ให้ชื่อ DNS แก่แต่ละ alias และกำหนดค่าแอปพลิเคชันและใบรับรองสำหรับชื่อนั้น เพราะการแปลไม่ได้เขียนการเปลี่ยนเส้นทางหรือ URL แบบสัมบูรณ์ที่ฝังอยู่ใหม่ ใช้ชื่อเดียวต่อไซต์เพื่อให้ความไม่ตรงกันของใบรับรองไม่ถูกเข้าใจผิดว่าเป็นความผิดพลาดในการกำหนดเส้นทาง

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

wg show wg0 allowed-ips
sudo nft list ruleset
curl -sS -o /dev/null -w "%{http_code}\n" https://site-a.example.net/

alias ว่างหรือไม่คาดคิดในคำสั่งแรกหมายความว่าการเลือก peer ผิดก่อนที่กฎไฟร์วอลล์ใดจะมีความหมาย ถ้า alias ถูกแต่ชื่อยังล้มเหลว ปัญหาได้ย้ายไปที่ DNS และใบรับรอง เมื่อทั้งสองชื่อตอบและพอร์ตที่สามยังปิดอยู่ การออกแบบก็ทำในสิ่งที่อ้าง: บริการสองอย่างที่เผยแพร่แคบ ๆ ไม่ใช่สอง LAN ที่หลอมรวม

บทความที่เกี่ยวข้อง