Hardening Ubuntu — это управляемое уменьшение поверхности атаки, а не запуск случайного скрипта из интернета. CIS Benchmark даёт согласованный baseline безопасной конфигурации, но применять его нужно с учётом роли сервера. Настройка, подходящая для bastion-host, может нарушить работу web-приложения, Docker или агента мониторинга.
Ниже — практический порядок работ для Ubuntu 24.04 LTS. Он не заменяет официальный CIS Benchmark: зафиксируйте используемую версию документа, профиль Level 1 или Level 2 и каждое исключение. Изменения сначала проверяйте на стенде и только потом переносите в production.
Снимите текущее состояние и подготовьте откат
cat /etc/os-release
uname -r
systemctl --failed
systemctl --type=service --state=running
ss -tulpn
df -h
sudo cp -a /etc /root/etc-before-hardening
Копия /etc полезна для сравнения, но не заменяет полный backup. Создайте снимок VPS или проверенную резервную копию, убедитесь в наличии web-консоли и зафиксируйте ожидаемые порты. Не начинайте с firewall, если не знаете, как восстановить доступ.
Обновления и поддерживаемая система
sudo apt update
apt list --upgradable
sudo apt full-upgrade
sudo apt install unattended-upgrades needrestart
sudo dpkg-reconfigure unattended-upgrades
Автоматическая установка security updates снижает окно уязвимости, но перезагрузки и изменения критичных библиотек должны контролироваться. Команда needrestart помогает увидеть процессы, использующие старые версии библиотек. Для production назначьте окно обслуживания и мониторинг после обновления.
Удаляйте пакет только после проверки зависимостей:
apt-mark showmanual
sudo apt autoremove --dry-run
Минимизация сервисов и портов
Каждый активный демон — дополнительный код и потенциальная точка входа. Сравните список сервисов с ролью узла:
systemctl list-unit-files --state=enabled
ss -lntup
sudo lsof -i -P -n | grep LISTEN
Не отключайте службы по названию без понимания зависимости. Сначала выполните systemctl status и systemctl cat, затем остановите сервис в тестовой среде и проверьте приложение.
UFW и сетевой baseline
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow from 203.0.113.10 to any port 22 proto tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status numbered
Разрешайте только реальные сервисы. PostgreSQL, Redis, панели администрирования и Docker API должны находиться в private network, VPN или слушать localhost. Правила облачного firewall и UFW должны дополнять друг друга, а не противоречить.
SSH hardening
Создайте drop-in /etc/ssh/sshd_config.d/60-hardening.conf:
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin no
PubkeyAuthentication yes
PermitEmptyPasswords no
MaxAuthTries 3
LoginGraceTime 30
X11Forwarding no
AllowUsers admin deploy
sudo sshd -t
sudo systemctl reload ssh
sudo sshd -T | grep -E 'passwordauthentication|permitrootlogin'
Держите открытой резервную сессию, пока не проверите новый вход. Для критичных узлов добавьте MFA или аппаратные FIDO2-ключи.
AppArmor и принцип наименьших привилегий
Ubuntu использует AppArmor для ограничения возможностей процессов. Проверьте состояние:
sudo aa-status
systemctl status apparmor
Не переводите профиль в complain-mode навсегда только потому, что приложение получает отказ. Изучите событие, уточните профиль и верните enforce. Отключение AppArmor целиком убирает важный слой защиты.
Пользователи, sudo и права
getent passwd
getent group sudo
sudo -l -U admin
sudo find / -xdev -type f -perm -0002 -ls
sudo find / -xdev -type f -perm /6000 -ls
Последние команды находят world-writable и setuid/setgid-файлы. Они не являются списком для удаления: системные бинарники могут иметь такие права законно. Сравнивайте результат с пакетной базой и ролью сервера.
Сервисам назначайте отдельных системных пользователей без интерактивного shell. Не запускайте web-приложение от root. Права на секреты обычно должны быть доступны только владельцу процесса.
systemd sandboxing
Для собственного сервиса используйте ограничения unit-файла:
[Service]
User=myapp
Group=myapp
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/var/lib/myapp
CapabilityBoundingSet=
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
Каждый параметр тестируйте. systemd-analyze security имя.service помогает оценить изоляцию, но высокий балл не гарантирует безопасность приложения.
Журналирование и auditd
sudo apt install auditd audispd-plugins
sudo systemctl enable --now auditd
sudo auditctl -s
journalctl -p warning..alert --since today
Определите retention и ограничение диска для journald. Критичные события отправляйте на отдельный сервер, поскольку локальные логи могут исчезнуть вместе с узлом.
Параметры ядра и сети
Не копируйте огромные списки sysctl из старых гайдов. Часть параметров устарела, часть мешает контейнерам или маршрутизации. Вносите только настройки, соответствующие роли узла, через файл в /etc/sysctl.d/, затем применяйте и проверяйте:
sudo sysctl --system
sudo sysctl -a | grep '^net.ipv4'
Резервные копии и восстановление
Храните копию вне VPS, шифруйте её и ограничивайте учётную запись backup только нужным направлением. Тест восстановления должен включать базу, файлы, секреты, конфигурацию и функциональную проверку приложения. Зафиксируйте фактические RTO/RPO.
Проверка после hardening
- SSH доступен из разрешённой сети;
- web-приложение отвечает по HTTPS;
- база недоступна из интернета;
- cron, очереди и systemd-сервисы работают;
- AppArmor не создаёт неожиданных отказов;
- логи и алерты поступают;
- backup создаётся и восстанавливается;
- изменения задокументированы.
Файловые системы и временные каталоги
CIS уделяет внимание параметрам монтирования, но их влияние зависит от роли узла. Для временных и пользовательских разделов рассматривают nodev, nosuid и noexec. Параметр noexec не является полноценной защитой от выполнения кода и может ломать установщики, агенты и приложения, которые запускают файлы из /tmp. Сначала соберите фактическое использование, затем применяйте на стенде.
findmnt --verify
findmnt -o TARGET,SOURCE,FSTYPE,OPTIONS
systemd-analyze verify /etc/fstab
После изменения /etc/fstab выполните проверку до перезагрузки. Ошибка в записи способна оставить сервер в emergency mode.
Синхронизация времени
Корректное время критично для TLS, журналов, токенов и расследований. Используйте один управляемый механизм синхронизации и проверяйте его состояние:
timedatectl status
timedatectl timesync-status
systemctl status systemd-timesyncd
Не запускайте несколько NTP-клиентов одновременно. Для инфраструктуры с требованиями к точности укажите утверждённые источники времени и мониторьте смещение.
Контроль целостности
Проверка целостности помогает заметить неожиданные изменения системных файлов. Инструмент должен иметь доверенную базу, созданную после установки и hardening, а результаты — уходить за пределы проверяемого сервера. Локальная база, которую может изменить root, мало полезна против полной компрометации.
Для пакетных файлов используйте возможности менеджера пакетов, для собственных конфигураций — Git/Ansible и контроль хэшей. Не пытайтесь мониторить каждый изменяемый файл: логи, кэш и runtime-каталоги создадут постоянный шум.
Автоматизация и проверка соответствия
Описывайте baseline в коде, но разделяйте проверку и исправление. Сначала audit формирует отчёт, затем инженер оценивает влияние, после чего remediation применяется небольшими группами. Для каждого исключения укажите причину, владельца, компенсирующую меру и дату пересмотра.
После обновления Ubuntu или CIS Benchmark запустите проверку заново. Номер «100% compliance» не является целью сам по себе: важнее соответствие реальной модели угроз и отсутствие неконтролируемых отклонений.
FAQ
Можно ли применить CIS одной командой?
Технически существуют средства автоматизации, но без профиля, тестов и отката они способны нарушить работу сервера.
Level 2 всегда безопаснее Level 1?
Level 2 строже и может сильнее влиять на совместимость. Выбор зависит от угроз и назначения системы.
Hardening нужно повторять?
Да. Новые пакеты, сервисы и доступы меняют состояние, поэтому проверки должны быть регулярными.
Для сайтов, ботов и pet-проектов можно использовать Beget: виртуальный хостинг от 420 ₽/мес., VPS от 330 ₽/мес. и тестовый период.
Разберём задачу по VPS/Linux, DNS, WordPress, Telegram-ботам и интеграциям. Стоимость определяется после оценки объёма.

