Погодин Евгений — ИТ Заметки
🔐Безопасность Обновлено 10.11.2026

Безопасность для начинающих 08. Базовая защита Linux-сервера: закалка за час

Note

Материал сверен с официальной документацией (документация Ubuntu Server и Ubuntu Security, man-страницы, документация systemd; ссылки — в конце статьи). Примеры вывода — иллюстрации: на вашей системе значения и формат могут отличаться. Перед работой на боевых системах проверьте шаги на тестовой машине.

Сервер lnx2 работает: файлы доступны, агент мониторинга отвечает (lnx1 — сервер Zabbix, сайт из Безопасность 09 стоит на нём, шаги те же). Потом вы читаете журнал и видите чужие адреса, перебирающие имена пользователей, а в интернете находите гигантский чек-лист, часть пунктов которого способна сломать сервер. С чего начать и когда остановиться? Свежая Ubuntu устроена безопасно, но, как сказано в документации Ubuntu, эту защиту легко ослабить случайно. Поэтому «закалка» здесь — не набор волшебных настроек, а порядок: сузить то, что видно снаружи, проверить уже настроенное, добавить недостающее и записать, как всё откатить. В статье девять шагов, у каждого есть проверка и откат.

№ Шаг Что проверяем
1 Порты и пакеты что слушает сервер и что на нём установлено
2 Пользователи и sudo кто может повышать права
3 SSH итоговая конфигурация sshd -T
4 Брандмауэр совпадает ли ufw (Uncomplicated Firewall) с реальными портами
5 Обновления работают ли автообновления, нужна ли перезагрузка
6 AppArmor включён ли, нет ли отказов
7 fail2ban блокировки и белый список
8 Службы оценка systemd-analyze security
9 Файлы, ядро, время SUID-файлы, sysctl, часы

Порядок не случаен (практика автора): шаги 1–2 уменьшают то, что вообще можно атаковать, шаги 3–5 закрывают двери и латают известные дыры, шаги 6–8 ограничивают ущерб, если что-то всё же сломали, а шаг 9 и скрипт в конце помогают заметить отклонения. Это принципы «наименьшей поверхности» и «глубокой защиты» из Безопасность 01: ни один слой не рассчитан на то, что остальные не подведут.

Warning

Шаги про SSH, ufw, fail2ban и sysctl способны отрезать вас от сервера. Держите открытой консоль ВМ в гипервизоре и второй сеанс SSH, проверяйте конфигурацию SSH командой sshd -t до перезагрузки службы, добавляйте ufw allow OpenSSH до ufw enable, вносите свой адрес в белый список fail2ban до его запуска. Перед правкой сохраняйте копию файла. Все примеры — для Ubuntu 24.04 LTS; адреса 192.168.10.x учебные.

Что нужно знать заранее

Подготовка: страховка

Откройте консоль ВМ и второй сеанс SSH, затем сохраните копию настроек. Архив содержит и хеши паролей, поэтому создаём его с закрытыми правами:

sudo sh -c 'umask 077; tar -czpf /root/etc-before.tar.gz /etc'
sudo ls -l /root/etc-before.tar.gz

Отдельный файл возвращают из архива командой sudo tar -xzpf /root/etc-before.tar.gz -C / etc/ssh/sshd_config.d/10-keys-only.conf (путь — свой). Копию удалите, когда закончите.

Шаг 1. Что слушает сервер и что на нём стоит

Открытый порт — это служба, в которой может оказаться уязвимость, поэтому лишние порты увеличивают поверхность атаки. Смотрите слушающие порты без loopback-адресов, то есть те, что видны из сети (так делает и документация Ubuntu):

sudo ss -utlnp | grep -vE '127(\.[0-9]+){3}|\[::1\]'

Пример вывода (колонки сокращены):

State  Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0      128    0.0.0.0:22         0.0.0.0:*         sshd
LISTEN 0      50     *:445              *:*               smbd
LISTEN 0      4096   *:10050            *:*               zabbix_agent2

