Twee terreine, een subnet, een WireGuard-hub: kry dit aan die werk
Albei LAN's sit op 10.10.7.0/24, so die hub kan nie 'n terrein volgens bestemming kies nie. Gee elke diens 'n alias en vertaal by sy poort.
Albei terreine gebruik dieselfde LAN-reeks, en die oorvleueling is nie wat die ontwerp werklik breek nie. Die hub moet 'n terrein kies op grond van slegs die bestemmingsadres, en twee identiese bestemmings gee hom niks om mee te kies nie. Om 'n werkende kantoor te hernommer net om 'n tonnel te pas, is gewoonlik 'n slegter ruil as om elke gepubliseerde diens 'n eie adres te gee wat die tonnel kan dra. Die ontwerp hieronder publiseer een HTTPS-diens per terrein en niks anders nie.
Waarom die oorvleueling nie die werklike probleem is nie
WireGuard stuur aan die hand van die bestemming: die AllowedIPs van 'n peer bepaal watter peer 'n pakkie ontvang. Twee peers kan nie albei 10.10.7.0/24 adverteer sonder dat een van hulle elke opsoek wen nie. Dit is 'n eienskap van die peer-tabel en nie van die tonnel nie, en daarom is die oplossing hier 'n adresplan en nie 'n truuk met roetes nie.
Die plan is om heeltemal op te hou om die LAN te adverteer. Adverteer eerder 'n alias per diens, een adres per terrein, en laat elke terrein se poort daardie alias na sy werklike toepassing vertaal.
Die gebruiker roeteer twee unieke adresse, sien nooit die dubbelsinnige voorvoegsel nie, en niks in een van die twee kantore verander nie. Dit stel ook die grens eerlik: jy publiseer een HTTPS-diens uit elke terrein, nie twee netwerke wat saamgesmelt word nie. Die reëls hieronder bly klein omdat die stelling smal is. 'n Wyere stelling sou wyere reëls nodig hê, en dit is hoe sulke ontwerpe ingewikkeld raak.
Gee elke terrein 'n alias wat die gebruiker kan roeteer
Kies adresse uit 'n reeks wat met niks op die gebruiker se masjien, die hub of een van die LAN's bots nie. Hier is die hub 10.66.0.1, die gebruiker 10.66.0.10, die poorte 10.66.0.21 en 10.66.0.22, en die twee aliases 10.77.1.20 en 10.77.2.20. Die hub publiseer elke alias deur die peer wat dit besit, sodat 'n uitgaande pakkie wat aan een alias gerig is net deur die ooreenstemmende terrein kan vertrek:
[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
Die gebruikerkant het net die twee aliases nodig, wat die kliëntkonfigurasie vry hou van albei LAN-voorvoegsels. Niks in daardie konfigurasie noem een van die werklike LAN's nie:
[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
Elke poort adverteer die hub en die gebruiker se bron, niks anders nie, sodat 'n terrein nooit die ander terrein se LAN leer ken nie. Keepalive hou 'n NAT-koppeling op die terrein se oplyn in stand; dit magtig nie verkeer nie, en die firewall besluit steeds wat toegelaat word. Om een poort se konfigurasie na die ander te kopieer is reg, mits die private key, die koppelvlakadres en die alias almal verander.
Wat die hub tussen twee van sy peers moet toelaat
Die hub stuur pakkies tussen twee van sy eie peers aan, wat 'n besluit in die forward-ketting is eerder as 'n besluit by die inset. Aktiveer IPv4-forwarding deur die platform se normale meganisme, en laat dan presies die pare toe wat die ontwerp nodig het.
Die reël hieronder laat die gebruiker na een alias en een poort toe, en laat terugkeerverkeer deur verbindingopsporing deur. Dit laat alles anders in die forward-pad val, en dit is juis die punt:
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
Twee besonderhede is die moeite werd om te noem, want hulle veroorsaak stil foute. 'n Accept in een basisketting hef nie 'n drop in 'n ander op nie, dus smelt dit saam met die bestaande beleid eerder as om dit daarnaas te laai. En die bronadres identifiseer die toestel, nie die persoon nie; hou toepassingverifikasie apart van netwerktoelating.
Waar 'n alias 'n werklike adres word
Terrein A ontvang 'n versoek vir 10.77.1.20, herskryf die bestemming na die werklike toepassing, en herskryf die bron na sy eie LAN-adres sodat die antwoord kan terugkeer sonder 'n roete na die tonnel. Om albei vertalings op een plek te doen, hou die res van die netwerk onkundig oor die alias. Die reëls hieronder is die hele meganisme:
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
Terrein A se forward-beleid moet dan die vertaalde vloei van die tonnelkoppelvlak na die LAN-koppelvlak toelaat, plus die terugrigting. Die forward-haak sien die bestemming ná bestemmingsvertaling en vóór die bronherskrywing, en daarom noem die reël die werklike toepassingadres. Lees daardie twee hake in daardie volgorde wanneer 'n reël lyk of dit niks pas nie. 'n Forward-reël wat teen die alias geskryf is, kan nooit pas nie, want die alias bestaan nie meer by daardie haak nie.
Terrein B herhaal dit met sy eie alias en sy eie sleutel. Dit moet nie Terrein A se private key hergebruik nie, want twee peers wat een identiteit deel is 'n konfigurasiefout wat moeilik is om te sien en maklik is om te maak deur 'n lêer te kopieer. Hou albei poortdokumente identies behalwe vir die waardes wat moet verskil, sodat die verskil in 'n oorsig opval. 'n Gekopieerde lêer is die gewone oorsprong van daardie fout.
Die bronherskrywing het 'n prys. Die toepassing sien die poort as sy kliënt, so sy logs wys nie meer watter gebruiker gekoppel het nie. Hou die poort se ouditspoor, en moenie die toepassing se aanmelding verswak om te vergoed vir 'n netwerkidentiteit wat die vertaling weggeneem het nie.
Hoe om te bewys dat albei gepubliseerde name antwoord
Gee elke alias 'n DNS-naam en stel die toepassing en sertifikaat vir daardie naam op, want vertaling herskryf nie aansture of ingebedde absolute URL's nie. Gebruik een naam per terrein sodat 'n sertifikaatwanpassing nooit as 'n roetefout misverstaan kan word nie.
Toets van die werklike kliënt, bevestig watter terrein geantwoord het, en toets ook 'n ongemagtigde poort. Gebruik nuwe verbindings na enige NAT-verandering, want gevestigde toestand hou die ou koppeling:
wg show wg0 allowed-ips
sudo nft list ruleset
curl -sS -o /dev/null -w "%{http_code}\n" https://site-a.example.net/
'n Lee of onverwagte alias in die eerste opdrag beteken die peer-keuse is verkeerd voordat enige firewall-reël saak maak. As die alias reg is en die naam werk steeds nie, het die probleem na DNS en sertifikate geskuif. Sodra albei name antwoord en die derde poort gesluit bly, doen die ontwerp wat dit sê: twee nou gepubliseerde dienste, nie twee saamgesmelte LAN's nie.