РУКОВОДСТВО ПО БЕЗОПАСНОСТИ СЕРВЕРОВ

Пользователи Linux, sudo и принцип минимальных привилегий на VPS: практический аудит

Большинство руководств по защите сервера описывают путь внутрь: файрвол, SSH, обновления. Это руководство о том, что происходит после того, как кто-то оказался внутри, или после того, как ошибка в одном сервисе даёт атакующему его права. Ответ зависит от того, кто и что владеет root. Принцип минимальных привилегий прост по формулировке и регулярно игнорируется на небольших серверах, где у одного администратора неограниченный sudo, скрипты развёртывания работают от root, а сервисы делят одного пользователя. В памятке OWASP по авторизации он определён как предоставление пользователям только минимальных привилегий, необходимых для их работы. Это руководство превращает его в аудит, который можно выполнить за десять минут, и набор изменений, ограничивающих последствия, когда что-то идёт не так. Оно дополняет руководство по защите SSH и чек-лист безопасности VPS.

Быстрый результат (10 минут)

  • Выполните awk -F: '($3 == 0) {print $1}' /etc/passwd. В выводе должен быть только root.
  • Выполните getent group sudo wheel docker и проверьте, что каждый участник действительно нуждается в доступе.
  • Выполните sudo grep -rn NOPASSWD /etc/sudoers /etc/sudoers.d/ и отметьте каждый результат.
  • Выполните sudo --version | head -1 и сравните с исправленным релизом в разделе о CVE ниже.
  • Составьте список учётных записей с реальной оболочкой входа: grep -vE "nologin|false" /etc/passwd.

Почему привилегии важны после проникновения

Защита отказывает по слоям. Уязвимое веб-приложение, украденный пароль или утёкший ключ пускают атакующего под каким-то пользователем. Что он сможет сделать дальше, определяют привилегии этого пользователя. Если это собственный непривилегированный пользователь веб-сервера, ущерб ограничен тем, что он может читать и писать. Если же он может запускать sudo без ограничений или сервис работает от root, атакующий за секунды получает машину целиком, может отключить журналирование, прочитать все секреты и удалить бэкапы, как описано в руководстве по защите от ransomware.

Та же логика относится к особым группам. Членство в группе docker равнозначно root, как объяснено в руководстве по безопасности Docker-хоста. Минимальные привилегии означают, что каждый человек и каждый сервис держит только то, что нужно для работы, и ничего сверх, чтобы ошибка или компрометация оставались небольшими.

Проверьте, у кого сейчас есть root

Начните с поиска всех путей к root. Выполните от имени администратора:

# учётные записи с UID 0 (должен быть только root)
awk -F: '($3 == 0) {print $1}' /etc/passwd

# кто может использовать sudo, напрямую или через группу
getent group sudo wheel
sudo grep -rnE '^[^#]' /etc/sudoers /etc/sudoers.d/

# правила NOPASSWD, пропускающие аутентификацию
sudo grep -rn NOPASSWD /etc/sudoers /etc/sudoers.d/

# учётные записи с пустым паролем
sudo awk -F: '($2 == "") {print $1}' /etc/shadow

# учётные записи с интерактивным входом
grep -vE 'nologin|false' /etc/passwd

Любая вторая учётная запись с UID 0 это замаскированный root и классический приём закрепления; прочитайте статью об UID 0 и, если нашли такую, которую вы не создавали, переходите к руководству по реагированию на взлом. Для каждой учётной записи человека спросите, нужно ли ему вообще администрировать сервер. Удаляйте ушедших людей, удаляйте неиспользуемые записи командой sudo userdel -r name после сохранения нужного, а те, что могут понадобиться позже, блокируйте командой sudo usermod -L name вместе с оболочкой nologin. Убедитесь также, что прямой вход root по SSH отключён; почему, объясняет статья о root-входе.

Дайте сервисам собственные непривилегированные учётные записи

Каждый сервис должен работать от собственного пользователя, а не от root и не от вашей административной учётной записи. Для записей, которые никогда не должны входить в систему, задайте оболочку nologin, которая, согласно её справочной странице, выводит сообщение о том, что учётная запись недоступна, и завершается с ненулевым кодом, а также предназначена как замена поля оболочки, чтобы запретить вход в учётную запись:

sudo useradd --system --home-dir /nonexistent --shell /usr/sbin/nologin myapp

В системах с systemd укажите пользователя в unit-файле и добавьте параметры изоляции из документации systemd. User=myapp запускает процесс без привилегий. NoNewPrivileges=yes гарантирует, что процесс сервиса и все его потомки никогда не смогут получить новые привилегии. ProtectSystem=strict монтирует всю иерархию файловой системы только для чтения, кроме файловых систем API, а запись в нужные пути вы разрешаете через ReadWritePaths=. DynamicUser=yes выделяет временного пользователя для простых сервисов. Слушайте порты выше 1024 за обратным прокси, а не запускайте что-либо от root ради порта 80 или 443. Для контейнеров действуют те же идеи, они разобраны в руководстве по Docker, ссылка на которое дана выше.

Пишите узкие и безопасные правила sudo

Никогда не правьте /etc/sudoers напрямую обычным редактором. Используйте visudo, который проверяет синтаксис перед сохранением, чтобы опечатка не лишила администраторов доступа. Свои правила храните в отдельных файлах в /etc/sudoers.d/, создавая их командой sudo visudo -f /etc/sudoers.d/deploy. В руководстве по sudoers отмечено, что этот каталог пропускает файлы, имена которых заканчиваются на ~ или содержат точку, поэтому называйте файлы без точек, иначе правило молча не применится.

