Запускайце дзеянне пасля падключэння VPN як карыстальнік, а не як дэман
Зменная асяроддзя з USER=alice не мяняе, ад якога ўліковага запісу працуе хук. Падзяліце падзею, трыгер і дзеянне, а затым дакажыце UID.
Хукі падключэння ў дэмане VPN працуюць як дэман, а звычайна гэта значыць, што яны працуюць як root. Як толькі адзін з такіх хукаў запісвае ў хатні каталог кагосьці або перазапускае памочнік працоўнага стала, вы далі сеткавай падзеі магчымасць дзейнічаць як адвольны лакальны карыстальнік. Звычайны кароткі шлях, прачытаць імя карыстальніка са зменнай асяроддзя і перадаць яго далей, гэтага не выпраўляе. Ён пераназывае дзеянне, не мяняючы, які ўліковы запіс яго выконвае. Працуе трохчасткавая перадача: прывілеяваны крок кажа, што адбылося, а асобная адзінка выконвае дзеянне пад правільнай ідэнтычнасцю.
Імя карыстальніка ў асяроддзі не пераключальнік правоў
Unix вырашае, да чаго працэс можа дакрануцца, па эфектыўным ідэнтыфікатары карыстальніка, а не па радках у яго асяроддзі. Усталяванне USER=alice або экспарт LOGNAME мяняе тое, што неахайнае праграмнае забеспячэнне друкуе ў сваім вывадзе; гэта не мяняе нічога ў праверках уласнасці файлаў. Хук, які працуе як root з гэтай зменнай, усё роўна адкрывае файлы Alice як root.
Імёны таксама не адно і тое ж імя. Лагін аддаленага доступу, лакальны ўліковы запіс Unix і агульнае імя сертыфіката, гэта тры ідэнтыфікатары, якія часта супадаюць, а часам не. Карыстальнік, які аўтэнтыфікуецца як a.smith, можа наогул не мець лакальнага ўліковага запісу або адлюстроўвацца на asmith праз службу каталогаў. Любы дызайн, які мяркуе, што адзін радок выконвае ўсе тры ролі, зламаецца на першым падрадчыку.
Таму першае пытанне не «які карыстальнік падключаны», а «які лакальны ўліковы запіс мае права выконваць гэтае дзеянне». Адказвайце на гэта з уласнай базы ўліковых запісаў, а не з таго, што прыслаў кліент:
id -u alice
getent passwd alice | cut -d: -f1,3,6
stat -c '%U:%G %a %n' /home/alice/.local/state/vpn-status.json
Трэцяя каманда, гэта тая, якую людзі прапускаюць. Калі мэтавы файл належыць root, бо яго стварыў папярэдні хук, правільна наладжанае дзеянне карыстальніка завершыцца памылкай доступу, якая выглядае як праблема systemd і ёй не з'яўляецца.
Дэман застаецца там, дзе ён ёсць
Змяніць уласны User= службы VPN на Alice, гэта няправільны рычаг. Гэта змяняе тое, як дэман звязвае інтэрфейсы, чытае ключы, запісвае файл стану і кіруе маршрутамі, і пераносіць увесь гэты рызык у адзінку, якая працавала. Дэману патрэбныя яго прывілеі; наступнаму дзеянню не.
Паглядзіце, што адзінка насамрэч робіць, перш чым яе чапаць. Дзве каманды пакажуць ідэнтычнасць выканання і дакладныя радкі каманд, уключаючы ўсё, што дадаў файл перавызначэння:
systemctl show -p User -p Group -p ExecStart openvpn-server@server
systemctl cat openvpn-server@server
Пры стандартнай устаноўцы пакета дэман root, і скрыпт --up атрымлівае гэта ў спадчыну. Пацвердзіце гэта, а не мяркуйце, бо ўзмоцнены дыстрыбутыў мог перанесці яго на асобны ўліковы запіс, а напісаны ўручную drop-in можа запускаць хук праз абгортку з іншымі правіламі.
Тры названыя часткі, адзін вузкі трыгер
Канструкцыя, якая перажывае абслугоўванне, мае падзею, трыгер і дзеянне. Дэман паведамляе, што названая сесія ўзнялася. Трыгер прымае гэты маленькі факт і запытвае адно фіксаванае дзеянне. Дзеянне працуе пад лакальным уліковым запісам, якому належаць файлы, якіх яно датыкаецца. Нішто ў ланцугу не прымае адвольны шлях да каманды.
Само дзеянне, звычайная адзінка службы, а ідэнтычнасць адна дырэктыва ўнутры яе:
[Service]
Type=oneshot
User=alice
Group=alice
ExecStart=/usr/local/bin/refresh-vpn-status --slot %i
Заўважце, што User=alice дзейнічае на ўсю адзінку, і systemd дакументуе адно выключэнне, вартае ведання: каманда з прэфіксам + працуе з поўнымі прывілеямі незалежна ад гэтага. Гэты прэфікс законны інструмент для аднаго прывілеяванага кроку і зручны спосаб адмяніць падзел, які вы толькі што пабудавалі, таму стаўцеся да любога + у гэтай адзінцы як да таго, што трэба абгрунтаваць на разглядзе.
Трымайце ўваход трыгера мінімальным і не сакрэтным. Ідэнтыфікатар сесіі, адлюстраваны ўліковы запіс і адзнака часу, звычайна гэта ўсё, што трэба. Ніколі не перадавайце праз мяжу фрагмент абалонкі, шлях да выканальнага файла або блок асяроддзя ад кліента, бо прымаючы бок не мае спосабу адрозніць законнае значэнне ад укаранёнага.
Праверце, якая ідэнтычнасць насамрэч працавала
Разгляд канфігурацыі не доказ. Пасля ўхваленага тэставага падключэння пацвердзіце UID, які дакрануўся да файла, і UID, які дэман усё яшчэ выкарыстоўвае:
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
Першы радок павінен паказаць Alice і адзнаку часу ўнутры вашага тэставага акна. Другі павінен па-ранейшаму паказваць root або ўліковы запіс службы з пакета, што даказвае, што дэман не зрушыўся. Трэці, самы танны спосаб праверыць правы дзеяння, не чакаючы сапраўднага перападключэння.
Калі ўладальнік файла Alice, але яго група або рэжым змяніліся паміж запускамі, шукайце UMask= або розніцу правоў каталога, а не памылку логікі. Калі адзнака часу зусім не зрушылася, трыгер ніколі не спрацаваў, і карысны наступны крок journalctl -u для адзінкі дзеяння, а не чарговае перападключэнне кліента.
Што падзея падключэння ўсё яшчэ не даказвае
Усталяваны тунель, гэта адзін факт. Ён не азначае, што сесія працоўнага стала разблакаваная, што шына сесіі дасягальная або што прыватны рэсурс, патрэбны дзеянню, ужо даступны. Адзінка oneshot пад UID Alice мае яе ідэнтычнасць і нічога з яе сесіі, таму ўсё, што патрабуе графічнай шыны, павінна ісці праз падтрымоўваны механізм карыстальніцкай сесіі і вызначаць, што адбываецца, калі яна выйшла з сістэмы.
Перападключэнні таксама паўтараюцца. Наўтбук, які засынае ў цягніку, можа выдаць дзесятак падзей падключэння за гадзіну, а хук, які кожны раз дадае радок, ператварае файл стану ў журнал, які ніхто не можа чытаць. Зрабіце дзеянне ідэмпатэнтным або дазвольце яму замяняць адзін запіс з ключом па сесіі.
Нарэшце, абмяжуйце радыус паражэння ў самой адзінцы: прадстаўленне файлавай сістэмы толькі для чытання па-за каталогам стану, без новых прывілеяў і з яўным тайм-аўтам. Падзел паміж дэманам і дзеяннем карыстальніка варты сам па сабе, але ён варты нашмат большага, калі дзеянне не можа зрабіць нічога, акрамя адзінай рэчы, якую вы ўхвалілі.