Дългото време на работа доказва само, че стартирането е успяло с привилегиите, които демонът е имал в този момент. Отказите, които имат значение тук, идват по-късно: свързва се нов клиент, списъкът с оттегляния се заменя, помощен скрипт трябва да запише файл. Всяко от тях е ново отваряне, извършено от непривилегирования акаунт, със свой въпрос за правата и свое съобщение за грешка. Три решения разделят конфигурация, която продължава да работи, от такава, която се проваля при следващото събитие.

Отделете зареденото рано от отваряното по-късно

Дескрипторът е дръжка към отворено описание на файл и режимът на достъп е фиксиран при създаването на това описание. Смяната на потребителя на процеса по-късно не затваря дръжката, затова ключов файл, прочетен като root, продължава да работи след свалянето. Режимът също не се променя: дръжка, отворена за четене, не става за запис, а дръжка за запис не се отнема само защото акаунтът е загубил правата си върху пътя. Тези два факта обясняват повечето изненадващо поведение в тези доклади.

Другата половина е паметта. Демонът може да анализира сертификат, да запази анализирания материал и да затвори файла; в употреба остават данни, а не отворен файл. Затова продължаващият трафик не доказва нито че дескрипторът е отворен, нито че пътят е достъпен. Доказва само, че материалът, нужен за текущата сесия, е получен по-рано.

По-късното отваряне е друга транзакция. То работи с текущите идентификационни данни, текущия контекст на сигурност и текущия изглед на монтиране, затова път, четим при стартиране, може да бъде отказан при следващата връзка. Ротацията добавя капан: записването на нов файл върху същото име на път оставя съществуващата дръжка привързана към стария обект, така че презареждането може да изглежда успешно, докато демонът още използва предишното съдържание. Сравнете inode, който процесът държи, с този на диска, преди да повярвате, че ротацията е в сила.

Назовете трите четения по време на работа и кога се случва всяко

Три ресурса обикновено се отварят доста след инициализацията и се провалят в различни моменти. Конфигурационен файл за конкретен клиент се чете, когато този клиент се свърже, затова може да се счупи за един потребител, докато останалите продължават. Данните за оттегляне се проверяват при удостоверяване на партньора и отново при подмяна на файла. Временната директория се докосва само когато скрипт или плъгин запише нещо.

Нито един от трите не принадлежи към пътя на стартиране, затова сървър, здрав в продължение на седмици, може да се провали при следващата връзка. Категорията посочва и собственика на поправката: първите два са права за четене на конфигурация под акаунта на демона, а третият е място за запис с тясно предназначение.

Path reopened laterWhat triggers the openFirst sign when it fails
Client configuration fileA connection for that client identityOne client rejected while others connect
Revocation dataPeer authentication, including after replacementRevoked and valid peers both refused
Script or plugin temporary directoryA helper needs to create a fileThe helper exits with a path error

persist-key отговаря на по-тесен въпрос, отколкото повечето хора предполагат. Той държи ключовия файл отворен през документираните нулирания SIGUSR1 и ping-restart, и не прави нищо за CCD файлове, данни за оттегляне, помощни изпълними файлове или пълно рестартиране на процеса. Те продължават по свои собствени пътища на отваряне, под акаунта, който работи в този момент.

Потвърдете акаунта и изгледа, който той наистина има

Попитайте работещия демон кой акаунт използва, вместо да вярвате на unit файла, после сравнете отговора с това, което unit задава. Несъответствието е първото, което трябва да се реши, защото всяка следваща проверка на правата работи като този, който процесът наистина е. После обходете пътя компонент по компонент; преминаването се оценява на всяко ниво, затова четим файл в нечетима директория остава нечетим. Крайният режим на файла е последният въпрос, а не първият.

Просторите от имена и служебните пясъчници добавят граници, които собствеността и битовете на режима не описват. Път, видим в обвивката ви, може да липсва или да е само за четене вътре в chroot, монтирано пространство от имена или unit, който скрива домашните директории. Модулите за сигурност добавят още един слой, затова файл, който изглежда четим, може да бъде отказан при отваряне.

ps -o user:12,pid,args -C openvpn
systemctl show -p User -p Group -p ProtectHome -p RootDirectory [email protected]
sudo -u openvpn namei -l /etc/openvpn/ccd/alice

Успешното четене в обвивката на администратора не проверява нито едно от тези съчетани условия. Изпълнете проверката под акаунта на демона, със същото пространство от имена и пясъчник, или приемете, че резултатът описва обвивката ви, а не сървъра. Третата команда е евтиният вариант на този тест: тя отпечатва режима на всеки компонент и се проваля на първия, който акаунтът на демона не може да премине.

Дайте записа по време на работа в отделна директория

Четенето е само половината от инвентара. Помощен скрипт може да трябва да създаде файл за състояние, плъгин може да трябва да запише състояние до конфигурацията си, и тези записи не се покриват от това дървото на конфигурацията да стане за запис. Дайте на конкретната директория правата за запис, които функцията и изисква, със собственик и режим, които можете да обясните. Предпочитайте достъп само за четене за всичко, което само се чете.

Дръжте правата на частния ключ отделно от файловете на политиката. Ключ, който трябва да се препрочете след нулиране, има различно изискване от клиентски файл, четен при всяка връзка, и един разрешаващ режим за двата дава повече достъп, отколкото проблемът иска. Отделен акаунт на демона с тясна собственост се одитира по-лесно от широка група. Когато ключът трябва да преживее нулирания, persist-key премахва препрочитането вместо да разширява директорията.

Решавайте от събитието, което можете да възпроизведете

Жив тунел доказва един път през кода. Събитието, което се нуждае от файла, е единственият тест, който покрива отварянето, което ви интересува, било то нова клиентска връзка, заменен файл за оттегляне, разрешено меко нулиране или планиран рестарт. Изберете събитието, изпълнете го и запазете първата грешка, а не последната.

За меко нулиране един сигнал и журналът на unit показват дали ключът е прочетен отново. Изпратете сигнала, после прочетете последните редове, които unit е записал:

systemctl kill -s SIGUSR1 [email protected]
journalctl -u [email protected] -n 40 --no-pager

Не заключавайте, че компрометиран демон вече не може да променя файлове само защото привилегиите са свалени. Какво още може зависи от останалите идентификационни данни, способностите му, директориите, в които може да пише, и всяка дръжка за запис, която още държи. Намаляването на привилегиите стеснява властта, а инвентарът на отварянията по време на работа показва докъде. Запишете тази граница до конфигурацията, за да не се налага следващият човек да я открива отново.

Подобни статии