0.0.0.0, [::] и * значат «все адреса». Для каждой строки спросите: нужна ли служба, должна ли она отвечать всем. Ненужную остановите и отключите, остальным сузьте адрес в настройках самой службы (служба только для этого сервера слушает 127.0.0.1), а доступ к порту ограничьте брандмауэром (шаг 4):

sudo systemctl stop <служба>
sudo systemctl disable <служба>

Отключённая служба может стартовать как зависимость другой; откат — sudo systemctl enable --now <служба>.

С пакетами осторожнее. Удалять безопасно то, что вы поставили сами и больше не нужно (apt-mark showmanual покажет вручную установленные, но в списке будут и пакеты базовой установки). Пакеты базовой установки Ubuntu без нужды не убирайте: Ubuntu предупреждает, что это ведёт к неожиданной потере функций, даже если они кажутся лишними. Удаляйте командой sudo apt remove <пакет> после чтения списка зависимых; откат — sudo apt install <пакет>.

Шаг 2. Пользователи и sudo

Принцип прост: обычные учётные записи без лишних прав, sudo только для администрирования, у каждого человека своя запись (Безопасность 06). Проверьте, кто что может:

getent group sudo
sudo grep -rn 'NOPASSWD' /etc/sudoers /etc/sudoers.d
getent passwd | awk -F: '$3 >= 1000 && $3 < 65534 {print $1, $7}'
last -n 10

Первая команда показывает членов группы sudo, вторая — правила без пароля, третья — обычные учётные записи и их оболочки, четвёртая — последние входы (откуда и когда). Лишнего участника sudo уберите: sudo deluser <имя> sudo (откат — sudo adduser <имя> sudo). Запись, которой никто не пользуется, отключите: sudo usermod --expiredate 1 <имя> (откат — sudo usermod --expiredate '' <имя>) и проверьте её ~/.ssh/authorized_keys (Linux 08). Правила NOPASSWD: ALL в боевой системе не нужны.

Шаг 3. SSH: проверяем итог

Справка man и реальность расходятся. По sshd_config(5) значение X11Forwarding по умолчанию no, но в файле /etc/ssh/sshd_config, который ставит Ubuntu, стоит X11Forwarding yes: справка сама предупреждает, что пакет Debian задаёт несколько значений, отличных от умолчаний sshd. Поэтому смотрите итоговые значения, а не память:

sudo sshd -T | grep -E \
  -e '^(permitrootlogin|passwordauthentication) ' \
  -e '^(kbdinteractiveauthentication|x11forwarding) ' \
  -e '^(allowtcpforwarding|allowusers|listenaddress) '

Пример вывода (порядок и формат могут отличаться):

permitrootlogin no
passwordauthentication no
kbdinteractiveauthentication no
x11forwarding yes
allowtcpforwarding yes
allowusers admin-lab
listenaddress 0.0.0.0:22
listenaddress [::]:22

Что должно получиться:

Директива По умолчанию по man Что нужно
PermitRootLogin prohibit-password no
PasswordAuthentication, KbdInteractiveAuthentication yes (Ubuntu ставит no для второй) no после проверки входа по ключу
X11Forwarding no, но в файле Ubuntu yes no, если графические программы не нужны
AllowUsers, AllowGroups пускают всех список нужных
ListenAddress все локальные адреса при нескольких интерфейсах — только адрес управления; смена адреса требует systemctl daemon-reload и systemctl restart ssh.socket (Linux 08)

Чтобы выключить X11, добавьте строку в свой файл из sshd_config.d (например, в 10-keys-only.conf): значения из этого каталога подключаются раньше основного файла и побеждают. Проверка и применение: sudo sshd -t, затем sudo systemctl reload ssh, затем вход из нового сеанса, пока старый открыт. Откат — удалить строку и снова выполнить reload. Запрет X11 защищает прежде всего клиентов; на сервере без графических программ пересылка X11 не нужна.

Не все «галочки» из чек-листов работают. По man, запрет AllowTcpForwarding и AllowAgentForwarding не повышает безопасность, пока у пользователя есть доступ к оболочке: он всегда может поставить свой переадресатор. Эти запреты имеют смысл для записей без оболочки (например, только для SFTP). Смена порта SSH — не защита, об этом сказано в Linux 08.

