Перейти к содержимому

Права и sudo

От пользователя Нужен root
list, search, diff, status, check, config-path apply
add, rm, enable, disable (без --apply) off
group *, zone * (без --apply) backup restore, backup prune
source add/update/list/rm любая команда с --apply
init, import, edit, completions, backup list, man migrate, когда доходит до удаления старого блока

Правило одно: запись в /etc/hosts или в каталог бэкапов требует root, всё остальное нет. backup prune попал в правую колонку по второй причине — он удаляет файлы в root-овом каталоге, поэтому проверяет права заранее, а не сообщает, что удалил ноль снимков.

Когда прав не хватает, hostsctl не пытается ничего обойти. Он печатает точную команду для повторного запуска и выходит с кодом 4:

error: apply: no write access to /etc/hosts
run: sudo hostsctl apply

Конфиг и кеш живут в твоём домашнем каталоге, а не в root-овом. Под sudo $HOME указывает на вызывающего пользователя не всегда, а $XDG_CONFIG_HOME вообще указывает на окружение root, поэтому hostsctl не доверяет ни тому ни другому: настоящий домашний каталог берётся из SUDO_USER через passwd.

Файлы и каталоги, созданные под root, возвращаются вызывающему пользователю — по всей цепочке от созданного каталога вверх до домашнего. В результате sudo hostsctl apply никогда не оставляет root-овых файлов в ~/.config и ~/.cache, то есть не делает классического трюка, когда утилита делает собственный конфиг нечитаемым для его владельца.

Terminal window
hostsctl apply -n # рендерит, показывает diff, ничего не пишет
hostsctl diff # та же картина без церемоний apply

--dry-run глобальный, работает у любой команды. У изменяющей команды он ещё и сообщает, что записал бы в конфиг.

Запись атомарная: временный файл рядом с целью, fsync, затем rename. Права и владелец существующего файла читаются заранее и выставляются временному, поэтому /etc/hosts остаётся root:wheel 0644 при любом umask, а на его месте оказывается обычный файл с той же идентичностью.

Если в результате не оказалось бы 127.0.0.1 localhost, запись отменяется до того, как что-либо переименовано. Эта проверка ловит и плохой конфиг, и баг в самом hostsctl.

Terminal window
hostsctl --target /tmp/hosts apply -y

--target (а также settings.target и $HOSTSCTL_TARGET) направляет hostsctl в другой файл. Сброс DNS-кеша при этом пропускается, если цель — не настоящий /etc/hosts: правка копии в /tmp резолвер не волнует. Именно так тесты прогоняют весь путь записи, не трогая системный файл.