ორივე საიტი ერთსა და იმავე LAN დიაპაზონს იყენებს და გადაფარვა არ არის ის, რაც დიზაინს რეალურად ამტვრევს. კვანძმა საიტი მხოლოდ დანიშნულების მისამართით უნდა აირჩიოს და ორი იდენტური დანიშნულება მას არჩევანისთვის არაფერს აძლევს. მომუშავე ოფისის გადანომრვა გვირაბის დასაკმაყოფილებლად ჩვეულებრივ უარესი გაცვლაა, ვიდრე თითოეულ გამოქვეყნებულ სერვისს მივცეთ ცალკე მისამართი, რომლის ტარებაც გვირაბს შეუძლია. ქვემოთ მოცემული დიზაინი აქვეყნებს ერთ HTTPS სერვისს თითო საიტზე და სხვა არაფერს.

რატომ არ არის გადაფარვა ნამდვილი პრობლემა

WireGuard გადასცემს დანიშნულების მიხედვით: peer-ის AllowedIPs განსაზღვრავს, რომელი 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-ის დაბმას საიტის აპლინკზე; ის არ ანიჭებს ტრაფიკს უფლებას და firewall მაინც წყვეტს, რა დაიშვას. ერთი კარიბჭის კონფიგურაციის მეორეში კოპირება ნორმალურია, სანამ პირადი გასაღები, ინტერფეისის მისამართი და 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

შემდეგ საიტი A-ს forward პოლიტიკამ უნდა დაუშვას თარგმნილი ნაკადი გვირაბის ინტერფეისიდან LAN ინტერფეისზე, პლუს დაბრუნების მიმართულება. forward hook ხედავს დანიშნულებას დანიშნულების თარგმანის შემდეგ და წყაროს გადაწერამდე, ამიტომ წესი ასახელებს რეალური აპლიკაციის მისამართს. წაიკითხეთ ეს ორი hook ამ თანმიმდევრობით, როცა წესი თითქოს არაფერს ემთხვევა. alias-ის წინააღმდეგ დაწერილი forward წესი ვერასოდეს დაემთხვევა, რადგან alias იმ hook-ზე აღარ არსებობს.

საიტი B იმეორებს ამას საკუთარი alias-ით და საკუთარი გასაღებით. მან არ უნდა გამოიყენოს საიტი A-ს პირადი გასაღები, რადგან ორი peer-ის ერთი იდენტობის გაზიარება კონფიგურაციის შეცდომაა, რომლის დანახვაც ძნელია და ფაილის კოპირებით შექმნაც ადვილი. შეინახეთ ორივე კარიბჭის დოკუმენტი იდენტური გარდა იმ მნიშვნელობებისა, რომლებიც უნდა განსხვავდებოდეს, რომ განსხვავება განხილვისას თვალში საცემი იყოს. კოპირებული ფაილი ამ ხარვეზის ჩვეულებრივი წყაროა.

წყაროს გადაწერას თავისი ფასი აქვს. აპლიკაცია კარიბჭეს საკუთარ კლიენტად ხედავს, ამიტომ მისი ჟურნალები აღარ აჩვენებს, რომელი მომხმარებელი დაუკავშირდა. შეინახეთ კარიბჭის აუდიტის კვალი და არ შეასუსტოთ აპლიკაციის შესვლა იმ ქსელური იდენტობის კომპენსაციისთვის, რომელიც თარგმანმა მოხსნა.

როგორ დავამტკიცოთ, რომ ორივე გამოქვეყნებული სახელი პასუხობს

მიეცით თითოეულ alias-ს DNS სახელი და დააკონფიგურირეთ აპლიკაცია და სერტიფიკატი ამ სახელისთვის, რადგან თარგმანი არ გადაწერს გადამისამართებებს ან ჩაშენებულ აბსოლუტურ 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-ის არჩევა არასწორია მანამ, სანამ რომელიმე firewall წესი მნიშვნელოვანი გახდება. თუ alias სწორია და სახელი მაინც ვერ მუშაობს, პრობლემა DNS-სა და სერტიფიკატებზე გადავიდა. როგორც კი ორივე სახელი უპასუხებს და მესამე პორტი დახურული დარჩება, დიზაინი აკეთებს იმას, რასაც აცხადებს: ორი ვიწროდ გამოქვეყნებული სერვისი და არა ორი გაერთიანებული LAN.

დაკავშირებული სტატიები