Шаг 4. Брандмауэр: сверяем, а не настраиваем

Включение ufw и порядок правил описаны в Linux 07. Здесь нужна сверка двух списков: что слушает сервер (шаг 1) и что разрешено в ufw. Если ufw status verbose показывает Status: inactive (по умолчанию он выключен), включите его по Linux 07: сначала sudo ufw allow OpenSSH, затем sudo ufw enable, консоль ВМ открыта.

sudo ufw status verbose

Для входящих должна стоять политика deny, а каждому порту из шага 1 соответствует правило с адресом источника, если порт нужен не всем. Например, порт агента мониторинга открывают только серверу мониторинга:

sudo ufw allow from 192.168.10.20 to any port 10050 proto tcp
sudo ufw delete allow from 192.168.10.20 to any port 10050 proto tcp

Вторая команда — откат. Порт управления SSH при возможности ограничьте адресами администраторов, как в Linux 07. Если на сервере есть Docker, помните: опубликованные порты контейнеров обходят правила ufw (см. там же), а как публиковать их безопасно и почему не нужен --privileged, сказано в Linux 10.

Шаг 5. Обновления и перезагрузки

Регулярно обновляйтесь и держите включённым unattended-upgrades: исправления безопасности должны ставиться без вашего участия. Проверка, что всё работает (подробности — в Linux 05):

cat /etc/apt/apt.conf.d/20auto-upgrades
sudo unattended-upgrade --dry-run -v
test -f /run/reboot-required && echo "нужна перезагрузка"

Пробный запуск ничего не меняет. Если файл /run/reboot-required существует, ядро или библиотеки обновлены, но работают старые версии, пока вы не перезагрузитесь в удобное окно. Сторонних репозиториев по возможности избегайте. Если критичная служба установлена из universe, помните, что исправления безопасности для этого компонента официально обеспечивает подписка Ubuntu Pro (Linux 05). Как выбирать срок и порядок установки — в Безопасность 03.

Шаг 6. AppArmor: не отключать

AppArmor — система мандатного контроля доступа. Обычные права Linux (DAC, избирательный контроль доступа) определяют, что может пользователь, а AppArmor добавляет политику, за пределы которой не выйдет и программа: профиль перечисляет файлы, сетевые действия и привилегии, которые ей разрешены. Ubuntu загружает AppArmor по умолчанию.

sudo aa-status
sudo journalctl -k --since today -g 'apparmor="DENIED"'

Пример вывода первой команды (значения вымышленные):

apparmor module is loaded.
110 profiles are loaded.
102 profiles are in enforce mode.
8 profiles are in complain mode.
Out of 129 processes running:
13 processes have profiles defined.

Профиль работает в одном из двух режимов: enforce запрещает и записывает нарушения, complain только записывает. Вторая команда ищет в журнале ядра отказы. Если служба не работает после смены каталога данных или обновления, причина может быть там. Ubuntu настоятельно не советует «лечить» это отключением AppArmor целиком: пропадёт защита всех остальных программ, в том числе snap-пакетов. Порядок такой:

  1. Найдите в журнале отказ и запомните профиль (поле profile=).
  2. Переведите в режим complain только этот профиль: sudo aa-complain /путь/к/программе (команда из пакета apparmor-utils). Если служба заработала, причина подтверждена.
  3. Добавьте нужное разрешение. Для некоторых профилей предусмотрены локальные файлы в /etc/apparmor.d/local/: правки там не теряются при обновлении пакета. Перезагрузите профиль: sudo apparmor_parser -r /etc/apparmor.d/<профиль>.
  4. Верните режим enforce: sudo aa-enforce /путь/к/программе.

Последнее средство — отключить только проблемный профиль. Отключение всего AppArmor параметром ядра apparmor=0 не делайте. Если конфликт похож на ошибку профиля пакета, сообщите о ней в Launchpad.

Шаг 7. fail2ban: помощник, а не защита

