Å returnere en adresse fra et client-connect-skript ser ut som det skal sette klientens IP. Det gjør det ikke: hookens eneste kanal til serveren er en midlertidig fil hvis sti kommer som skriptets siste argument, og adressen må skrives der i ifconfig-push-syntaks. Et skript som skriver ut adressen eller avslutter med null uten å skrive noe, gir en tilkoblet klient med en adresse fra puljen, og serverloggen ser helt sunn ut.

Forvirringen er rimelig, fordi flere andre hooks faktisk svarer via exit-koder eller miljøvariabler. Denne har sin egen kontrakt, og kontrakten begynner med et filnavn.

Hooken skriver en fil, ikke en returverdi

Deklarasjonen er to linjer: script-security 2 for å tillate kallet, deretter client-connect /etc/openvpn/server/assign-address.sh. Når en klient autentiserer seg, kjører serveren det skriptet med den genererte filstien lagt til som siste argument, som bare er $1 hvis deklarasjonen ikke sender egne ekstra argumenter. Alt som brukes på den klienten, går i den filen som vanlige direktiver, ett per linje, akkurat slik de ville stått i en konfigurasjon. En wrapper som legger til sine egne parametere, forskyver posisjonen, og det klassiske symptomet er et skript som skriver til en sti som ligner --verbose.

Exit-statusen er den andre halvdelen av kontrakten. Null betyr godta og les filen; alt annet avviser tilkoblingen, og det er slik en ikke-mappet identitet blir nektet i stedet for stille å falle tilbake til puljen. Skriv det komplette direktivet før du returnerer suksess, så en halvskrevet fil aldri blir en klients konfigurasjon.

To direktiver fortjener oppmerksomhet fordi de samhandler med alt annet. ifconfig-push låser adressen, mens en sendt route forteller klienten hva som er tilgjengelig gjennom tunnelen; returner den første og glem den andre, og du får en klient med adresse og ingen steder å gå. Rekkefølgen i filen spiller ingen rolle, men fullstendigheten gjør det. En hook som sender en rute for et prefiks ingen peer kan nå, er den samme feilen sett fra den andre enden.

Inndata kommer via miljøvariabler: common_name, trusted_ip, ifconfig_pool_remote_ip og resten. Behandle dem alle som strenger utenfra serveren, aldri som shell-fragmenter.

Adressemapping er en policy, ikke aritmetikk

En fristende snarvei er å parse sertifikatnavnet og bruke sifrene som siste oktett. Det er ikke en allokator, og det feiler på vanlige måter: to navn med samme suffiks kolliderer, et navn som ender på 300 er ikke en adresse, og et sertifikat en administrator gir nytt navn, flytter stille en enhet. Valider subnettilhørighet, det brukbare vertsområdet, reserverte adresser og unikhet ved hvert kall, og hold mappingen i en tabell et menneske kan lese.

Den som kontrollerer navnet, kontrollerer adressen, så avgjør hva common_name egentlig representerer i denne utrullingen. Med username-as-common-name aktivert er identiteten innloggingen og ikke sertifikatets subjekt. Send aldri den verdien inn i shell-evaluering, og la aldri klienten påvirke en filsti.

En registerbasert allokator må tåle samtidighet. Reserver adressen atomisk, håndter en mislykket skriving uten å slippe inn en halvkonfigurert klient, og merk hver tildeling med tilkoblingen som eier den, slik at en sen frakobling fra en eldre økt ikke kan frigjøre en adresse som en nyere allerede holder. Flere serverinstanser som deler én pulje gjør kravet skarpere i stedet for valgfritt.

Topologien avgjør hva ifconfig-push betyr

Med topology subnet på 10.77.0.0/24 er ifconfig-push 10.77.0.20 255.255.255.0 en adresse pluss nettmasken. Under topology net30 er det andre argumentet slett ikke en maske, men peer-adressen, så kopiering av subnetformen til en net30-server gir deg en klient som assosierer og ikke kan føre trafikk. Endre topologien med vilje, aldri for at et eksempel skal se konsistent ut. En server som allerede kjører net30, har levende klienter på den gamle adresseringen, så byttet er en migrering med vedlikeholdsvindu, ikke en enlinjes rettelse.

Statiske adresser må ligge utenfor den dynamiske puljen og utenfor enhver annen statisk tildeling, inkludert dem som deles ut av vanlige client-config-dir-filer. Hvis to mekanismer kan produsere samme adresse for forskjellige klienter, vil en av dem til slutt gjøre det.

Test fire tilfeller før du stoler på det

Kjør de samme kontrollene mot en mappet identitet, en ikke-mappet, en gjenoppkobling og en simulert registerfeil. openvpn --config client.ovpn --verb 4 viser den tildelte adressen i push-svaret, og på serveren bekrefter grep -A2 PUSH_REPLY /var/log/openvpn/openvpn.log hva som faktisk ble sendt. For den ikke-mappede identiteten er det forventede resultatet en avvist tilkobling, ikke en adresse fra puljen.

Undersøk deretter katalogen daemonen skriver de midlertidige filene i. Skriptet kjører i den nedgraderte tjenestekonteksten, så en sti som root kan skrive til, men daemonen ikke, gjør hver tilkobling til en avvisning med en tillatelsesfeil begravd flere linjer ned i loggen.

Tildeling er ikke autorisasjon: en festet adresse gir fortsatt ikke tilgang til hver destinasjon bak serveren. Hold ruting- og brannmurpolicyen i sitt eget lag, og verifiser den mot adressen du nettopp festet.

Relaterte artikler