Tilkoplings-hooks på ein VPN-daemon køyrer som daemonen, og det tyder vanlegvis at dei køyrer som root. I det augneblinken ein av desse hookane skriv i heimekatalogen til nokon eller startar ein skrivebordshjelpar på nytt, har du gjeve ei nettverkshending evna til å handle som ein vilkårleg lokal brukar. Den vanlege snarvegen, å lese eit brukarnamn frå ein miljøvariabel og sende det vidare, rettar ikkje dette. Han merkar berre handlinga på nytt utan å endre kva konto som utfører henne. Det som verkar, er ei overlevering i tre delar, der det privilegerte trinnet seier kva som hende, og ei eiga eining utfører handlinga under rett identitet.

Eit brukarnamn i miljøet er ikkje ein identitetsbrytar

Unix avgjer kva ein prosess får røre ut frå sin effektive brukar-ID, ikkje ut frå strengane i miljøet sitt. Å setje USER=alice eller eksportere LOGNAME endrar kva uforsiktig programvare skriv ut i utdataa; det endrar ingenting i eigarskapskontrollane av filer. Ein hook som køyrer som root med den variabelen sett, opnar framleis filene til Alice som root.

Namna er heller ikkje det same namnet. Fjerninnlogginga, den lokale Unix-kontoen og det vanlege namnet på sertifikatet er tre identifikatorar som ofte fell saman og stundom ikkje. Ein brukar som autentiserer seg som a.smith, har kanskje ingen lokal konto i det heile, eller blir mappa til asmith via ein katalogteneste. Eitkvart design som føreset at éin streng tener alle tre rollene, vil bryte saman hos den første innleigde konsulenten.

Så det første spørsmålet er ikkje «kva brukar er tilkopla», men «kva lokal konto har lov til å utføre denne handlinga». Svar på det frå din eigen kontodatabase, ikkje frå det klienten sende:

id -u alice
getent passwd alice | cut -d: -f1,3,6
stat -c '%U:%G %a %n' /home/alice/.local/state/vpn-status.json

Den tredje kommandoen er den folk hoppar over. Viss målfilen er eigd av root fordi den førre hooken oppretta han, vil ei rett konfigurert brukarhandling feile med ein tilgangsfeil som ser ut som eit systemd-problem og ikkje er det.

Daemonen blir der han er

Å endre VPN-tenesta sin eigen User= til Alice er feil spak. Det endrar korleis daemonen bind grensesnitt, les nøklar, skriv statusfila si og styrer ruter, og det flyttar all denne risikoen inn i ei eining som fungerte. Daemonen treng privilegia sine; oppfølgingshandlinga gjer det ikkje.

Sjå kva eininga faktisk gjer før du rører henne. To kommandoar fortel deg køyreidentiteten og dei nøyaktige kommandolinjene som gjeld, inkludert alt ei overstyring har lagt til:

systemctl show -p User -p Group -p ExecStart openvpn-server@server
systemctl cat openvpn-server@server

Ved ein standard pakkeinstallasjon er daemonen root, og --up-skriptet arvar det. Stadfest det i staden for å føresetje det, fordi ein herda distribusjon kan ha flytta det til ein dedikert konto, og ein handskriven drop-in kan køyre hooken gjennom ei innpakning med andre reglar.

Tre namngjevne delar, éin smal utløysar

Ordninga som overlever vedlikehald, har ei hending, ein utløysar og ei handling. Daemonen rapporterer at ei namngjeven økt er oppe. Ein utløysar godtek det vesle faktumet og ber om éi fast handling. Handlinga køyrer under den lokale kontoen som eig filene ho rører. Ingenting i kjeda godtek ein vilkårleg kommandobane.

Sjølve handlinga er ei vanleg tenesteeining, og identiteten er eitt direktiv inne i henne:

[Service]
Type=oneshot
User=alice
Group=alice
ExecStart=/usr/local/bin/refresh-vpn-status --slot %i

Legg merke til at User=alice gjeld for heile eininga, og systemd dokumenterer eitt unntak som er verdt å kjenne: ein kommando med prefikset + køyrer med fulle privilegium uansett. Det prefikset er eit legitimt verktøy for eitt einskilt privilegert trinn og ein praktisk måte å oppheve separasjonen du nettopp bygde, så handsam kva som helst + i den eininga som noko som må grunngivast i gjennomgangen.

Hald inndataa til utløysaren minimale og ikkje-hemmelege. Øktidentifikatoren, den mappa kontoen og eit tidsstempel er vanlegvis alt som trengst. Send aldri eit shell-fragment, ein køyrbar filbane eller ein klientlevert miljøblokk over grensa, fordi mottakarsida ikkje har nokon måte å skilje ein legitim verdi frå ein injisert.

Stadfest identiteten som faktisk køyrde

Konfigurasjonsgjennomgang er ikkje prov. Etter ei godkjend testtilkopling, stadfest UID-en som rørte fila, og UID-en som daemonen framleis brukar:

stat -c '%U %G %y %n' /home/alice/.local/state/vpn-status.json
ps -o user=,pid=,cmd= -p "$(pgrep -o -f 'openvpn --daemon')"
systemd-run --uid=alice --pipe /usr/local/bin/refresh-vpn-status --dry-run

Den første linja bør vise Alice og eit tidsstempel innanfor testvindauget ditt. Den andre bør framleis vise root eller tenestekontoen til pakken, noko som provar at daemonen ikkje flytta seg. Den tredje er den billegaste måten å teste løyva til handlinga på utan å vente på ei ekte attoppkopling.

Viss eigaren av fila er Alice, men gruppa eller modusen endra seg mellom køyringar, sjå etter ein UMask= eller ein skilnad i katalogrettar i staden for ein logikkfeil. Viss tidsstempelet ikkje flytta seg i det heile, vart utløysaren aldri utløyst, og det nyttige neste steget er journalctl -u for handlingseininga i staden for nok ei klientattoppkopling.

Kva ei tilkoplinghending framleis ikkje provar

Ein etablert tunnel er eitt faktum. Det tyder ikkje at skrivebordsøkta er låst opp, at øktbussen er tilgjengeleg, eller at den private ressursen handlinga vil ha, allereie er tilgjengeleg. Ei oneshot-eining under UID-en til Alice har identiteten hennar og ingenting av økta hennar, så alt som krev ein grafisk buss, må gå gjennom den støtta brukarøktmekanismen og definere kva som skjer når ho er logga ut.

Attoppkoplingar gjentek seg også. Ein berbar pc som søv på eit tog, kan produsere eit dusin tilkoplinghendingar på ein time, og ein hook som legg til ei linje kvar gong, gjer ei statusfil til ein logg ingen kan lese. Gjer handlinga idempotent, eller la henne erstatte éin post med nøkkel på økt.

Til slutt, avgrens skaderadiusen i sjølve eininga: ein skriveverna vising av filsystemet utanfor statuskatalogen, ingen nye privilegium og ein eksplisitt tidsavbrot. Separasjonen mellom daemon og brukarhandling er verdt noko i seg sjølv, men han er verdt mykje meir når handlinga ikkje kan gjere noko anna enn det eine du godkjende.

Relaterte artiklar