fail2ban читает журналы, находит повторяющиеся неудачные входы и временно блокирует адрес средствами брандмауэра. Пакет Ubuntu уже включает защиту sshd (файл /etc/fail2ban/jail.d/defaults-debian.conf: [sshd] enabled = true, banaction = nftables, журнал systemd), а по умолчанию 5 неудач за 10 минут дают блокировку на 10 минут. Базовую настройку, jail.local и значения bantime и findtime разбирает Linux 08; здесь только то, чего там нет.

Пределы защиты. Если вход по паролю в SSH отключён, подбирать пароли нечего: fail2ban лишь уменьшает шум в журналах. Больше пользы там, где пароли есть: в jail.conf есть заготовки для nginx, postfix, dovecot и общая защита recidive для повторяющихся нарушителей. Главный риск — заблокировать самих себя, поэтому порядок такой: сначала файл с белым списком, потом установка (пакет запускает службу сразу).

sudo mkdir -p /etc/fail2ban
sudo nano /etc/fail2ban/jail.local
sudo apt install fail2ban
[DEFAULT]
ignoreip = 127.0.0.1/8 ::1 192.168.10.101

В ignoreip внесите адрес административной станции (в лаборатории PC1; при сегментации — подсеть управления из Безопасность 05), а не весь офис: иначе подбор с заражённого компьютера останется незамеченным. Собственные адреса сервера игнорируются и так (ignoreself). Остальные значения оставьте по умолчанию либо задайте как в Linux 08.

Проверьте, что защита видит неудачные входы. Фильтр sshd пакета Ubuntu 24.04 задаёт journalmatch = _SYSTEMD_UNIT=sshd.service + _COMM=sshd; «+» означает «или» (journalctl(1)), поэтому записи службы ssh.service подходят по условию _COMM=sshd, хотя имя службы в первом условии иное. Всё же проверьте на деле: сделайте 2–3 неудачные попытки входа с тестового адреса вне ignoreip и посмотрите, растёт ли Total failed. Если нет, укажите условие явно: добавьте в jail.local блок [sshd] со строкой journalmatch = _SYSTEMD_UNIT=ssh.service + _COMM=sshd (так сделано в пакете 26.04).

sudo fail2ban-client -t
sudo systemctl restart fail2ban
sudo fail2ban-client status sshd
sudo fail2ban-client get sshd ignoreip

Пример вывода status sshd для 24.04 (формат приблизительный):

