VPN-csatlakozás utáni művelet futtatása felhasználóként, ne démonként
A USER=alice értékű környezeti változó nem változtatja meg, melyik fiókkal fut egy hook. Válassza szét az eseményt, a kiváltót és a műveletet, majd bizonyítsa az UID-t.
A VPN-démon kapcsolódási hookjai démonként futnak, és ez általában azt jelenti, hogy rootként futnak. Abban a pillanatban, amikor az egyik ilyen hook valaki otthoni könyvtárába ír, vagy újraindít egy asztali segédprogramot, egy hálózati eseménynek adta meg a lehetőséget, hogy tetszőleges helyi felhasználóként cselekedjen. A szokásos rövidítés, hogy felhasználónevet olvasunk ki egy környezeti változóból és továbbadjuk, nem javítja meg ezt. Csak újracímkézi a műveletet anélkül, hogy megváltoztatná, melyik fiók hajtja végre. Ami működik, az egy háromrészes átadás, amelyben a kiemelt lépés elmondja, mi történt, és egy külön egység végzi el a műveletet a helyes identitás alatt.
A környezetben lévő felhasználónév nem identitáskapcsoló
A Unix abból dönti el, mihez érhet egy folyamat, hogy mi az effektív felhasználói azonosítója, nem a környezetében lévő karakterláncokból. A USER=alice beállítása vagy a LOGNAME exportálása megváltoztatja, mit nyomtat a hanyag szoftver a kimenetére; a fájlok tulajdonjogának ellenőrzésein semmit sem változtat. A rootként futó hook ezzel a változóval továbbra is rootként nyitja meg Alice fájljait.
A nevek sem ugyanaz a név. A távoli hozzáférésű bejelentkezés, a helyi Unix-fiók és a tanúsítvány köznapi neve három azonosító, amelyek gyakran egybeesnek, és néha nem. Lehet, hogy egy a.smith néven hitelesítő felhasználónak egyáltalán nincs helyi fiókja, vagy egy címtárszolgáltatáson keresztül asmith-re képeződik le. Minden olyan terv, amely feltételezi, hogy egyetlen karakterlánc szolgálja mindhárom szerepet, az első alvállalkozónál eltörik.
Tehát az első kérdés nem az, hogy „melyik felhasználó van csatlakozva“, hanem hogy „melyik helyi fiók jogosult erre a műveletre“. Erre a saját fiókadatbázisából válaszoljon, nem abból, amit a kliens küldött:
id -u alice
getent passwd alice | cut -d: -f1,3,6
stat -c '%U:%G %a %n' /home/alice/.local/state/vpn-status.json
A harmadik parancs az, amelyet az emberek kihagynak. Ha a célfájl root tulajdonában van, mert az előző hook hozta létre, egy helyesen beállított felhasználói művelet engedélyhibával fog meghiúsulni, amely systemd-problémának tűnik, és nem az.
A démon ott marad, ahol van
A VPN-szolgáltatás saját User= beállítását Alice-re változtatni rossz kar. Megváltoztatja, hogyan köt a démon interfészeket, olvas kulcsokat, írja az állapotfájlját és kezeli az útvonalakat, és mindezt a kockázatot egy működő egységbe helyezi át. A démonnak szüksége van a jogosultságaira; a következő műveletnek nem.
Nézze meg, mit tesz valójában az egység, mielőtt hozzányúl. Két parancs megmondja a végrehajtási identitást és a hatályos pontos parancssorokat, beleértve mindent, amit egy felülírás hozzáadott:
systemctl show -p User -p Group -p ExecStart openvpn-server@server
systemctl cat openvpn-server@server
Alapértelmezett csomagtelepítésnél a démon root, és a --up szkript ezt örökli. Erősítse meg ezt ahelyett, hogy feltételezné, mert egy megerősített disztribúció áthelyezhette egy dedikált fiókra, és egy kézzel írt drop-in egy más szabályokkal rendelkező burkolón keresztül futtathatja a hookot.
Három megnevezett rész, egy szűk kiváltó
A karbantartást túlélő elrendezésben van egy esemény, egy kiváltó és egy művelet. A démon jelenti, hogy egy megnevezett munkamenet feljött. A kiváltó elfogadja ezt a kis tényt, és egyetlen rögzített műveletet kér. A művelet azon helyi fiók alatt fut, amely a megérintett fájlok tulajdonosa. A láncban semmi nem fogad el tetszőleges parancsútvonalat.
A művelet maga egy közönséges szolgáltatásegység, az identitás pedig egyetlen direktíva benne:
[Service]
Type=oneshot
User=alice
Group=alice
ExecStart=/usr/local/bin/refresh-vpn-status --slot %i
Vegye észre, hogy a User=alice az egész egységre vonatkozik, és a systemd dokumentál egy kivételt, amelyet érdemes ismerni: a + előtaggal ellátott parancs ettől függetlenül teljes jogosultságokkal fut. Ez az előtag jogos eszköz egyetlen kiemelt lépéshez, és kényelmes módja az éppen felépített szétválasztás visszavonására, ezért kezelje bármelyik +-et abban az egységben úgy, mint amit a felülvizsgálat során indokolni kell.
Tartsa a kiváltó bemenetét minimálisnak és nem titkosnak. A munkamenet-azonosító, a leképezett fiók és egy időbélyeg általában minden, amire szükség van. Soha ne adjon át a határon shell-töredéket, végrehajtható fájl útvonalát vagy a kliens által szolgáltatott környezeti blokkot, mert a fogadó félnek nincs módja megkülönböztetni a jogszerű értéket a befecskendezettől.
Ellenőrizze, milyen identitás futott valójában
A konfiguráció felülvizsgálata nem bizonyíték. Egy jóváhagyott tesztkapcsolat után erősítse meg a fájlt megérintő UID-t és azt az UID-t, amelyet a démon még használ:
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
Az első sornak Alice-t és egy időbélyeget kell mutatnia a tesztablakán belül. A másodiknak továbbra is rootot vagy a csomag szolgáltatásfiókját kell mutatnia, ami bizonyítja, hogy a démon nem mozdult. A harmadik a legolcsóbb módja a művelet jogosultságainak tesztelésére anélkül, hogy valódi újracsatlakozásra várna.
Ha a fájl tulajdonosa Alice, de a csoportja vagy módja megváltozott a futások között, keressen UMask=-et vagy könyvtárjogosultság-különbséget, nem logikai hibát. Ha az időbélyeg egyáltalán nem mozdult, a kiváltó soha nem lépett működésbe, és a hasznos következő lépés a journalctl -u a műveletegységhez, nem egy újabb kliens-újracsatlakozás.
Mit még mindig nem bizonyít egy kapcsolódási esemény
Egy létrejött alagút egyetlen tény. Nem jelenti azt, hogy az asztali munkamenet fel van oldva, a munkamenet-busz elérhető, vagy hogy a művelet által kívánt privát erőforrás már elérhető. Az Alice UID-je alatti oneshot egység rendelkezik az identitásával és semmivel a munkamenetéből, ezért mindennek, ami grafikus buszt igényel, a támogatott felhasználói munkamenet-mechanizmuson keresztül kell mennie, és meg kell határoznia, mi történik, amikor kijelentkezik.
Az újracsatlakozások is ismétlődnek. Egy vonaton alvó laptop egy óra alatt egy tucat kapcsolódási eseményt állíthat elő, és egy hook, amely minden alkalommal sort fűz hozzá, olvashatatlan naplóvá változtatja az állapotfájlt. Tegye a műveletet idempotenssé, vagy engedje, hogy egyetlen, munkamenet szerint kulcsolt rekordot helyettesítsen.
Végül korlátozza a kár sugarát magában az egységben: csak olvasható fájlrendszer-nézet az állapotkönyvtáron kívül, új jogosultságok nélkül és kifejezett időkorláttal. A démon és a felhasználói művelet szétválasztása önmagában is megéri, de sokkal többet ér, ha a művelet semmi mást nem tehet, mint azt az egyet, amit jóváhagyott.