Du site'ai, vienas potinklis, vienas WireGuard šakas: paleiskite tai
Abu LAN yra 10.10.7.0/24, todėl šakas negali pasirinkti site'o pagal paskirtį. Suteikite kiekvienai paslaugai alias ir verskite jos šliuze.
Abu site'ai naudoja tą patį LAN diapazoną, ir dizainą iš tiesų laužo ne persidengimas. Šakas turi pasirinkti site'ą tik pagal paskirties adresą, o du identiški tikslai neduoda jam nieko, pagal ką rinktis. Veikiančio biuro pernumeravimas, kad tilptų tunelis, paprastai yra blogesnis mainas nei suteikti kiekvienai publikuojamai paslaugai atskirą adresą, kurį tunelis gali pernešti. Toliau pateiktas dizainas publikuoja vieną HTTPS paslaugą kiekvienam site'ui ir nieko daugiau.
Kodėl persidengimas nėra tikroji problema
WireGuard persiunčia pagal paskirtį: peer'o AllowedIPs nusprendžia, kuris peer'as gaus paketą. Du peer'ai negali abu skelbti 10.10.7.0/24, jei vienas iš jų nelaimi kiekvienos paieškos. Tai peer'ų lentelės, o ne tunelio savybė, todėl sprendimas čia yra adresų planas, o ne maršrutizavimo triukas.
Planas yra visiškai nustoti skelbti LAN. Vietoj to skelbkite alias kiekvienai paslaugai, po vieną adresą kiekvienam site'ui, ir leiskite kiekvieno site'o šliuzui išversti tą alias į savo tikrąją programą.
Naudotojas maršrutizuoja du unikalius adresus, niekada nemato dviprasmio prefikso, ir nė viename iš dviejų biurų niekas nesikeičia. Tai taip pat sąžiningai įvardija ribą: jūs publikuojate vieną HTTPS paslaugą iš kiekvieno site'o, o ne sujungiate du tinklus. Toliau pateiktos taisyklės lieka mažos, nes teiginys yra siauras. Platesniam teiginiui reikėtų platesnių taisyklių, ir būtent taip šie dizainai tampa sudėtingi.
Suteikite kiekvienam site'ui alias, kurį naudotojas gali maršrutizuoti
Pasirinkite adresus iš diapazono, kuris nesusiduria su niekuo naudotojo kompiuteryje, šake ar bet kuriame iš dviejų LAN. Čia šakas yra 10.66.0.1, naudotojas 10.66.0.10, šliuzai 10.66.0.21 ir 10.66.0.22, o du alias 10.77.1.20 ir 10.77.2.20. Šakas publikuoja kiekvieną alias per tą peer'ą, kuriam jis priklauso, todėl išeinantis paketas, adresuotas vienam alias, gali išeiti tik per atitinkamą site'ą:
[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
Naudotojo pusei reikia tik dviejų alias, o tai palieka kliento konfigūraciją be abiejų LAN prefiksų. Niekas toje konfigūracijoje nemini nė vieno tikro 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
Kiekvienas šliuzas skelbia šaką ir naudotojo šaltinį, nieko daugiau, todėl site'as niekada nesužino kito site'o LAN. Keepalive palaiko NAT susiejimą site'o uplink'e; jis neįgalina srauto, o ugniasienė vis dar sprendžia, kas įleidžiama. Vieno šliuzo konfigūracijos kopijavimas į kitą yra gerai, jei privatus raktas, sąsajos adresas ir alias visi keičiasi.
Ką šakas turi leisti tarp dviejų savo peer'ų
Šakas persiunčia paketus tarp dviejų savo peer'ų, o tai yra forward grandinės sprendimas, o ne įvesties sprendimas. Įjunkite IPv4 persiuntimą įprastu platformos mechanizmu, tada leiskite būtent tas poras, kurių reikia dizainui.
Žemiau pateikta taisyklė leidžia naudotojui vieną alias ir vieną prievadą, ir leidžia grįžtamąjį srautą per jungčių sekimą. Ji atmeta visa kita forward kelyje, ir tai yra esmė:
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
Du dalykai verti paminėjimo, nes jie sukelia tylias klaidas. Accept vienoje bazinėje grandinėje nepanaikina drop kitoje, todėl suliekite tai su esama politika, o ne įkelkite šalia. Ir šaltinio adresas identifikuoja įrenginį, o ne asmenį; laikykite programos autentifikavimą atskirai nuo tinklo priėmimo.
Kur alias tampa tikru adresu
Site'as A gauna užklausą 10.77.1.20, perrašo paskirtį į tikrąją programą ir perrašo šaltinį į savo LAN adresą, kad atsakymas galėtų grįžti be maršruto į tunelį. Abiejų vertimų atlikimas vienoje vietoje palieka likusį tinklą nežinantį apie alias. Žemiau pateiktos taisyklės yra visas mechanizmas:
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
Tada site'o A forward politika turi leisti išverstą srautą iš tunelio sąsajos į LAN sąsają, be to, grįžimo kryptį. Forward hook'as mato paskirtį po paskirties vertimo ir prieš šaltinio perrašymą, todėl taisyklė įvardija tikrosios programos adresą. Skaitykite tuos du hook'us tokia tvarka, kai taisyklė atrodo nieko neatitinkanti. Forward taisyklė, parašyta prieš alias, niekada negali atitikti, nes alias to hook'o metu nebeegzistuoja.
Site'as B kartoja tai su savo alias ir savo raktu. Jis neturi naudoti iš naujo site'o A privataus rakto, nes du peer'ai, dalijantys vieną tapatybę, yra konfigūracijos klaida, kurią sunku pastebėti ir lengva sukurti kopijuojant failą. Laikykite abu šliuzo dokumentus identiškus, išskyrus reikšmes, kurios turi skirtis, kad skirtumas išryškėtų peržiūros metu. Nukopijuotas failas yra įprasta tos klaidos priežastis.
Šaltinio perrašymas turi kainą. Programa mato šliuzą kaip savo klientą, todėl jos žurnalai neberodo, kuris naudotojas prisijungė. Išsaugokite šliuzo audito pėdsaką ir nesusilpninkite programos prisijungimo, kad kompensuotumėte tinklo tapatybę, kurią pašalino vertimas.
Kaip įrodyti, kad abu publikuoti vardai atsako
Suteikite kiekvienam alias DNS vardą ir sukonfigūruokite programą bei sertifikatą tam vardui, nes vertimas neperrašo peradresavimų ar įterptų absoliučių URL. Naudokite vieną vardą kiekvienam site'ui, kad sertifikato neatitikimas niekada nebūtų supainiotas su maršrutizavimo gedimu.
Testuokite iš tikro kliento, patvirtinkite, kuris site'as atsakė, ir išbandykite neleistiną prievadą. Po bet kokio NAT pakeitimo naudokite naujas jungtis, nes nustatyta būsena išlaiko seną susiejimą:
wg show wg0 allowed-ips
sudo nft list ruleset
curl -sS -o /dev/null -w "%{http_code}\n" https://site-a.example.net/
Tuščias ar netikėtas alias pirmoje komandoje reiškia, kad peer'o pasirinkimas yra neteisingas dar prieš tai, kai bet kuri ugniasienės taisyklė turi reikšmės. Jei alias teisingas, o vardas vis tiek neveikia, problema persikėlė į DNS ir sertifikatus. Kai abu vardai atsako, o trečias prievadas lieka uždarytas, dizainas daro tai, ką teigia: dvi siaurai publikuotos paslaugos, o ne du sujungti LAN.