Короткий ответ
Baseline — набор команд с ожидаемым выводом, а не «поставили fail2ban». Минимум на Ubuntu 22.04/24.04: отдельный admin без root SSH, ключи, UFW default deny incoming, AppArmor enforce, unattended security, persistent journal, auditd watches на identity/sudo, слушатели по матрице. Каждую позицию снимите в /home/admin/baseline/. Не CIS из 200 sysctl с gist. Не отключайте firewall/AppArmor «чтобы ansible прошёл». Хост host.example (10.0.20.10).
Детали узлов: SSH, firewall, патчи, auditd, пользователи.
Симптомы и как отличить
Нет baseline, если после инцидента нельзя ответить: был ли UFW active вчера. Отличие от linux-статьи «базовый hardening Ubuntu» в разделе серверов: здесь упор на проверяемый security-минимум и связку SSH+FW+патчи+аудит, не на NTP/диск.
Возможные причины отсутствия стандарта
- Образ провайдера «уже безопасен».
- Ansible без проверок в конце.
- Временные дыры не закрыли.
- Боязнь lockout — оставили PermitRootLogin yes.
Диагностика (съёмка «как есть»)
mkdir -p /home/admin/baseline && cd /home/admin/baseline
date -Is > 00-meta.txt
hostnamectl >> 00-meta.txt
sudo sshd -T | grep -Ei 'permitrootlogin|passwordauthentication|allowusers|maxauthtries' | tee 01-sshd.txt
sudo ufw status verbose | tee 02-ufw.txt
sudo aa-status | tee 03-apparmor.txt
systemctl is-enabled unattended-upgrades apt-daily-upgrade.timer | tee 04-unattended.txt
sudo unattended-upgrade --dry-run 2>&1 | tail | tee -a 04-unattended.txt
sudo auditctl -s 2>/dev/null | tee 05-audit.txt || echo 'no auditd' | tee 05-audit.txt
ss -tulnp | tee 06-ss.txt
sudo passwd -S -a | tee 07-users.txtЭто диагностика текущего долга. Дальше закрываете пункты.
Решение — минимум, который можно проверить
A. Идентичность и SSH
Пользователь admin, sudo с паролем, не NOPASSWD ALL. PermitRootLogin no, пароль SSH нет, AllowUsers admin. Команды внедрения — в статье sshd. Ожидание в 01-sshd.txt: permitrootlogin no.
B. Firewall
ufw default deny incoming, allow 22 с 10.0.20.0/24, enable. Ожидание: Status: active, Default: deny (incoming). Не параллельный nft flush.
C. Пакеты
unattended-upgrades с origins security, Automatic-Reboot false (ребут в окне). Не dist-upgrade в этом baseline. /var/run/reboot-required мониторить.
D. MAC
systemctl enable --now apparmor. Профили сервисов enforce. DENIED — профиль, не aa-disable. SELinux на Ubuntu не штатно.
E. Аудит и логи
Пакет auditd, rules identity/sudoers/sshd_config. Journal Storage=persistent с MaxUse. Копия на коллектор желательна, для минимума — хотя бы persistent + не world-writable /var/log.
F. Поверхность
ss ⊆ матрица. Нет 2375, нет Redis на 0.0.0.0. Группа docker без прикладных пользователей. Нет 777 на /var/www. SUID в /opt нет.
G. Пользователи
Таблица lastlog/sudo. Нет второго uid 0.
Внедрение пакетами с проверкой после каждого. Снимок VM.
sudo apt-get install -y unattended-upgrades auditdНе ставьте десятки universe-утилит «для hardening».
Как внедрять на уже живом хосте, не на золотом образе. Снимите «как есть» (диагностика выше) и закройте дыры в порядке lockout-риска: сначала второй ключ и admin, потом sshd, потом UFW, потом unattended, потом auditd/AppArmor дельты. Не включайте всё одним ansible play без assert между шагами.
Ansible: после каждого блока — command sshd -T, ufw status, регистрируйте и failed_when если permitrootlogin не no. Playbook без assert снова станет «запустили и забыли».
Облачные metadata SSH keys: провайдер может снова положить ключ в ubuntu. Либо выключите эту функцию, либо включите ubuntu в AllowUsers осознанно, либо ежедневный cron сверки authorized_keys с эталоном (осторожно с самим cron-правами).
Не включайте в минимум: полный CIS sysctl, disable IPv6, fail2ban без рабочего UFW, SELinux на Ubuntu, PermitRootLogin yes «для terraform». Terraform/ansible работают под admin+sudo.
Метрики успеха через 30 дней: нет Accepted password, нет permitrootlogin yes, unattended лог не пустой, auditd enabled 1, nmap WAN ⊆ матрица. Если метрика красная — это не «baseline был», это регрессия.
Связь с разделом linux (не security): поломки apt, диска, ssh timeout чинятся там; этот чеклист не заменяет диагностику «sshd не слушает».
Чеклист «готово» без самообмана: кто угодно по вашей инструкции повторяет команды и получает те же значения. Если проверка «ну вроде ufw включён» без вывода — это не baseline. Кладите файлы 01-sshd.txt … в тикет.
Не расширяйте минимум fail2ban+auditd+UFW одним днём на 50 хостов без канарейки. Один хост, сутки наблюдения, затем группа.
Как проверить, что проблема устранена
Повторите съёмку. Чеклист ожиданий:
| Проверка | Ожидание |
|---|---|
sshd -T permitrootlogin | no |
| passwordauthentication | no |
ufw status | active, deny incoming |
aa-status | apparmor enabled, не все в complain |
| unattended timer | enabled |
auditctl -s enabled | 1 |
ssh BatchMode admin | 0 |
ssh root | отказ |
ss | только матрица |
Артефакты в git/заявке. Повтор ежеквартально.
Если не помогло
- Облако SG any-any — гостевой baseline недостаточен.
- Cloud-init перетирает sshd — 99- drop-in.
- Автообновления ломают — сузьте origins, не маскируйте таймер.
- Политика запрещает auditd — зафиксируйте исключение, не молчите.
- Нужен CIS сверх минимума — отдельный проект, не ломайте 1С пачкой sysctl.
Профилактика
- Золотой образ + cloud-init.
- Ansible с assert по командам таблицы.
- Алерт: ufw inactive, permitrootlogin yes, auditd dead.
- Change: любой новый порт в матрице.
Связанные углубления: Fail2Ban, секреты, cron, SUID — после этого минимума, не вместо.
FAQ
Это CIS Ubuntu Level 2?
Нет, это операционный минимум, который админ может проверить за час. CIS — шире и ломает приклад без пилота.
Нужен ли fail2ban в минимуме?
Рекомендован если 22 хоть как-то виден вне jump. Не замена ключей. Ставьте после UFW.
sysctl net.ipv4.ip_forward
На app-сервере 0. На роутере 1 осознанно. Не gist из 80 строк.
Ubuntu 24.04 vs 22.04
Тот же чеклист. Unit ssh vs детали socket. deb822 sources. Команды в статьях узлах.
Можно ли baseline без консоли BMC?
Риск lockout. Для облака — serial console. Без запасного входа не включайте UFW и не режьте Password до ключа.