Mae bachau cysylltu daemon VPN yn rhedeg fel y daemon, ac fel arfer mae hynny’n golygu eu bod yn rhedeg fel root. Yr eiliad y bydd un o’r bachau hynny’n ysgrifennu yng nghyfeiriad cartref rhywun neu’n ailddechrau cynorthwyydd bwrdd gwaith, rydych wedi rhoi gallu i ddigwyddiad rhwydwaith weithredu fel unrhyw ddefnyddiwr lleol. Nid yw’r ffordd fyr arferol, sef darllen enw defnyddiwr o newidyn amgylchedd a’i basio ymlaen, yn unioni hynny. Mae’n ailenwi’r weithred heb newid pa gyfrif sy’n ei chyflawni. Yr hyn sy’n gweithio yw trosglwyddiad tair rhan lle mae’r cam breiniol yn dweud beth ddigwyddodd ac mae uned ar wahân yn gwneud y weithred o dan yr hunaniaeth gywir.

Nid yw enw defnyddiwr yn yr amgylchedd yn switsh hunaniaeth

Mae Unix yn penderfynu beth y gall proses gyffwrdd ag ef o’i ID defnyddiwr effeithiol, nid o’r llinynnau yn ei hamgylchedd. Mae gosod USER=alice neu allforio LOGNAME yn newid beth mae meddalwedd ddiofal yn ei argraffu yn ei allbwn; nid yw’n newid dim yng ngwiriadau perchnogaeth ffeiliau. Mae hook sy’n rhedeg fel root gyda’r newidyn hwnnw wedi’i osod yn dal i agor ffeiliau Alice fel root.

Nid yw’r enwau ychwaith yr un enw. Mae mewngofnodi mynediad o bell, y cyfrif Unix lleol ac enw cyffredin y dystysgrif yn dri dynodwr sy’n aml yn cyd-daro ac weithiau ddim. Efallai nad oes gan ddefnyddiwr sy’n dilysu fel a.smith unrhyw gyfrif lleol o gwbl, neu efallai ei fod yn mapio i asmith trwy wasanaeth cyfeiriadur. Bydd unrhyw ddyluniad sy’n tybio bod un llinyn yn gwasanaethu’r tair rôl yn torri ar y contractwr cyntaf.

Felly’r cwestiwn cyntaf yw nid «pa ddefnyddiwr sy’n gysylltiedig» ond «pa gyfrif lleol sydd â chaniatâd i wneud y weithred hon». Atebwch hynny o’ch cronfa ddata gyfrifon eich hun, nid o’r hyn a anfonodd y cleient:

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

Y drydedd orchymyn yw’r un y mae pobl yn ei hepgor. Os yw’r ffeil darged yn eiddo i root oherwydd bod y hook blaenorol wedi’i chreu, bydd gweithred defnyddiwr a gyfluniwyd yn gywir yn methu â gwall caniatâd sy’n edrych fel problem systemd ac nad yw.

Mae’r daemon yn aros lle mae

Mae newid User= y gwasanaeth VPN ei hun i Alice yn y lifer anghywir. Mae’n newid sut mae’r daemon yn clymu rhyngwynebau, yn darllen allweddi, yn ysgrifennu ei ffeil statws ac yn rheoli llwybrau, ac mae’n symud yr holl risg honno i uned a oedd yn gweithio. Mae ar y daemon angen ei freintiau; nid oes ar y weithred ddilynol eu hangen.

Edrychwch beth mae’r uned yn ei wneud mewn gwirionedd cyn ei chyffwrdd. Mae dwy orchymyn yn dweud yr hunaniaeth gyflawni a’r llinellau gorchymyn union sydd mewn grym, gan gynnwys unrhyw beth a ychwanegwyd gan ddiystyriad:

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

Ar osodiad pecyn diofyn mae’r daemon yn root ac mae sgript --up yn etifeddu hynny. Cadarnhewch hynny yn lle tybio, oherwydd efallai bod dosbarthiad caled wedi’i symud i gyfrif pwrpasol, ac efallai bod drop-in wedi’i ysgrifennu â llaw yn rhedeg y hook trwy lapio â rheolau gwahanol.

Tri rhan a enwir, un sbardun cul

