OpenVPN client-connect-krok: kvar adressa di eigentleg hamnar
Eit client-connect-skript kan ikkje returnere ei adresse ved å skrive ho ut. Sjå korleis den mellombelse fila til kroken, exit-statusen og topologien avgjer IP-en til klienten.
Å returnere ei adresse frå eit client-connect-skript ser ut som det skal setje IP-en til klienten. Det gjer det ikkje: den einaste kanalen kroken har til tenaren, er ei mellombels fil der stien kjem som det siste argumentet til skriptet, og adressa må skrivast der i ifconfig-push-syntaks. Eit skript som skriv ut adressa eller endar med null utan å skrive noko, gjev ein tilkopla klient med ei adresse frå bassenget, og tenarloggen ser heilt sunn ut.
Forvirringa er rimeleg, fordi fleire andre krok svarar gjennom exit-kodar eller miljøvariablar. Denne har sin eigen kontrakt, og kontrakten byrjar med eit filnamn.
Kroken skriv ei fil, ikkje ein returverdi
Deklarasjonen er to linjer: script-security 2 for å tillate kallet, deretter client-connect /etc/openvpn/server/assign-address.sh. Når ein klient autentiserer seg, køyrer tenaren det skriptet med den genererte filstien lagd til som siste argument, som berre er $1 om deklarasjonen ikkje sender eigne ekstra argument. Alt som vert brukt på den klienten, går i den fila som vanlege direktiv, eitt per linje, nøyaktig slik dei ville stått i ein konfigurasjon. Ein wrapper som legg til sine eigne parameterar, forskyv posisjonen, og det klassiske symptomet er eit skript som skriv til ein sti som liknar --verbose.
Exit-statusen er den andre halvdelen av kontrakten. Null tyder godta og les fila; alt anna avviser tilkoplinga, og slik vert ein ikkje-mappa identitet nekta i staden for stille å falle tilbake til bassenget. Skriv det komplette direktivet før du returnerer suksess, så ei halvskriven fil aldri vert konfigurasjonen til ein klient.
To direktiv fortener merksemd fordi dei samverkar med alt anna. ifconfig-push festar adressa, medan ein send route fortel klienten kva som er tilgjengeleg gjennom tunnelen; returner den første og gløym den andre, og du får ein klient med adresse og ingen stad å gå. Rekkjefølgja i fila speler inga rolle, men fullstendigheiten gjer det. Ein krok som sender ei rute for eit prefiks ingen jamlike kan nå, er den same feilen sett frå den andre enden.
Inndata kjem via miljøvariablar: common_name, trusted_ip, ifconfig_pool_remote_ip og resten. Handsame dei alle som strengar utanfrå tenaren, aldri som shell-fragment.
Adressemapping er ein politikk, ikkje aritmetikk
Ein freistande snareveg er å parse sertifikatnamnet og bruke sifra som siste oktett. Det er ikkje ein allokator, og det feilar på vanlege måtar: to namn med same suffiks kolliderer, eit namn som endar på 300 er ikkje ei adresse, og eit sertifikat ein administrator gjev nytt namn, flyttar stille ein eining. Valider subnettilhøyrsle, det brukbare vertsområdet, reserverte adresser og unikskap ved kvart kall, og hald mappinga i ein tabell eit menneske kan lese.
Den som styrer namnet, styrer adressa, så avgjer kva common_name eigentleg representerer i denne utrullinga. Med username-as-common-name aktivert er identiteten innlogginga og ikkje subjektet til sertifikatet. Send aldri den verdien inn i shell-evaluering, og lat aldri klienten påverke ein filsti.
Ein registerbasert allokator må tole samtidigheit. Reserver adressa atomisk, handter ei mislukka skriving utan å sleppe inn ein halvkonfigurert klient, og merk kvar tildeling med tilkoplinga som eig ho, slik at ein sein fråkopling frå ei eldre økt ikkje kan frigje ei adresse som ei nyare alt held. Fleire tenarinstansar som deler eitt basseng gjer kravet skarpare i staden for valfritt.
Topologien avgjer kva ifconfig-push tyder
Med topology subnet på 10.77.0.0/24 er ifconfig-push 10.77.0.20 255.255.255.0 ei adresse pluss nettmaska. Under topology net30 er det andre argumentet slett ikkje ei maske, men jamlikeadressa, så kopiering av subnetforma til ein net30-tenar gjev deg ein klient som assosierer og ikkje kan føre trafikk. Endre topologien med vilje, aldri for at eit døme skal sjå konsistent ut. Ein tenar som alt køyrer net30, har levande klientar på den gamle adresseringa, så bytet er ein migrasjon med vedlikehaldsvindauge, ikkje ei einlinjes retting.
Statiske adresser må liggje utanfor det dynamiske bassenget og utanfor kvar annan statisk tildeling, inkludert dei som vert delte ut av vanlege client-config-dir-filer. Viss to mekanismar kan produsere same adresse for ulike klientar, vil ein av dei til slutt gjere det.
Test fire tilfelle før du stolar på det
Køyr dei same kontrollane mot ein mappa identitet, ein ikkje-mappa, ei attoppkopling og ein simulert registerfeil. openvpn --config client.ovpn --verb 4 viser den tildelte adressa i push-svaret, og på tenaren stadfestar grep -A2 PUSH_REPLY /var/log/openvpn/openvpn.log kva som faktisk vart sendt. For den ikkje-mappede identiteten er det venta resultatet ei avvist tilkopling, ikkje ei adresse frå bassenget.
Undersøk deretter mappa der daemonen skriv dei mellombelse filene. Skriptet køyrer i den nedgraderte tenestekonteksten, så ein sti som root kan skrive til, men daemonen ikkje, gjer kvar tilkopling til ei avvising med ein tilgangsfeil gravlagd fleire linjer ned i loggen.
Tildeling er ikkje autorisasjon: ei fastsett adresse gjev framleis ikkje tilgang til kvar destinasjon bak tenaren. Hald rutings- og brannmurpolitikken i sitt eige lag, og verifiser han mot adressa du nettopp festa.