OpenVPN client-connect-hook: hvor din adresse egentlig ender
Et client-connect-script kan ikke returnere en adresse ved at printe den. Se hvordan hookets midlertidige fil, exitstatus og topologi bestemmer klientens IP.
At returnere en adresse fra et client-connect-script ser ud til at skulle sætte klientens IP. Det gør det ikke: hookets eneste kanal til serveren er en midlertidig fil, hvis sti kommer som scriptets sidste argument, og adressen skal skrives der i ifconfig-push-syntaks. Et script, der printer adressen eller afslutter med nul uden at skrive noget, giver en forbundet klient med en adresse fra puljen, og serverloggen ser helt sund ud.
Forvirringen er rimelig, fordi flere andre hooks faktisk svarer via exitkoder eller miljøvariabler. Denne har sin egen kontrakt, og kontrakten begynder med et filnavn.
Hooket skriver en fil, ikke en returværdi
Deklarationen er to linjer: script-security 2 for at tillade kaldet, derefter client-connect /etc/openvpn/server/assign-address.sh. Når en klient autentificerer, kører serveren det script med den genererede filsti tilføjet som sidste argument, som kun er $1, hvis deklarationen ikke selv sender ekstra argumenter. Alt, hvad der anvendes på den klient, går i den fil som almindelige direktiver, ét pr. linje, præcis som de ville stå i en konfiguration. En wrapper, der tilføjer sine egne parametre, flytter positionen, og det klassiske symptom er et script, der skriver til en sti, der ligner --verbose.
Exitstatus er den anden halvdel af kontrakten. Nul betyder accepter og læs filen; alt andet afviser forbindelsen, og det er sådan en ikke-mappet identitet bliver nægtet i stedet for stille at falde tilbage til puljen. Skriv det komplette direktiv, før du returnerer succes, så en halvskrevet fil aldrig bliver en klients konfiguration.
To direktiver fortjener opmærksomhed, fordi de interagerer med alt andet. ifconfig-push fastlåser adressen, mens en sendt route fortæller klienten, hvad der kan nås gennem tunnelen; returner den første og glem den anden, og du får en klient med en adresse og ingen steder at gå hen. Rækkefølgen i filen er ligegyldig, men fuldstændigheden er ikke. Et hook, der sender en rute for et præfiks, ingen peer kan nå, er den samme fejl set fra den anden ende.
Input kommer via miljøvariabler: common_name, trusted_ip, ifconfig_pool_remote_ip og resten. Behandl dem alle som strenge udefra serveren, aldrig som shell-fragmenter.
Adressemapping er en politik, ikke aritmetik
En fristende genvej er at parse certifikatnavnet og bruge dets cifre som den sidste oktet. Det er ikke en allokator, og det fejler på almindelige måder: to navne med samme suffiks kolliderer, et navn, der ender på 300, er ikke en adresse, og et certifikat, en administrator omdøber, flytter stille en enhed. Validér subnettilhørsforhold, det brugbare værtsinterval, reserverede adresser og unikhed ved hvert kald, og hold mappingen i en tabel, et menneske kan læse.
Den, der kontrollerer navnet, kontrollerer adressen, så beslut, hvad common_name egentlig repræsenterer i denne udrulning. Med username-as-common-name aktiveret er identiteten login, ikke certifikatets emne. Send aldrig den værdi ind i shell-evaluering, og lad aldrig klienten påvirke en filsti.
En registerbaseret allokator skal overleve samtidighed. Reservér adressen atomisk, håndter en mislykket skrivning uden at lukke en halvkonfigureret klient ind, og mærk hver tildeling med den forbindelse, der ejer den, så en sen afbrydelse fra en ældre session ikke kan frigive en adresse, som en nyere allerede holder. Flere serverinstanser, der deler én pulje, gør det krav skarpere i stedet for valgfrit.
Topologien afgør, hvad ifconfig-push betyder
Med topology subnet på 10.77.0.0/24 er ifconfig-push 10.77.0.20 255.255.255.0 en adresse plus dens netmaske. Under topology net30 er det andet argument slet ikke en netmaske, men peer-adressen, så kopiering af subnetformen til en net30-server giver dig en klient, der associerer og ikke kan føre trafik. Skift topologien med vilje, aldrig for at få et eksempel til at se konsistent ud. En server, der allerede kører net30, har levende klienter på den gamle adressering, så skiftet er en migrering med et vedligeholdelsesvindue, ikke en enlinjes rettelse.
Statiske adresser skal ligge uden for den dynamiske pulje og uden for enhver anden statisk tildeling, herunder dem, der uddeles af almindelige client-config-dir-filer. Hvis to mekanismer kan producere samme adresse til forskellige klienter, vil en af dem til sidst gøre det.
Test fire tilfælde, før du stoler på det
Kør de samme kontroller mod en mappet identitet, en ikke-mappet, en genopkobling og en simuleret registerfejl. openvpn --config client.ovpn --verb 4 viser den tildelte adresse i push-svaret, og på serveren bekræfter grep -A2 PUSH_REPLY /var/log/openvpn/openvpn.log, hvad der faktisk blev sendt. For den ikke-mappede identitet er det forventede resultat en afvist forbindelse, ikke en adresse fra puljen.
Undersøg derefter den mappe, dæmonen skriver de midlertidige filer i. Scriptet kører i den nedgraderede servicekontekst, så en sti, som root kan skrive til, men dæmonen ikke, gør hver forbindelse til en afvisning med en tilladelsesfejl begravet flere linjer nede i loggen.
Tildeling er ikke autorisation: en fastlåst adresse giver stadig ikke adgang til hver destination bag serveren. Hold routing- og firewallpolitikken i sit eget lag, og verificér den mod den adresse, du netop har fastlåst.