Status for the jail: sshd
|- Filter
|  |- Currently failed: 1
|  |- Total failed:     27
|  `- Journal matches:  _SYSTEMD_UNIT=sshd.service + _COMM=sshd
`- Actions
   |- Currently banned: 2
   |- Total banned:     5
   `- Banned IP list:   203.0.113.50 198.51.100.7

Если заблокировали себя, войдите через консоль ВМ или с другого адреса и снимите блокировку: sudo fail2ban-client unban <адрес>. Откат всего: sudo rm /etc/fail2ban/jail.local, затем sudo systemctl restart fail2ban (полностью отключить — sudo systemctl disable --now fail2ban).

Шаг 8. Службы: оценка systemd-analyze security

systemd умеет запирать службу в «песочнице»: делать системные каталоги доступными только для чтения, скрывать /home, запрещать повышение привилегий. Оценит текущую картину команда:

systemd-analyze security --no-pager
systemd-analyze security --no-pager ssh.service

Без имени она показывает таблицу по всем работающим службам, с именем — подробный разбор. Оценка (exposure level) лежит в диапазоне от 0.0 до 10.0: чем выше, тем меньше ограничений. Высокая оценка не означает, что служба уязвима, а низкая не гарантирует безопасности; инструмент учитывает только возможности самого systemd, а не защиту внутри программы. Гнаться за нулём не нужно: чем строже песочница, тем вероятнее, что служба перестанет работать.

Если вы пишете собственную службу, ужесточайте по одной настройке через drop-in (sudo systemctl edit myapp.service):

[Service]
NoNewPrivileges=yes
PrivateTmp=yes
ProtectSystem=full
ProtectHome=yes

NoNewPrivileges не даёт процессу и его потомкам получить новые привилегии через setuid и подобное, PrivateTmp даёт службе собственные /tmp и /var/tmp, ProtectSystem=full делает /usr, /boot и /etc доступными только для чтения, ProtectHome скрывает /home. Добавляйте строки по одной: после каждой sudo systemctl restart myapp и проверка работы; если служба пишет в /etc, разрешите это через ReadWritePaths=. Откат — sudo systemctl revert myapp.service: он удаляет drop-in. Системные службы вроде ssh без нужды не трогайте.

Шаг 9. Файлы, ядро и время

SUID-файлы. Файлы с битом setuid запускаются с правами владельца (Linux 04). Практика автора: сохраните список сегодня и сравнивайте после обновлений, новая строка — повод разобраться. Команда find с опцией -xdev не заходит в другие файловые системы, поэтому для отдельных разделов (например, /home) повторите её с их путём.

sudo find / -xdev -perm -4000 -type f 2>/dev/null | sort |
  sudo tee /root/suid-baseline.txt > /dev/null
sudo find / -xdev -type f -perm -0002 2>/dev/null

Вторая команда ищет файлы, доступные на запись всем.

sysctl. Ubuntu уже включает защиты ядра, а страница «Dangerous sysctls» перечисляет параметры, которые требуют осторожности при изменении. Некоторые старые советы устарели: например, отключать tcp_timestamps для «безопасности» больше не нужно, на современных системах Ubuntu рекомендует значение 1. Поэтому здесь нужна только проверка:

sysctl kernel.dmesg_restrict kernel.kptr_restrict kernel.randomize_va_space \
  kernel.yama.ptrace_scope fs.protected_symlinks fs.protected_hardlinks \
  net.ipv4.tcp_syncookies

Ubuntu рекомендует: dmesg_restrict равно 1, kptr_restrict 1 или 2, randomize_va_space 2, ptrace_scope не 0, protected_symlinks и protected_hardlinks 1, tcp_syncookies 1. Если видите другое, найдите, кто это изменил (/etc/sysctl.conf, /etc/sysctl.d/), и верните рекомендованное значение. Правьте файл, а не sysctl -w, предварительно сохранив копию; применяется файл командой sudo sysctl -p <файл>, откат — возврат копии и тот же sysctl -p.

Время и журналы. Проверьте timedatectl status: в строке System clock synchronized должно быть yes (Безопасность 07). Там же — auditd, оповещения и копии журналов; в этой статье они не повторяются.

Итоговая проверка одним скриптом

Скрипт ничего не меняет, только собирает основное для чтения. Сохраните его как check-hardening.sh и запускайте через sudo bash check-hardening.sh:

#!/bin/bash
# Только чтение. Запуск: sudo bash check-hardening.sh
[ "$(id -u)" -eq 0 ] || { echo "Запустите через sudo"; exit 1; }

echo "== Порты, видимые из сети"
ss -utlnp | grep -vE '127(\.[0-9]+){3}|\[::1\]'
echo "== SSH, итоговые значения"
sshd -T | grep -E '^(permitrootlogin|passwordauthentication) '
sshd -T | grep -E '^(x11forwarding|allowusers) '
echo "== ufw"
ufw status verbose | head -n 5
echo "== AppArmor"
aa-status --enabled && echo "профилей загружено: $(aa-status --profiled)"
echo "в режиме complain: $(aa-status --complaining)"
echo "== Автообновления"
cat /etc/apt/apt.conf.d/20auto-upgrades
[ -f /run/reboot-required ] && echo "ТРЕБУЕТСЯ ПЕРЕЗАГРУЗКА"
echo "== fail2ban"
fail2ban-client status sshd 2>&1 | head -n 8
echo "== Группа sudo и время"
getent group sudo
timedatectl status | grep -i 'synchronized'

Практика автора: запускайте его после каждого обновления релиза и раз в месяц, изменения видны сразу. Эти девять шагов закрывают типичные слабые места, но не делают сервер неуязвимым: у вас должны быть ещё резервные копии (3-2-1), мониторинг и план действий на случай инцидента (Безопасность 10).

Tip

Чек-лист.

  • Из сети видны только нужные порты, остальное закрыто или слушает 127.0.0.1.
  • В группе sudo только администраторы, правил NOPASSWD: ALL нет.
  • sshd -T показывает отключённые пароль и вход root, X11Forwarding no, список допущенных пользователей.
  • ufw включён: входящие запрещены, нужные порты открыты по источникам.
  • Автообновления работают, перезагрузки после них планируются.
  • AppArmor включён, проблемные профили чинят по одному, а не отключают всё.
  • В fail2ban внесён свой адрес в ignoreip, известен способ снять блокировку.
  • Список SUID-файлов сохранён, sysctl не ослаблен, время синхронизировано.

Состояние на ноябрь 2026 года (проверьте актуальность). По документации пакетов Ubuntu 24.04 LTS содержит OpenSSH 9.6, fail2ban 1.0.2, AppArmor 4.0.1 и auditd 3.1.2, а Ubuntu 26.04 LTS — OpenSSH 10.2, fail2ban 1.1.0, AppArmor 5.0.2 и auditd 4.1.2; сверьте свои версии командой apt policy. В OpenSSH 10.2 включены по умолчанию штрафы PerSourcePenalties (адрес с неудачными попытками на время получает отказ в соединении), в версии из 24.04 их нет. Строка X11Forwarding yes стоит в поставляемом sshd_config и в 24.04, и в 26.04. Условие по службе в фильтре sshd пакета 24.04 называет sshd.service, в пакете 26.04 — ssh.service; условие _COMM=sshd пропускает записи процесса sshd. Страница Ubuntu «Security suggestions» называет полезными для сервера Ubuntu Pro, расширенное обслуживание безопасности (ESM) и Livepatch (исправления ядра без немедленной перезагрузки) и сообщает, что Pro бесплатен для личного и делового использования на пяти машинах; условия проверьте на сайте.

Типичные ошибки и недоразумения

  • Отключили AppArmor, «чтобы заработало». Защита пропала у всех программ. Находите профиль, переводите в complain, правьте.
  • Включили ufw без правила для SSH. Новые подключения отклоняются; лечится консолью ВМ (sudo ufw allow OpenSSH).
  • fail2ban без ignoreip или с белым списком на весь офис. Либо блокируете себя, либо не видите подбор изнутри.
  • Смена порта SSH вместо ключей. Порт находят сканированием; защищают ключи и ограничение адресов.
  • Чужой список sysctl «для безопасности». Он может ослабить защиту; проверяйте значения, а не добавляйте.
  • Удалили пакеты базовой установки по чек-листу. Пропали функции; удалять стоит то, что поставили сами.
  • Автообновления отключили, чтобы не перезагружаться. Без обновлений дыры остаются открытыми, а перезагрузку можно планировать.
  • Скопировали правила NOPASSWD: ALL. Любой, кто получил доступ к такой записи, получает root без пароля.

Проверьте себя

  1. Как узнать действующие значения SSH и почему нельзя доверять только man-странице? sudo sshd -T: он показывает итог с учётом всех файлов. В файле Ubuntu стоит X11Forwarding yes, хотя по man значение по умолчанию no.
  2. Служба не стартует, в журнале ядра apparmor="DENIED". Что делать? Найти профиль, перевести только его в complain, добавить разрешение (например, в /etc/apparmor.d/local/), вернуть enforce; AppArmor целиком не отключать.
  3. Зачем нужен ignoreip и как снять блокировку? Он перечисляет адреса, которые fail2ban не блокирует, чтобы не заблокировать самих себя; блокировку снимает sudo fail2ban-client unban <адрес>.
  4. Что означает высокая оценка systemd-analyze security? Что у службы мало ограничений песочницы. Это не значит, что она уязвима, а низкая оценка не гарантирует безопасности.
  5. Чем 0.0.0.0:3306 в выводе ss опаснее 127.0.0.1:3306? Первая запись означает, что порт слушает на всех адресах и виден из сети, вторая — только локальным процессам.

Что дальше

Источники

Ещё по теме «Безопасность»