Затем делайте каждое правило настолько узким, насколько позволяет задача:

  • Предпочитайте конкретные команды вместо ALL. Пользователю развёртывания, которому нужно лишь перезапускать один сервис, дайте именно это: deploy ALL=(root) /usr/bin/systemctl restart myapp.service.
  • Осторожно с NOPASSWD. По умолчанию sudo требует аутентификации, а тег NOPASSWD это меняет. Для узкого правила автоматизации это разумно, а для ALL на учётной записи человека плохая идея.
  • Избегайте подстановочных знаков в аргументах. В руководстве предупреждается, что подстановочные знаки могут совпасть с любым символом, включая пробел, и использовать их нужно осторожно.
  • Не разрешайте редакторы, пейджеры и оболочки. В руководстве сказано, что после запуска программы sudo она вольна делать что угодно, включая запуск других программ, что обходит контроль и журналирование sudo. Для правки файлов безопаснее дать пользователю право запускать sudoedit.
  • Используйте sudoedit для изменения конфигурации. sudoedit /etc/nginx/nginx.conf редактирует копию от вашего пользователя, а записывает обратно от root.

Узнайте, что пользователь реально может, командой sudo -l -U username, и после изменений быстро выполните sudo visudo -c.

Хотите, чтобы кто-то ещё посмотрел на ваши учётные записи?

Бесплатная проверка в режиме только чтения оценивает настройку учётных записей и привилегий вместе с открытыми сервисами, ничего не меняя.

Получить бесплатную проверку сервера Связаться с инженером по безопасности

Обновляйте сам sudo

Инструменты привилегий сами становятся целями. В 2025 году проект sudo раскрыл CVE-2025-32463, локальное повышение привилегий, связанное с опцией -R (--chroot). Согласно бюллетеню проекта, затронуты версии sudo с 1.9.14 по 1.9.17 включительно, исправлено в sudo 1.9.17p1, а в системах с поддержкой /etc/nsswitch.conf пользователь может выполнять произвольные команды от root. В бюллетене функция chroot названа устаревшей, а исправлением указано обновление до 1.9.17p1 или новее.

Проверьте свою версию командой sudo --version. Дистрибутивы часто переносят исправления без смены номера версии апстрима, поэтому сверьтесь и с трекером безопасности вендора или выполните обновление через менеджер пакетов. Именно поэтому важна рутина; см. руководство по управлению обновлениями. Это также показывает, почему ошибки локального повышения привилегий важны на небольшом сервере: любая точка опоры с низкими правами, например скомпрометированный пользователь веб-приложения, превращается в полный контроль, если sudo уязвим.

Ежедневные привычки

Минимальные привилегии со временем размываются, если их не поддерживать, поэтому планируйте проверку не реже раза в квартал. Повторите аудит выше, уберите доступ тем, кто сменил роль, и убедитесь, что у новых сервисов есть собственные учётные записи. Следите за журналами: sudo записывает каждую команду в журнал аутентификации или journal, а руководство по анализу журналов показывает, как оповещать о неожиданном использовании. Для особо чувствительных команд руководство по sudoers описывает и log_output для записи вывода терминала.

Сочетайте это со вторым фактором для входа администраторов, описанным в руководстве двухфакторная аутентификация SSH, чтобы один украденный ключ не отдавал учётную запись с правом sudo. И, наконец, ограничивайте и сами секреты: пользователь базы данных, ограниченный одной схемой, или токен API, ограниченный одним действием, сужает возможности открытого файла .env. Записывайте, кто чем владеет, чтобы ничего не держалось на памяти.

О форматах файлов, которые проверяются в этом аудите, см. справки по sudoers и /etc/passwd.

Справка: sudo (выполнение команд с правами root) объясняет саму команду, а sudoers (правила sudo) описывает файл политики.

Часто задаваемые вопросы

Что такое принцип минимальных привилегий на сервере?

Каждый пользователь и каждый сервис получает только минимальные права, нужные для работы. OWASP определяет его как предоставление пользователям только минимальных привилегий, необходимых для их работы. Он ограничивает ущерб при компрометации учётной записи или сервиса.

Как проверить, у кого есть root-доступ в Linux?

Выведите учётные записи с UID 0 через awk по /etc/passwd, проверьте членов групп sudo или wheel через getent и прочитайте правила в /etc/sudoers и /etc/sudoers.d. UID 0 должен быть только у root, а каждому пользователю с sudo этот доступ должен быть действительно нужен.

Безопасен ли NOPASSWD в sudoers?

Только для узких правил, например для одной учётной записи автоматизации, которой разрешена одна конкретная команда. По умолчанию sudo требует аутентификации, а NOPASSWD её убирает, поэтому не применяйте его к ALL или к учётным записям людей.

Почему нужно использовать visudo, а не править sudoers напрямую?

visudo проверяет синтаксис перед сохранением. Синтаксическая ошибка в файле sudoers может сломать sudo для всех, что на сервере с отключённым входом root может лишить вас возможности администрирования.

Какие версии sudo затронуты CVE-2025-32463?

По бюллетеню проекта sudo затронуты версии с 1.9.14 по 1.9.17 включительно, а ошибка исправлена в 1.9.17p1. Проверьте и трекер безопасности вашего дистрибутива, так как вендоры часто переносят исправления.

Что делает оболочка nologin?

Это замена поля оболочки, которая запрещает интерактивный вход в учётную запись. Она выводит сообщение о недоступности учётной записи и завершается с ненулевым кодом. Используйте её для сервисных записей, которые должны только запускать демоны.

Не уверены, в каком состоянии ваш сервер?

Получите бесплатную проверку безопасности в режиме только чтения или поговорите с инженером по безопасности об управляемой защите.

Получить бесплатную проверку сервера Связаться с инженером по безопасности