Что такое sudo
sudo буквально расшифровывается как “super user do” — «сделай как суперпользователь». Это утилита, которая позволяет обычному юзеру выполнить отдельную команду от имени root (или любого другого user), не открывая полноценный root-shell.
Идея простая: раньше админ заходил через su - (substitute user), вводил root-пароль и сидел в root-shell весь сеанс. Это опасно: одна опечатка rm -rf . где-нибудь в корне — катастрофа. Плюс root-пароль приходилось хранить и периодически менять.
sudo решил это: каждая команда — отдельный privilege-grant, с аудит-логом и гранулярной политикой. Можно разрешить sudo systemctl restart airflow, но запретить sudo bash. Команды логируются. Пароль для sudo — пароль самого юзера, а не root.
$ whoami
levo
$ id -u
1000
$ sudo whoami # запросит пароль ОДИН раз, потом cache 15 минут
[sudo] password for levo:
root
$ sudo id -u
0
Как sudo работает технически
sudo и root: модель привилегий Unix Linux capabilities: права без полного root/usr/bin/sudo — это SUID-binary:
$ ls -l /usr/bin/sudo
-rwsr-xr-x 1 root root 277736 Feb 10 12:34 /usr/bin/sudo
Видишь s вместо x для owner? Это SUID-bit (детально — урок 05). Когда обычный user запускает sudo, kernel при execve():
- Видит SUID-bit
- Устанавливает effective UID = owner-UID файла (то есть root=0)
- Запускает sudo с euid=0, оставляя
ruid=1000(твой настоящий UID)
Sudo, уже работающий с euid=0, может:
- Прочитать
/etc/sudoers(доступен только root) - Проверить: имеет ли user
levoправо выполнять эту команду? - Если да — спросить пароль (опционально), выполнить
setuid(0)(теперь и real UID = 0) иexecve()запрошенной команды - Команда выполняется уже от полноценного root
Каждый шаг — это явное действие kernel или sudo.
/etc/sudoers: политика
Файл /etc/sudoers — это конфиг правил «кто что может». Минимальный пример:
# Members of group sudo may gain root privileges
%sudo ALL=(ALL:ALL) ALL
# User airflow can restart airflow services without password
airflow ALL=(root) NOPASSWD: /bin/systemctl restart airflow-*
Синтаксис: WHO HOST=(AS_USER:AS_GROUP) [TAGS:] WHAT.
- WHO:
user1,%groupname(любой member),+netgroup - HOST: на каком хосте действует.
ALL= везде. Используется для одного/etc/sudoers, который раздаётся на много серверов. - AS_USER: от чьего имени можно выполнять.
ALL= от любого. По умолчанию это root. - AS_GROUP: от какой group выполнять.
- TAGS:
NOPASSWD:(не спрашивать пароль),SETENV:(разрешить передавать переменные окружения) - WHAT: список команд через запятую.
ALL= что угодно. Можно с аргументами:/bin/systemctl restart nginx.
Никогда не редактируй напрямую — используй visudo
# [X] ОЧЕНЬ ПЛОХО:
$ sudo vim /etc/sudoers
# Если ты ошибся в синтаксисе, файл повредится и НИКТО не сможет sudo.
# Получишь "syntax error" при попытке использовать sudo.
# Восстановление потребует boot в single-user mode.
# [x] ПРАВИЛЬНО:
$ sudo visudo
# Открывает /etc/sudoers в твоём $EDITOR, при сохранении ВАЛИДИРУЕТ синтаксис.
# Если ошибка — предложит исправить, не сохранит broken-версию.
visudo — это безопасный wrapper: parsing-check перед сохранением, locking файла (нельзя редактировать вдвоём), сохранение в temp-файл с атомарной заменой.
/etc/sudoers.d/ — рекомендованный путь
Вместо правки главного /etc/sudoers правильнее класть файлы в /etc/sudoers.d/. Имя — без точек и расширений:
# /etc/sudoers.d/airflow
airflow ALL=(root) NOPASSWD: /usr/bin/docker
airflow ALL=(root) NOPASSWD: /bin/systemctl restart airflow-*
Файлы из /etc/sudoers.d/ подцепляются @includedir /etc/sudoers.d в главном /etc/sudoers. Это удобно для:
- Управления через Ansible/Puppet (один файл — один сервис)
- Безопасных обновлений (изменения изолированы)
- Чистого uninstall (рудалили файл — правило исчезло)
Редактирование тоже через visudo: sudo visudo -f /etc/sudoers.d/airflow.
NOPASSWD: автоматизация без пароля
В CI/CD и для service-аккаунтов часто нужно выполнять sudo без интерактива:
deploy ALL=(root) NOPASSWD: /usr/bin/systemctl restart api
deploy ALL=(root) NOPASSWD: /usr/bin/docker pull *
Теперь user deploy может в скрипте написать sudo systemctl restart api без [sudo] password: prompt. Это безопасно если:
- Команды максимально специфичны (
restart api, неALL) - User
deploy— service-аккаунт, не интерактивный человек - Пароль/ключ
deployхранится в secret-менеджере
# В Ansible playbook:
- name: Restart API after deploy
become: false # не нужно sudo для всего playbook
shell: sudo systemctl restart api
sudo -u: выполнить от другого пользователя
$ sudo -u postgres psql -c "SELECT version()"
# Запустить psql от user postgres (полезно для local-trust в pg_hba.conf)
$ sudo -u airflow ls -la /var/log/airflow/
# Прочитать логи airflow с правами airflow (которые airflow и должны быть)
$ sudo -u www-data tail -f /var/log/nginx/error.log
# Хотя обычно nginx логи доступны через group adm
Без -u дефолт = root (или то, что задано в sudoers (AS_USER)). С -u USER — от его имени.
DE-сценарий: ты залогинен как levo, но Airflow CLI должен запускаться от service-аккаунта airflow, иначе он создаст файлы с твоим UID и потом сам не сможет их прочитать:
$ sudo -u airflow airflow dags list
$ sudo -u airflow airflow connections add my_conn ...
sudo !! и sudo -s
$ ls /etc/shadow
ls: cannot open '/etc/shadow': Permission denied
$ sudo !! # повторить последнюю команду с sudo
sudo ls /etc/shadow
ls /etc/shadow
!! — bash-расширение для «последняя команда». sudo !! — самый частый идиом после первого permission denied.
$ sudo -s
# root-shell, $HOME остаётся /home/levo
# полезно когда надо несколько команд подряд от root
$ sudo -i
# полноценный root-login: $HOME=/root, root-environment
# как если бы залогинился сразу как root
sudo-rs: Rust-замена в Ubuntu 26.04
С Ubuntu 25.10 (Plucky Puffin) и в Ubuntu 26.04 LTS sudo-rs становится дефолтной реализацией. Это полная переписка sudo на Rust, разработанная в рамках инициативы prossimo от ISRG (которые сделали Let’s Encrypt). Цели:
- Memory safety: исторический sudo на C имел регулярные CVE с buffer overflow (например, Baron Samedit / CVE-2021-3156, exploit за 13 лет был незамечен).
- Меньше attack surface: sudo-rs пока поддерживает только core-функциональность, без экзотических плагинов и legacy-опций.
- Audit-friendly: меньше кодовой базы, проще верифицировать.
Для пользователя совместимость почти полная: sudo command, sudoers-синтаксис, visudo работают так же. Различия:
- Не поддерживаются устаревшие опции (SSSD интеграция, runaspw, etc.)
- Лучше error messages
- Меньше rate-limit issues в multi-process scenarios
$ sudo --version # на Ubuntu 26.04
Sudo-rs 0.2.8
sudo-rs is an open source Sudo implementation in Rust.
Старый Sudo (/usr/bin/sudo.legacy) остаётся доступен на случай несовместимостей, но дефолт — Rust-версия. Если ты пишешь sudoers-правила и не используешь экзотику — никаких изменений не нужно.
Логи sudo
Все sudo-операции пишутся в /var/log/auth.log (Debian/Ubuntu) или /var/log/secure (RHEL/Fedora):
$ sudo grep sudo /var/log/auth.log | tail -3
May 13 12:34:01 host sudo: levo : TTY=pts/0 ; PWD=/home/levo ; USER=root ; COMMAND=/bin/systemctl restart nginx
May 13 12:35:02 host sudo: airflow : TTY=unknown ; PWD=/opt/airflow ; USER=root ; COMMAND=/usr/bin/docker pull img:v1
May 13 12:36:03 host sudo: levo : 3 incorrect password attempts ; TTY=pts/0 ; PWD=/home/levo ; USER=root ; COMMAND=/bin/cat /etc/shadow
Это золотая жила для аудита: кто что запускал, успешно или нет. Логи stream-ятся в journald тоже (journalctl _COMM=sudo).
Для DE: если твой Airflow worker внезапно начал делать sudo-операции, которые не должен, в auth.log это видно. Это первый артефакт компрометации, на который смотрят SRE.
DE-сценарии: где встретишься с sudo
Список регулярных задач, где без sudo не обойтись.
Безопасность
Несколько правил которые сэкономят тебе нервы:
- Никогда не
sudo curl URL | bashдля скриптов с непроверенного источника. Прочитай скрипт сначала. - NOPASSWD только для специфичных команд, не для
ALL. ПолныйNOPASSWD: ALLравен «у user есть root без аутентификации» — атакующий через любой бэкдор получает root. - sudo log — это compliance. Не отключай его (
!log_input/!log_output) без согласия SRE. - Не запускай длинные процессы через
sudo— таймаут sudo-токена 15 минут, потом надо переаутентифицироваться. Для daemons используй systemd unit сUser=.
Попробуй сам
- Проверь, какие команды можешь выполнять через sudo:
sudo -l - Открой sudoers через visudo (не сохраняй изменения!):
sudo visudo # выйди через :q без сохранения - Запусти
idот другого юзера:sudo -u nobody id - Посмотри последние sudo-операции:
sudo tail -20 /var/log/auth.log | grep sudo - Проверь свою версию sudo:
sudo --version | head -1
macOS-различия
- На macOS
sudo— оригинальная C-версия от sudo project (не sudo-rs). - Конфиг там же:
/etc/sudoers,/etc/sudoers.d/.visudoработает идентично. - На macOS правило по умолчанию:
%admin ALL=(ALL) ALL— все админы могут sudo. - Логи:
log show --predicate 'process == "sudo"'.
Главное
sudo— SUID-binary, который через PAM-аутентификацию и/etc/sudoersдаёт granular privilege escalation.- Никогда не редактируй
/etc/sudoersнапрямую — только черезvisudo, иначе можешь сломать sudo полностью. - Современная практика —
/etc/sudoers.d/имяСервиса, один файл на сервис, валидация черезvisudo -f. - NOPASSWD только для специфичных команд, never для ALL.
sudo -u USER— выполнить от другого пользователя.- Ubuntu 26.04 переходит на sudo-rs (Rust). Совместимость почти полная, безопаснее.
- Логи в
/var/log/auth.log(Debian/Ubuntu) — это аудит-история. - Разрешать interpreter в sudoers — это эквивалент
NOPASSWD: ALL.