Сэрвіс запускаецца, журнал скардзіцца, што не можа адкрыць прыладу tun, а маршруты так і не з'яўляюцца. Выканайце capsh --print у сваёй абалонцы, і cap_net_admin акажацца тут жа, што робіць збой немагчымым на выгляд. Розніца паміж вашай абалонкай і юнітам — гэта пераход прывілеяў, а не жаданне ядра выдаць магчымасць. Прайдзіце чатыры праверкі ніжэй па парадку і спыніцеся на першай, якая тлумачыць разрыў.

Аддзяліце адсутную магчымасць ад схаванай прылады

Два збоі выглядаюць аднолькава ў радку журнала. Працэс без CAP_NET_ADMIN не можа стварыць або наладзіць інтэрфейс тунеля, а працэс, чыя пясочніца хавае /dev/net/tun, не можа адкрыць яго з самага пачатку. Даданне магчымасцяў не выправіць другі выпадак.

Праверце, ці існуе прылада ў прасторы імёнаў сэрвіса, перш чым нешта змяняць. PrivateDevices=yes — распаўсюджаны радок умацавання, які цалкам выдаляе вузел tun, а абмежавальны ProtectSystem можа зрабіць шлях канфігурацыі толькі для чытання так, што гэта чытаецца як памылка правоў. Абодва даюць радкі журнала, якія згадваюць тунель, таму віна кладзецца на магчымасці. Спачатку пераканайцеся, што вузел прысутнічае і адкрываецца, потым ідзіце далей.

Ведайце, на які набор магчымасцяў вы глядзіце

Linux трымае дазволены, дзейны, наследуемы, абмежавальны і асяродкавы наборы, і менавіта асяродкавы набор перажывае exec ад карыстальніка не-root. Магчымасці файла на бінарніку могуць перадаць дазволеныя і дзейныя правы пры exec, але толькі пакуль нішто ў ланцугу не блакуе гэтую перадачу.

Менавіта тут sudo уводзіць людзей у зман. Каманда, запушчаная праз sudo -u, пачынае новы пераход прывілеяў, і асяродкавы набор знікае, таму тая ж праверка, якая паспяховая як root, там правальваецца. Кіраўнік сэрвісаў — яшчэ адзін пераход, і ён не дае нічога асяродкавага, калі юніт гэтага не кажа.

Дайце магчымасць у юніце, а не ў абгортцы

Мінімальны раздзел сэрвіса для тунеля, якому трэба стварыць прыладу і ўсталяваць маршруты, выглядае так.

[Unit]
Description=OpenVPN client, office profile
After=network-online.target

[Service]
Type=notify
User=openvpn
Group=openvpn
NoNewPrivileges=yes
AmbientCapabilities=CAP_NET_ADMIN
CapabilityBoundingSet=CAP_NET_ADMIN
ExecStart=/usr/sbin/openvpn --config /etc/openvpn/office.conf

AmbientCapabilities змяшчае права ў асяродкавы набор да запуску працэса, а CapabilityBoundingSet не дазваляе працэсу трымаць што-небудзь па-за гэтым спісам. NoNewPrivileges=yes блакуе набыццё прывілеяў праз setuid або магчымасці файла, а магчымасць, якую юніт дае яўна, усё роўна дзейнічае. Дадавайце CAP_NET_BIND_SERVICE толькі калі сэрвіс мусіць займаць нізкі порт, і ніколі не дадавайце CAP_SYS_ADMIN толькі таму, што так зрабіў форумны паток.

Калі юніт абгортвае бінарнік у sudo, прыбярыце абгортку. systemd ужо ўжывае User=, і гэты лішні слой — самая верагодная прычына пустога асяродкавага набору.

Правярайце на жывым працэсе, а не на файле юніта

Прачытайце, што кіраўнік фактычна ўжыў, а потым прачытайце працэс, які ён стварыў.

unit=openvpn-client@office
systemctl show -p User -p AmbientCapabilities "$unit"
systemctl show -p MainPID --value "$unit" | xargs -r getpcaps
grep -E '^Cap(Eff|Amb)' /proc/$(systemctl show -p MainPID --value "$unit")/status

Калі юніт пералічвае магчымасць, а CapEff усё яшчэ яе не мае, то drop-in перавызначае наладу або крок ExecStartPre змяняе асяроддзе. Пашукайце імя юніта ў каталогах drop-in, перш чым лічыць асноўны файл галоўным, бо пазнейшы файл моўчкі перамагае. Калі і юніт, і працэс паказваюць магчымасць, а тунель усё роўна не працуе, вярніцеся да праверак прылады і шляху, а не пашырайце абмежавальны набор. Яго пашырэнне хавае сапраўдную прычыну і пакідае сэрвіс больш прывілеяваным, чым ён быў.

Аддайце перавагу скідванню прывілеяў пасля запуску

OpenVPN можа стартаваць з прывілеямі, а потым перайсці на непрывілеяваны ўліковы запіс праз уласныя опцыі user і group, а persist-key і persist-tun захоўваюць тунель прыдатным далей. Такая схема звужае акно, у якім працэс трымае правы, і часта падыходзіць лепш, чым запуск усяго дэмана без прывілеяў з пастаяннымі магчымасцямі.

Якую б мадэль вы ні абралі, перазапусціце юніт і паўтарыце праверкі пасля перазагрузкі, бо сэрвіс, які працуе з інтэрактыўнай абалонкі root і збывае пры загрузцы, звычайна адрозніваецца менавіта магчымасцю, прыладай або правамі файла. Запішыце налады юніта побач з вывадам магчымасцяў працэса, каб наступны рэцэнзент бачыў, ці зрушыла мяжу абнаўленне пакета або drop-in.

Падобныя артыкулы