РАЗБОР
На проверке
Hardening Linux сервера: чек-лист для blue team
[ обложка статьи ]
Режим чтения
Понедельник, 9:15 утра. Алерт в SOC: исходящее TCP-соединение с известным C2-адресом с production-ноды Ubuntu 22.04. Через час постмортем показал картину, от которой хочется закрыть ноутбук и уйти в лес: атакующий зашёл через SSH с паролем сервисной учётки
deploy, поднял привилегии через забытый SUID-бинарник /usr/local/bin/backup-tool и закрепился cron-задачей от root. Сервер работал в проде восемь месяцев - ни одного прогона CIS-профиля за это время.Не zero-day. Не supply chain. Дефолтный
sshd_config, который «собирались захардить после релиза».По данным Verizon DBIR, misconfiguration входит в топ-5 причин утечек. А по российскому 152-ФЗ некорректная конфигурация сервера с персональными данными - это оборотные штрафы. Ниже - пошаговый hardening Linux сервера, где каждый шаг закрывает конкретную технику из MITRE ATT&CK.
Поверхность атаки Linux сервера через MITRE ATT&CK
Прежде чем крутить конфиги - зафиксируйте, что именно атакующий будет проверять первым делом. Маппинг типичных точек входа на Linux-сервере к конкретным техникам: Подробнее - в нашем подробном разборе linux для пентестера.| Вектор | MITRE ATT&CK | Результат для атакующего |
|---|---|---|
| SSH с паролем / дефолтным ключом | SSH (T1021.004, Lateral Movement) | Шелл + точка для горизонтального перемещения |
| Сервисные учётки с интерактивным shell | Local Accounts (T1078.003, Initial Access) | Легитимный доступ, невидимый для baseline-detection |
| SUID/SGID-бинарники | Linux and Mac Permissions (T1222.002, Defense Evasion) | Privilege escalation без эксплойтов ядра |
| Sudo misconfiguration | Sudo and Sudo Caching (T1548.003, Privilege Escalation) | Root через легитимный механизм |
| Writable cron | Cron (T1053.003, Persistence) | Персистентность, переживающая перезагрузку |
| Readable /etc/shadow | /etc/passwd and /etc/shadow (T1003.008, Credential Access) | Хеши для офлайн-брутфорса |
| Отключённый auditd | Disable or Modify Linux Audit System (T1562.012, Defense Evasion) | Невидимость для SOC |
| LD_PRELOAD / ld.so.preload | Dynamic Linker Hijacking (T1574.006, Defense Evasion) | Перехват вызовов библиотек, скрытый бэкдор |
Каждый раздел ниже закрывает один или несколько векторов из этой таблицы - не абстрактной «рекомендацией», а конкретной контрмерой с командой.
Аутентификация и защита SSH
SSH - основной вектор Lateral Movement (T1021.004). Автоматизированные сканеры находят открытый порт 22 за минуты. По данным DecryptionDigest, смена порта SSH на нестандартный снижает объём автоматизированного сканирования примерно на 80%, но это security through obscurity - дополнительный слой, а не замена нормальной аутентификации.Минимальный набор параметров
/etc/ssh/sshd_config: PermitRootLogin no, PasswordAuthentication no, PubkeyAuthentication yes, MaxAuthTries 3, AllowGroups admins, LoginGraceTime 30. Tunnel-возможности тоже режем: X11Forwarding no, AllowTcpForwarding no, AllowAgentForwarding no. Таймаут бездействия: ClientAliveInterval 300, ClientAliveCountMax 2.Криптография: ограничьте алгоритмы обмена ключами -
KexAlgorithms curve25519-sha256,diffie-hellman-group14-sha256, шифры - Ciphers aes256-gcm@openssh.com,chacha20-poly1305@openssh.com. Старые RSA/DSA ключи хоста - в топку: rm /etc/ssh/ssh_host_rsa_key[I] /etc/ssh/ssh_host_dsa_key[/I], генерируем Ed25519: ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N "".Для защиты от брутфорса - fail2ban с
maxretry = 3, bantime = 1h, findtime = 10m в секции [sshd] файла /etc/fail2ban/jail.local. Файрвол как дополнительный слой: на Ubuntu ufw default deny incoming + ufw allow from 10.0.0.0/8 to any port 22022; на RHEL firewall-cmd --set-default-zone=drop с whitelist для SSH-порта. Обе утилиты работают поверх nftables.Сервисные учётки: тихий вектор Initial Access
Техника Local Accounts (T1078.003) - одна из самых неприятных. Атакующий использует легитимную учётку, SIEM не видит ничего подозрительного. Найдите все аккаунты с интерактивным shell:awk -F: '$7 ~ /bash|sh|zsh/ {print $1}' /etc/passwd. Обычно там обнаруживается десяток сервисных учёток, которым shell вообще не нужен. Заблокируйте:
Bash:
for acct in games news lp sync shutdown halt operator; do
usermod -L -s /sbin/nologin $acct 2>/dev/null
done
passwd -l root и usermod -s /sbin/nologin root. Защита /etc/shadow от чтения (T1003.008): файл должен иметь права 640 с владельцем root:shadow - проверьте ls -la /etc/shadow. Парольную политику ужесточите через PAM: установите libpam-pwquality (Ubuntu) или pam_pwquality (RHEL), затем в /etc/security/pwquality.conf задайте minlen = 14, dcredit = -1, ucredit = -1. Блокировка после неудачных попыток: в /etc/security/faillock.conf - deny = 5, unlock_time = 900.Управление привилегиями sudo и минимизация поверхности атаки Linux
Sudo and Sudo Caching (T1548.003): атакующий получает shell пользователя с sudo-доступом, ждёт ввода пароля и использует кешированный токен для выполнения команд от root без повторной аутентификации. Бизнес-логика атаки простая: один скомпрометированный sudo-пользователь = root на сервере. Без вариантов.Контрмеры: создайте группу
admins и ограничьте sudo через /etc/sudoers.d/admins записью %admins ALL=(ALL) ALL. Отключите кеш: Defaults timestamp_timeout=0 - каждая команда требует пароль. Да, неудобно. Зато атакующий не проедет на кешированном токене. Включите логирование: Defaults logfile="/var/log/sudo.log". Для пентеста Linux сервера и верификации hardening - прогоните LinPEAS или linuxprivchecker: они первым делом проверяют sudo-конфигурацию и находят то, что вы пропустили.SUID-бинарники и cron: классические пути эскалации
Каждый SUID-бинарник - потенциальный privilege escalation без единого эксплойта. Поиск нестандартных:find / -perm -4000 -type f -not -path "/usr/[I]" -not -path "/bin/[/I]" 2>/dev/null. Сверьтесь с GTFOBins: если бинарник там есть (chmod, bash, awk, file, dmesg, apt, dnf), а SUID-бит стоит - это готовый path to root. Снимите бит: chmod u-s /path/to/binary. На практике я регулярно вижу кастомные бэкап-скрипты с SUID, которые кто-то поставил «временно» два года назад.Cron (T1053.003) - одновременно persistence и privilege escalation. Файлы
/etc/cron.d/, /etc/cron.daily/ и /etc/crontab должны принадлежать root с правами 600. Скрипты, вызываемые из cron, не должны быть writable для непривилегированных пользователей - иначе подмена содержимого даёт root shell по расписанию. Звучит банально, но встречается постоянно.Dynamic Linker Hijacking (T1574.006): проверьте, что файл
/etc/ld.so.preload пуст или отсутствует, а переменная LD_PRELOAD не задана глобально. Отключите неиспользуемые сервисы: systemctl list-units --type=service --state=running, затем systemctl disable --now cups avahi-daemon bluetooth postfix rpcbind - каждый лишний сервис расширяет поверхность.Системное усиление Linux: ядро и sysctl
включает логирование пакетов с невозможным source address - полезно для detection подозрительного сетевого трафика.
Что тут за что отвечает:
randomize_va_space = 2 включает полный ASLR; kptr_restrict = 2 скрывает адреса ядра из /proc/kallsyms, блокируя утечку layout для ROP-цепочек; dmesg_restrict = 1 закрывает доступ к dmesg для непривилегированных пользователей - через GTFOBins бинарник dmesg может читать чувствительную информацию. Монтируйте /tmp, /var/tmp, /dev/shm с опциями nodev,nosuid,noexec в /etc/fstab - это блокирует запуск бинарников из временных директорий при post-exploitation.Аудит безопасности Linux: auditd и detection для SOC
auditd - ядерный фреймворк аудита системных логов Linux. События пишутся в kernel ring buffer до того, как userspace-процесс может их перехватить. Это важно: даже если атакующий с root-правами убьёт демон auditd, события, уже попавшие в буфер, останутся. Установите:apt install auditd audispd-plugins (Ubuntu) или dnf install audit (RHEL), затем systemctl enable --now auditd. Если атакующий отключает auditd (T1562.012) - само отключение должно генерировать алерт в SIEM.CIS-aligned правила для
/etc/audit/rules.d/hardening.rules:
Код:
-D
-b 8192
-f 1
-w /etc/passwd -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/sudoers -p wa -k sudo_changes
-w /etc/ssh/sshd_config -p wa -k sshd_config
-a always,exit -F arch=b64 -S init_module -S finit_module -k modules
-e 2
-w /etc/passwd -p wa -k identity тегирует любое изменение файла паролей - SIEM-корреляция строится как алерт при identity событии вне окна change management. Правило -w /etc/ssh/sshd_config -k sshd_config детектирует модификацию конфига SSH: если кто-то включил PasswordAuthentication yes в проде - SOC узнает об этом, а не постмортем через полгода. Системный вызов init_module с тегом modules - индикатор загрузки kernel module и потенциального rootkit; если в проде никто не ставит драйверы, любое такое событие = инцидент. Флаг -e 2 делает правила immutable до перезагрузки - атакующий даже с root-правами не отключит auditd на лету.Для пересылки в SIEM настройте
audispd-plugins с syslog-output в формате CEF или JSON - зависит от стека (ELK, Splunk, MaxPatrol SIEM). Мониторинг целостности файлов вне auditd: AIDE фиксирует дельту файловой системы между проверками и ловит изменения, которые watch-правила auditd могут не покрыть.SELinux AppArmor конфигурация и systemd sandboxing
MAC-политики - рубеж, который работает когда атакующий уже получил code execution. Без Mandatory Access Control выполнение кода означает полный доступ ко всему, до чего дотянется процесс. С MAC - процесс ограничен профилем, даже если работает от root. На RHEL/CentOS/Rocky командаgetenforce должна возвращать Enforcing; если Permissive - setenforce 1 плюс SELINUX=enforcing в /etc/selinux/config. На Ubuntu/Debian - aa-status покажет профили в enforce mode; перевод из complain: aa-enforce /etc/apparmor.d/usr.sbin.your_service.По данным LinuxSecurity, в одном финансовом окружении SELinux-политики заблокировали pivot после компрометации веб-сервиса - инцидент потребовал реагирования, но не перерос в утечку данных. MAC сработал как последний рубеж, когда всё остальное уже было пробито.
systemd добавляет изоляцию без зависимости от MAC. Для каждого production-сервиса выполните
systemctl edit your-service и пропишите: ProtectSystem=strict (файловая система read-only кроме явных путей), ProtectHome=yes, NoNewPrivileges=yes (блокирует SUID-эскалацию из контекста сервиса), PrivateTmp=yes, ReadWritePaths=/var/lib/your-service. Параметр NoNewPrivileges - прямое противодействие SUID-атакам: если атакующий получил RCE в приложении, systemd не позволит использовать обнаруженный SUID-бинарник для эскалации. Настройка занимает пять минут на сервис, а закрывает целый класс атак.Автоматизация: CIS Benchmark Linux и инструменты аудита
Ручная настройка безопасности Linux сервера не масштабируется. CIS Benchmark для Ubuntu 22.04 LTS, RHEL 9, Debian 12 содержит более 250 правил. Два уровня:| Параметр | CIS Level 1 | CIS Level 2 |
|---|---|---|
| Цель | Минимальный baseline | Максимальная безопасность |
| Влияние на production | Минимальное | Может затронуть нагрузку |
| Пример | Отключение root SSH, ASLR | SELinux enforcing для всех сервисов |
| Применимость | Все серверы | PCI DSS, финтех, ПДн |
Альтернативные фреймворки: DISA STIG (DoD baseline для RHEL 8 и Ubuntu 22.04) - жёстче CIS, используется в государственных средах. NIST SP 800-53 (контроль CM-1: Configuration Management) определяет процесс на уровне организационной политики. Согласно CIS Controls v8 (CIS-4: Secure Configuration of Enterprise Assets and Software), hardening - непрерывный цикл: настройка, аудит, выявление drift, исправление. Не разовое мероприятие.
Инструменты проверки:
Lynis -
lynis audit system генерирует Hardening Index (0-100) и приоритизированные findings. Работает на всех дистрибутивах без подписки. Index ниже 70 - серьёзный сигнал, что LinPEAS найдёт path to root за минуты.OpenSCAP - автоматический аудит compliance. На Ubuntu доступен через Ubuntu Security Guide (USG) в составе Ubuntu Pro. Генерирует HTML-отчёт с точным маппингом к CIS-правилам.
CIS-CAT Pro - коммерческий инструмент от CIS с поддержкой автоматического remediation. Стоит денег, но на масштабе окупается.
Для массового деплоя - Ansible-плейбук, применяющий hardening-конфигурации при провижинге. Drift detection: запуск Lynis или OpenSCAP по расписанию с diff-анализом результатов относительно зафиксированного baseline.
Detection-чеклист: защита серверов для blue team после hardening
Hardening без мониторинга - половина работы. Таблица алертов для настройки в SIEM:| Событие | Источник | Тег auditd / лог | Severity |
|---|---|---|---|
| Изменение /etc/passwd или /etc/shadow | auditd | identity | Critical |
| Модификация sshd_config | auditd | sshd_config | High |
| Загрузка kernel module | auditd | modules | Critical |
| Изменение sudoers | auditd | sudo_changes | High |
| Остановка auditd | systemd journal | unit=auditd.service | Critical |
| SSH login от root | auth.log | session opened for user root | Critical |
| 5+ failed SSH за 10 мин | fail2ban / auth.log | Failed password | Medium |
| Новый SUID-бинарник | cron + find -perm -4000 | Дельта с baseline | High |
| SELinux/AppArmor в permissive | cron + getenforce/aa-status | Дельта с baseline | Critical |
| Появление /etc/ld.so.preload | auditd watch | linker_hijack | Critical |
Правило корреляции: если события
identity + sshd_config + modules происходят в течение 30 минут от одного источника - это kill chain in progress. Такая комбинация не встречается при плановом обслуживании и требует немедленного реагирования по playbook.Инсайдер и скомпрометированный легитимный хост
Отдельный сценарий, и самый неприятный: атакующий действует от имени легитимного пользователя с легитимной машины. Классический hardening тут не поможет - действия формально разрешены. Тут работает behavioral baseline: auditd с immutable rules покажет, чтоadmin-ivanov вдруг начал читать /etc/shadow (T1003.008), загружать kernel modules и менять sysctl - чего в его нормальном профиле активности не было. Без флага -e 2 атакующий с root-доступом просто удалит логи до того, как SIEM их заберёт.За последние два года я разбирал десятки инцидентов с Linux-серверами. Восемь из десяти начинались одинаково: дефолтная конфигурация, которую «собирались захардить, но руки не дошли». Не через zero-day и не через supply chain - через
sshd_config, который никто не трогал после установки, через SUID на кастомном скрипте и через auditd в состоянии inactive. CIS Level 1 закрывает 80% этих векторов за один Ansible-прогон.Индустрия вложила огромные ресурсы в EDR и threat intelligence, при этом половина production-серверов до сих пор работает с
PasswordAuthentication yes. Это не проблема инструментов - это проблема приоритетов: hardening откладывают «на после релиза», а релиз не заканчивается никогда. Hardening Index ниже 70 по Lynis означает, что LinPEAS найдёт path to root за минуты, и самый навороченный SIEM не поможет, если auditd не пишет события. По свежим инцидентам с misconfigured Linux на форуме codeby.net/forums/ разбираем hardening-baseline и detection-конфиги на практике.Содержание
Codeby Academy
Практика и мастерство
От основ до продвинутого — программы для практиков Codeby.
Перейти к курсу →
Комментарии
0