Mae gan y drefniant sy’n goroesi cynnal a chadw ddigwyddiad, sbardun a gweithred. Mae’r daemon yn adrodd bod sesiwn a enwir wedi codi. Mae sbardun yn derbyn y ffaith fach honno ac yn gofyn am un weithred sefydlog. Mae’r weithred yn rhedeg o dan y cyfrif lleol sy’n berchen ar y ffeiliau y mae’n cyffwrdd â nhw. Nid oes dim yn y gadwyn yn derbyn llwybr gorchymyn mympwyol.

Mae’r weithred ei hun yn uned gwasanaeth gyffredin, a’r hunaniaeth yw un cyfarwyddeb y tu mewn iddi:

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

Sylwch fod User=alice yn berthnasol i’r uned gyfan, ac mae systemd yn dogfennu un eithriad sy’n werth ei wybod: mae gorchymyn â’r rhagddodiad + yn rhedeg gyda phob braint beth bynnag. Mae’r rhagddodiad hwnnw’n offeryn cyfreithlon ar gyfer un cam breiniol ac yn ffordd gyfleus o ddadwneud y gwahanu yr ydych newydd ei adeiladu, felly triniwch unrhyw + yn yr uned honno fel rhywbeth i’w gyfiawnhau wrth adolygu.

Cadwch fewnbwn y sbardun yn fach ac yn ansicr. Mae’r dynodwr sesiwn, y cyfrif wedi’i fapio a stamp amser fel arfer yn ddigon. Peidiwch byth â phasio darn plisgyn, llwybr gweithredadwy na bloc amgylchedd a ddarparwyd gan y cleient dros y ffin, oherwydd nid oes gan yr ochr sy’n derbyn ffordd o wahaniaethu gwerth cyfreithlon oddi wrth un wedi’i chwistrellu.

Gwiriwch yr hunaniaeth a redodd mewn gwirionedd

Nid yw adolygu cyfluniad yn dystiolaeth. Ar ôl cysylltiad prawf a gymeradwywyd, cadarnhewch yr UID a gyffyrddodd â’r ffeil a’r UID y mae’r daemon yn dal i’w ddefnyddio:

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

Dylai’r llinell gyntaf ddangos Alice a stamp amser o fewn eich ffenestr brawf. Dylai’r ail ddangos root o hyd neu gyfrif gwasanaeth y pecyn, sy’n profi na symudodd y daemon. Y drydedd yw’r ffordd rataf o brofi caniatâd y weithred heb aros am ailosodiad go iawn.

Os mai Alice yw perchennog y ffeil ond bod ei grŵp neu ei fodd wedi newid rhwng rhediadau, chwiliwch am UMask= neu wahaniaeth caniatâd cyfeiriadur yn lle gwall rhesymeg. Os na symudodd y stamp amser o gwbl, ni thaniwyd y sbardun erioed, a’r cam nesaf defnyddiol yw journalctl -u ar gyfer uned y weithred yn lle ailgysylltiad cleient arall.

Yr hyn nad yw digwyddiad cysylltu’n ei brofi o hyd

Mae twnnel sefydledig yn un ffaith. Nid yw’n golygu bod sesiwn y bwrdd gwaith wedi’i datgloi, bod y bws sesiwn yn gyrraeddadwy, na bod yr adnodd preifat y mae’r weithred yn ei eisiau ar gael eto. Mae gan uned oneshot o dan UID Alice ei hunaniaeth a dim o’i sesiwn, felly rhaid i unrhyw beth sy’n gofyn am fws graffigol fynd trwy’r mecanwaith sesiwn defnyddiwr a gefnogir a diffinio beth sy’n digwydd pan fydd hi wedi allgofnodi.

Mae ailgysylltiadau hefyd yn ailadrodd. Gall gliniadur sy’n cysgu ar drên gynhyrchu dwsin o ddigwyddiadau cysylltu mewn awr, ac mae hook sy’n ychwanegu llinell bob tro yn troi ffeil statws yn gofnod na all neb ei ddarllen. Gwnewch y weithred yn idempotent, neu gadewch iddi ddisodli un cofnod wedi’i allweddu gan sesiwn.

Yn olaf, cyfyngwch y radiws difrod yn yr uned ei hun: golygfa system ffeiliau ddarllen yn unig ar wahân i’r cyfeiriadur statws, dim breintiau newydd, a therfyn amser penodol. Mae’r gwahanu rhwng daemon a gweithred defnyddiwr yn werth cael ar ei ben ei hun, ond mae’n werth llawer mwy pan na all y weithred wneud dim ond yr un peth a gymeradwyoch.

Erthyglau cysylltiedig