Блок 14
Безопасность Linux
> Что вас ждёт в этом блоке: мы соберём воедино всё, что изучили о пользователях (Блок 8), процессах и службах (Блоки 10–11), сети (Блок 12) и SSH (Блок 13), и посмотрим на систему глазами злоумышл…
Введение в блок
> Что вас ждёт в этом блоке: мы соберём воедино всё, что изучили о пользователях (Блок 8), процессах и службах (Блоки 10–11), сети (Блок 12) и SSH (Блок 13), и посмотрим на систему глазами злоумышленника — чтобы понять, как её защитить. Вы настроите firewall, установите защиту от перебора паролей, «закалите» (hardening) настройки SSH, включите автоматические обновления безопасности и научитесь проводить базовый аудит системы.
>
> Что нужно знать перед началом: весь материал Блока 13 (SSH обязателен — большая часть этого блока посвящена именно его защите), а также права доступа и sudo из Блока 8, службы из Блока 10, сеть и порты из Блока 12.
Урок 14.1. Основы информационной безопасности Linux
Сформировать системное понимание того, что такое информационная безопасность применительно к Linux-серверу: какие бывают угрозы, каковы базовые принципы защиты, и с чего начинается «закалка» (hardening) любой системы.
Теория
Зачем вообще думать о безопасности. Любой сервер, подключённый к интернету, находится под постоянным давлением автоматизированных атак. Это не теоретическая угроза для «крупных компаний» — даже маленький личный VPS-сервер, о существовании которого никто не знает, будет получать попытки подключения по SSH от ботов уже в первые минуты после появления в сети. Боты сканируют весь диапазон IP-адресов интернета непрерывно, в поисках открытых портов и слабых паролей.
Основные категории угроз для Linux-сервера:
- Перебор паролей (brute force) — автоматизированный подбор паролей к SSH, веб-приложениям, базам данных.
- Использование неисправленных уязвимостей — если система не обновляется, в ней могут годами существовать известные уязвимости, для которых существуют готовые эксплойты (программы для их использования).
- Неправильная конфигурация — открытые «на весь мир» службы, которые должны быть доступны только локально; слабые права доступа к файлам; излишние привилегии пользователей.
- Вредоносное ПО — вирусы, трояны, руткиты (специальный вид вредоносного ПО, маскирующийся под системные компоненты), криптомайнеры (незаконно использующие ресурсы сервера).
- Социальная инженерия и утечка учётных данных — например, случайная публикация пароля или ключа в открытом репозитории (это, увы, происходит постоянно даже с опытными разработчиками).
- DDoS-атаки (Distributed Denial of Service) — попытка «завалить» сервер огромным количеством запросов, чтобы сделать его недоступным для легитимных пользователей.
Фундаментальные принципы безопасности, которые применимы к любой системе:
1. Принцип наименьших привилегий (Principle of Least Privilege). Каждый пользователь, процесс и служба должны иметь ровно столько прав, сколько необходимо для их работы — не больше. Мы уже применяли этот принцип неявно: например, не работали постоянно от root (урок 8.3), а использовали sudo только когда это действительно требовалось.
2. Глубокоэшелонированная защита (Defense in Depth). Нельзя полагаться на одну-единственную меру защиты. Идея в том, чтобы выстроить несколько независимых «слоёв» обороны: даже если злоумышленник преодолеет один рубеж, его остановит следующий. В этом блоке мы выстроим сразу несколько таких слоёв: firewall (ограничивает сетевой доступ), Fail2Ban (блокирует после подозрительной активности), правильная настройка SSH (устраняет саму возможность подбора пароля), регулярные обновления (закрывают известные уязвимости).
3. Минимизация поверхности атаки (Attack Surface Reduction). Чем меньше открытых портов, запущенных служб и установленного ПО на сервере — тем меньше потенциальных точек входа для атаки. Правило простое: если служба не нужна — она должна быть отключена или удалена, а не «просто на всякий случай» установлена и работать в фоне.
4. Регулярные обновления. Разработчики программного обеспечения постоянно находят и исправляют уязвимости. Своевременная установка обновлений безопасности (мы подробно разбирали apt update/apt upgrade в Блоке 9) — одна из самых простых и при этом эффективных мер защиты.
5. Мониторинг и логирование. Нужно не только защищаться, но и иметь возможность заметить, если что-то пошло не так. Журналы системы (journalctl, изученный в Блоке 10) — первый источник информации при расследовании инцидента.
6. Принцип «нулевого доверия» к вводимым данным — актуален больше для разработки приложений, но важен и для администратора: никогда не предполагайте, что подключающийся к вашему серверу — «свой», пока это не доказано аутентификацией.
С чего начинается защита нового сервера (общий план, который мы реализуем по шагам в этом блоке):
- Обновить систему сразу после установки (
sudo apt update && sudo apt upgrade). - Создать отдельного пользователя с правами
sudo, не работать от root напрямую (это мы уже делаем с самого начала курса — см. Блок 8). - Настроить SSH-ключи и отключить вход по паролю (урок 14.4).
- Настроить firewall, разрешив только необходимые порты (урок 14.2).
- Установить защиту от перебора (Fail2Ban, урок 14.3).
- Включить автоматические обновления безопасности (урок 14.5).
- Регулярно проверять систему на предмет подозрительной активности (урок 14.6).
Именно эту последовательность шагов реальные администраторы выполняют на каждом новом сервере — это называется начальным хардненингом (initial hardening) или иногда «server hardening checklist».
Практика
В этом вводном уроке мы проведём первичный аудит текущего состояния системы — своего рода «медицинский осмотр» перед тем, как приступать к лечению.
Шаг 1. Проверьте, какие пользователи имеют право входа в систему и какие из них — административные (вспомните урок 8.2, где мы разбирали файл /etc/passwd):
```bash
cat /etc/passwd | grep -E "/bin/bash$|/bin/sh$"
```
Что вы увидите: список пользователей, у которых установлена интерактивная оболочка (то есть теоретически возможен вход в систему), в отличие от системных учётных записей с оболочкой /usr/sbin/nologin или /bin/false.
[Скриншот терминала]
Шаг 2. Проверьте, кто входит в группу sudo (имеет административные права — см. урок 8.3):
```bash
getent group sudo
```
Что вы увидите: список пользователей, у которых есть право выполнять команды с sudo.
Шаг 3. Проверьте, какие сетевые порты открыты и слушают входящие подключения (используем команду из урока 12.5):
```bash
sudo ss -tulnp
```
Что вы увидите: список всех служб, слушающих сеть, с указанием портов. Обратите внимание: любой порт в этом списке — потенциальная точка входа. Задайте себе вопрос по каждой строке: «действительно ли эта служба должна быть доступна по сети?».
[Скриншот терминала]
Шаг 4. Проверьте статус SSH-сервера и текущие настройки безопасности (файл конфигурации сервера, отличный от клиентского ~/.ssh/config из Блока 13):
```bash
sudo grep -E "^PermitRootLogin|^PasswordAuthentication|^Port" /etc/ssh/sshd_config
```
Что вы увидите: текущие значения ключевых параметров безопасности SSH-сервера (мы разберём их подробно в уроке 14.4). Скорее всего, увидите значения по умолчанию — именно их мы и будем «закалять».
Шаг 5. Проверьте, когда система последний раз обновлялась:
```bash
grep " upgrade\| install" /var/log/dpkg.log | tail -10
```
Что вы увидите: последние 10 записей об установке или обновлении пакетов с датами — это покажет, как давно система обновлялась в последний раз.
Шаг 6. Проверьте, установлен ли firewall и активен ли он:
```bash
sudo ufw status
```
Что вы увидите: скорее всего, Status: inactive — firewall ещё не настроен. Это мы исправим в следующем уроке.
[Скриншот терминала]
Шаг 7. Составьте в конспекте краткий отчёт по итогам этого мини-аудита: сколько пользователей с интерактивной оболочкой, сколько из них в группе sudo, сколько открытых портов, активен ли firewall, разрешён ли вход root по SSH, разрешена ли аутентификация по паролю.
Разбор команд
Команда getent
- Назначение:** получить записи из системных баз данных (пользователи, группы и др.), включая как локальные файлы, так и внешние источники (например, LDAP, если он настроен — для наших целей источник всегда локальный,
/etc/passwdи/etc/group). - Синтаксис:**
getent база_данных [ключ] - Примеры:**
getent passwd имя_пользователя— информация о конкретном пользователе;getent group sudo— состав группыsudo. - Почему не просто
cat /etc/group:**getentуниверсален и корректно работает, даже если в системе настроены внешние источники учётных записей (сетевые каталоги), тогда как прямое чтение файла/etc/groupпокажет только локальные записи.
Команда grep " upgrade\| install" /var/log/dpkg.log
- Назначение:** найти в системном логе dpkg (лог всех операций установки и обновления пакетов) строки об установке или обновлении.
- Разбор:** символ
\|внутриgrep(без ключа-E) экранирует специальное значение вертикальной черты как «ИЛИ» — то есть ищутся строки, содержащие либоupgrade, либоinstall.
Возможные ошибки
- Ошибка:** после первичного аудита обнаруживается, что вход по паролю разрешён для root напрямую по SSH.
Почему возникает: это настройка по умолчанию во многих базовых установках (хотя современные образы облачных провайдеров обычно уже отключают это).
Как определить: PermitRootLogin yes в выводе шага 4.
Как исправить: мы подробно разберём это в уроке 14.4 — отключение прямого входа root и переход на ключи.
Как избежать: проверять эту настройку сразу при получении доступа к новому серверу, до начала любой другой работы.
Практические задания
- Проведите аудит по шагам 1–6 практики на своей системе и запишите результаты в отдельный файл
~/security_audit_$(date +%Y%m%d).txtс помощью перенаправления вывода (мы изучали>в Блоке 6). - Изучите список процессов, запущенных от имени root (
ps aux | grep "^root"— командуpsмы изучали в Блоке 11), и выпишите пять любых процессов, объяснив в конспекте, зачем каждому из них могут требоваться права root. - Найдите в интернете (или, если доступен, на сайте CVE — Common Vulnerabilities and Exposures, общедоступная база данных известных уязвимостей) информацию о недавней громкой уязвимости в каком-либо Linux-компоненте и кратко опишите в конспекте, в чём она заключалась и как была исправлена.
Проверка знаний
Вопрос 1. Что такое «принцип наименьших привилегий» и как он уже применялся в этом курсе, даже если вы не осознавали этого явно?
Ответ: Принцип наименьших привилегий означает, что каждый пользователь, процесс или служба должны иметь минимально необходимый набор прав для выполнения своей задачи. Мы применяли его с самого начала курса: работали от обычного пользователя, а не от root, используя sudo только для конкретных административных команд (Блок 8), вместо того чтобы постоянно находиться в сессии с правами суперпользователя.
Вопрос 2. Почему принцип «глубокоэшелонированной защиты» важнее, чем полагаться на одну очень надёжную меру защиты (например, только на сложные пароли)?
Ответ: Потому что любая отдельная мера защиты может быть обойдена или содержать неизвестную уязвимость. Если полагаться только на одну линию обороны и она будет пробита — злоумышленник получает полный доступ. Несколько независимых слоёв защиты (firewall + Fail2Ban + SSH-ключи + обновления + мониторинг) означают, что даже успешный обход одного слоя не приведёт к компрометации системы, потому что дальше стоят другие барьеры.
Итоги урока
Вы изучили: основные категории угроз для Linux-сервера, фундаментальные принципы безопасности (наименьшие привилегии, глубокоэшелонированная защита, минимизация поверхности атаки, регулярные обновления, мониторинг), общий план начального хардненинга сервера.
Вы умеете: проводить базовый аудит безопасности системы (пользователи, порты, обновления, статус firewall и SSH).
В следующем уроке потребуется: понимание того, какие порты открыты в системе (шаг 3 практики) — это основа для настройки firewall.
Урок 14.2. Firewall: UFW (Uncomplicated Firewall)
Понять, что такое firewall и зачем он нужен, освоить UFW — самый простой и распространённый инструмент управления firewall в Ubuntu, настроить базовые правила для типичного сервера.
Теория
Что такое firewall. Firewall (межсетевой экран) — это система, которая контролирует, какой сетевой трафик разрешён, а какой заблокирован, на основе заданных правил. Представьте себе firewall как охранника на входе в здание: он проверяет каждого входящего (и иногда исходящего) по списку правил — «этому можно, этому нельзя» — и на основе портов, IP-адресов и протоколов принимает решение: пропустить пакет данных или отбросить его.
Зачем нужен firewall, если служба и так не запущена? Хороший вопрос. Ответ: firewall — это дополнительный, независимый слой защиты (вспомните принцип «глубокоэшелонированной защиты» из предыдущего урока). Даже если сегодня на сервере запущены только нужные службы, firewall защищает от:
- Случайно запущенной службы, которая по ошибке слушает на всех интерфейсах (мы видели в Блоке 12, что это распространённая ошибка конфигурации).
- Служб, установленных сторонним ПО, о которых вы могли не знать (некоторые пакеты автоматически поднимают вспомогательные службы).
- Будущих изменений конфигурации — забыть закрыть порт значительно проще, чем забыть про существование firewall с чётко описанной политикой.
Как работает firewall на техническом уровне (концептуально). В ядре Linux есть подсистема netfilter, которая может перехватывать, анализировать и фильтровать каждый сетевой пакет, проходящий через систему. Классический интерфейс для управления этой подсистемой называется iptables — мощный, но сложный в использовании инструмент с непростым синтаксисом. UFW (Uncomplicated Firewall, «незамысловатый firewall») — это надстройка над iptables, созданная специально для Ubuntu с целью значительно упростить типичные задачи настройки firewall, не требуя изучения синтаксиса iptables напрямую.
Базовая философия UFW-правил. Правила UFW обычно формулируются в терминах:
- Разрешить (allow) или запретить (deny) / отклонить (reject)** трафик.
- Определённый порт (
22,80) или диапазон портов, или именованную службу (ssh,http). - Протокол (
tcp,udp). - Направление: входящий (incoming) трафик — то, что приходит к вашему серверу, или исходящий (outgoing) — то, что уходит от сервера.
- Источник: конкретный IP-адрес или подсеть, откуда разрешён/запрещён трафик.
Политика по умолчанию (default policy). Прежде чем добавлять конкретные правила, задаётся общая политика: например, «по умолчанию весь входящий трафик запрещён, весь исходящий — разрешён». Затем добавляются точечные исключения («но разрешить входящий трафик на порт 22 для SSH»). Это гораздо безопаснее, чем подход «разрешено всё, кроме перечисленного» — потому что при таком подходе легко забыть заблокировать что-то новое.
Разница между deny и reject. Обе команды блокируют трафик, но по-разному реагируют:
deny— пакет просто отбрасывается (drop), без ответа отправителю. Отправитель не получает никакого сигнала — соединение просто «зависает» и в итоге истекает по таймауту. Это усложняет сканирование портов злоумышленником (он не может быстро понять, закрыт порт или машина вообще недоступна).reject— пакет отклоняется, но отправителю отправляется явный ответ («соединение отклонено»). Быстрее для легитимных пользователей (они сразу видят ошибку, а не ждут таймаута), но и быстрее выдаёт злоумышленнику информацию о том, что машина существует и порт закрыт осознанно.
Для входящих подключений на сервер обычно используют deny как политику по умолчанию.
Практика
Шаг 1. Проверьте, установлен ли UFW (в Ubuntu он обычно предустановлен):
```bash
sudo ufw version
```
Если не установлен: sudo apt install ufw.
Шаг 2. Проверьте текущий статус:
```bash
sudo ufw status verbose
```
Что вы увидите: Status: inactive — firewall создан, но ещё не включён (мы это уже видели в предыдущем уроке).
[Скриншот терминала]
Шаг 3. КРИТИЧЕСКИ ВАЖНЫЙ ШАГ. Прежде чем включать firewall, обязательно разрешите SSH! Если этого не сделать, включение firewall немедленно заблокирует ваше собственное SSH-соединение, и вы потеряете удалённый доступ к серверу (если работаете именно через SSH — если сейчас вы за локальным терминалом, риска нет, но привычку нужно выработать сразу):
```bash
sudo ufw allow ssh
```
Что произойдёт: UFW добавит правило, разрешающее входящие подключения на порт 22 (стандартный порт SSH — UFW знает соответствие имён служб портам через файл /etc/services, который мы упоминали в Блоке 12).
Альтернативный способ указать то же самое явно через номер порта:
```bash
sudo ufw allow 22/tcp
```
Шаг 4. Задайте политики по умолчанию — запретить весь входящий трафик, разрешить весь исходящий (это стандартная и рекомендуемая отправная точка):
```bash
sudo ufw default deny incoming
sudo ufw default allow outgoing
```
Что произойдёт: UFW запомнит эти политики как базовые. Все специфичные правила (как allow ssh на шаге 3) — это исключения из данной политики.
[Скриншот терминала]
Шаг 5. Теперь включите firewall:
```bash
sudo ufw enable
```
Что произойдёт: UFW предупредит, что это может нарушить существующие SSH-соединения, и запросит подтверждение. Введите y. После этого firewall активен и начинает фильтровать трафик согласно заданным правилам.
[Скриншот терминала]
Шаг 6. Проверьте статус ещё раз:
```bash
sudo ufw status verbose
```
Что вы увидите: Status: active, политики по умолчанию, и список правил — в том числе разрешение для порта 22/tcp.
[Скриншот терминала со статусом active]
Шаг 7. Добавьте правила для типичного веб-сервера (даже если у вас пока не установлен веб-сервер — мы установим Nginx в Блоке 19, и тогда эти правила понадобятся):
```bash
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
```
Что произойдёт: разрешены порты 80 (HTTP) и 443 (HTTPS) — стандартные веб-порты, которые мы разбирали в Блоке 12.
Шаг 8. Изучите нумерованный список правил (полезно для последующего удаления конкретных правил):
```bash
sudo ufw status numbered
```
Что вы увидите: каждое правило с номером в квадратных скобках, например [1] 22/tcp ALLOW IN Anywhere.
[Скриншот нумерованного списка]
Шаг 9. Потренируйтесь удалять правило — удалите правило для порта 443 (мы добавим его снова, когда реально понадобится, в Блоке 19):
```bash
sudo ufw delete allow 443/tcp
```
Или, используя номер из предыдущего шага:
```bash
sudo ufw status numbered
sudo ufw delete 3
```
(Номер может отличаться — используйте тот, что соответствует правилу для 443 в вашем выводе.)
Шаг 10. Ограничьте доступ к порту SSH конкретным IP-адресом (демонстрация возможности — если вы точно знаете, с какого адреса будете подключаться, это значительно повышает безопасность):
```bash
sudo ufw allow from 203.0.113.50 to any port 22
```
Это добавит дополнительное разрешающее правило для конкретного IP. Не выполняйте эту команду по-настоящему, если не уверены в IP-адресе, с которого будете подключаться — иначе рискуете заблокировать себе доступ (общее правило allow ssh из шага 3 всё ещё продолжит работать, если вы его не удаляли, так что в рамках практики это безопасно, но будьте внимательны в реальной эксплуатации).
Шаг 11. Посмотрите на команду ufw limit — специальную защиту от перебора для SSH:
```bash
sudo ufw limit ssh
```
Что произойдёт: UFW заменит простое правило allow на limit — теперь если один и тот же IP-адрес попытается подключиться более 6 раз за 30 секунд, дальнейшие попытки будут временно заблокированы. Это встроенная в UFW базовая защита от перебора (хотя специализированный Fail2Ban, который мы изучим в следующем уроке, работает намного тоньше и эффективнее).
[Скриншот терминала]
Разбор команд
Команда ufw
- Назначение:** управление firewall (надстройка над iptables).
- Синтаксис:**
ufw [опции] команда - Основные команды:**
ufw enable/ufw disable— включить/выключить firewall.ufw status [verbose|numbered]— показать текущий статус и правила.ufw default allow|deny incoming|outgoing— задать политику по умолчанию.ufw allow ПОРТ[/протокол]— разрешить порт (например,ufw allow 8080/tcp).ufw allow ИМЯ_СЛУЖБЫ— разрешить по имени службы из/etc/services(например,ufw allow ssh,ufw allow http).ufw deny ПОРТ— запретить порт (без ответа отправителю).ufw reject ПОРТ— отклонить порт (с явным ответом отправителю).ufw delete ПРАВИЛО— удалить правило (по описанию или номеру).ufw limit ПОРТ— разрешить порт, но с ограничением частоты подключений (защита от перебора).ufw allow from IP to any port ПОРТ— разрешить конкретный IP на конкретный порт.ufw allow from IP/маска— разрешить всю подсеть (используем нотацию CIDR из урока 12.2).ufw reset— сбросить все правила к начальному состоянию (осторожно!).- Реальные примеры использования:**
sudo ufw allow from 192.168.1.0/24 to any port 22— разрешить SSH только из локальной подсети.sudo ufw allow 5432/tcp— открыть порт PostgreSQL (мы изучим эту базу данных в Блоке 19), если к ней нужен доступ извне (обычно не рекомендуется — базы данных лучше держать доступными только локально).sudo ufw status numberedзатемsudo ufw delete 2— удалить второе по счёту правило.- Типичные ошибки:**
- Включить firewall с политикой
deny incomingдо того, как разрешить SSH — это заблокирует собственный удалённый доступ администратора. - Забыть протокол при работе с UDP-службами (по умолчанию
ufw allow ПОРТразрешает и TCP, и UDP; если нужен только один протокол — указывайте явно/tcpили/udp).
Возможные ошибки
- Ошибка:** после
sudo ufw enableSSH-соединение обрывается и больше не устанавливается.
Почему возникает: правило для SSH не было добавлено до включения firewall (пропущен шаг 3 практики), и политика по умолчанию заблокировала входящие подключения, включая ваше собственное SSH-соединение.
Как определить: классическая ситуация — вы теряете доступ к удалённому серверу сразу после включения firewall.
Как исправить: если у вас есть доступ к серверу через консоль провайдера (веб-консоль, которую обычно предоставляют облачные провайдеры, независимо от сетевого доступа — подробнее об этом в Блоке 20) — войдите через неё и выполните sudo ufw allow ssh и sudo ufw reload, либо sudo ufw disable для временного отключения. Если консольного доступа нет — ситуация серьёзная, потребуется обращение в поддержку провайдера.
Как избежать: всегда разрешать SSH до включения firewall с политикой deny incoming. Это железное правило, которое стоит запомнить навсегда — оно спасёт вас от одной из самых частых и обидных ошибок начинающих администраторов.
- Ошибка:** правило добавлено, но не применяется — сервис всё ещё недоступен.
Почему возникает: возможен конфликт правил (более специфичное правило deny может стоять раньше allow для того же порта), либо служба реально не запущена (firewall тут ни при чём).
Как определить: проверить порядок правил sudo ufw status numbered; проверить, что служба вообще слушает порт: sudo ss -tlnp.
Как исправить: удалить конфликтующее правило или добавить правильное в нужном порядке.
Практические задания
- Настройте UFW на своей системе по описанному в практике плану (allow SSH → default deny incoming → default allow outgoing → enable), затем проверьте статус. Обязательно сначала выполните шаги в правильном порядке!
- Добавьте правило, ограничивающее доступ по SSH только из локальной подсети вашей домашней/учебной сети (узнайте свою подсеть командой
ip addrиз Блока 12), и объясните в конспекте, почему это повышает безопасность по сравнению с открытым для всего интернета SSH. - Изучите разницу между
sudo ufw deny 8080иsudo ufw reject 8080на практике: откройте порт 8080 временно (python3 -m http.server 8080в отдельном терминале — простой встроенный веб-сервер Python для тестов), примените оба правила по очереди и попробуйте подключиться (curl http://localhost:8080`), сравнив время ответа и полученное сообщение.
Проверка знаний
Вопрос 1. Почему крайне важно разрешить SSH в UFW до установки политики default deny incoming и включения firewall, а не после?
Ответ: Потому что как только firewall включается с политикой запрета входящего трафика по умолчанию, все подключения, включая ваше текущее SSH-соединение, будут немедленно заблокированы, если для них явно не создано разрешающее правило. Если вы забудете разрешить SSH заранее, вы потеряете удалённый доступ к серверу сразу после включения firewall — и для восстановления доступа потребуется физический или консольный доступ к машине.
Вопрос 2. В чём разница между ufw deny и ufw reject, и почему для защиты от сканирования портов предпочтительнее deny?
Ответ: deny молча отбрасывает пакет без ответа отправителю — тот вынужден ждать таймаута, не понимая, заблокирован порт или машина недоступна вовсе. reject отправляет явный ответ об отклонении соединения. Для защиты от сканирования deny предпочтительнее, потому что усложняет злоумышленнику (или автоматическому сканеру) быстрое определение того, какие порты реально существуют и намеренно закрыты, а какие просто недоступны.
Итоги урока
Вы изучили: что такое firewall и netfilter/iptables, философию UFW, политики по умолчанию, разницу между deny и reject.
Вы умеете: включать и настраивать UFW, разрешать/запрещать порты по номеру или имени службы, ограничивать доступ по IP, использовать ufw limit для базовой защиты от перебора.
В следующем уроке потребуется: работающий firewall — теперь мы добавим ещё один, более «умный» слой защиты — Fail2Ban, который анализирует логи и динамически блокирует источники атак.
Урок 14.3. Защита от перебора: Fail2Ban
Установить и настроить Fail2Ban — систему, которая автоматически анализирует логи сервера и временно блокирует IP-адреса, демонстрирующие признаки атаки перебором (много неудачных попыток входа за короткое время).
Теория
Мы уже разрешили в UFW входящий трафик на SSH — а значит, сервер снова доступен для попыток подключения из любой точки интернета. Как мы обсуждали в уроке 14.1, боты постоянно сканируют интернет и пытаются подобрать пароли к SSH. ufw limit (который мы включили в предыдущем уроке) даёт очень базовую защиту, но Fail2Ban — специализированный и гораздо более гибкий инструмент именно для этой задачи.
Как работает Fail2Ban (принцип действия):
- Fail2Ban постоянно отслеживает (мониторит) системные логи — в первую очередь логи SSH (записи о неудачных попытках входа, которые генерирует
sshdи которые мы можем увидеть черезjournalctl, изученный в Блоке 10). - Он ищет в логах определённые паттерны (шаблоны текста), соответствующие неудачным попыткам аутентификации — например, строку вида
Failed password for invalid user admin from 203.0.113.99. - Если один и тот же IP-адрес генерирует такие записи слишком часто (по умолчанию — 5 неудачных попыток за 10 минут, но это настраивается), Fail2Ban считает этот адрес источником атаки.
- Fail2Ban автоматически добавляет правило firewall (используя тот же iptables, который лежит в основе UFW), блокирующее весь трафик с этого IP-адреса на определённое время (по умолчанию — 10 минут, но обычно настраивают на более долгий срок).
- По истечении времени блокировки IP автоматически разблокируется — если атака продолжится, он будет заблокирован снова.
Термины Fail2Ban:
- Jail** («тюрьма» или «камера») — это конфигурационный «модуль» Fail2Ban, отвечающий за защиту конкретной службы. Например, jail
sshdследит за логами SSH, jailnginx-http-auth(если установлен Nginx) следит за логами веб-сервера. Каждая jail имеет свои настройки: какой лог отслеживать, какой паттерн искать, сколько попыток допустимо, на какое время блокировать. - Filter** (фильтр) — правило (обычно на основе регулярных выражений, которые мы подробно изучим в уроке 15.8, но уже частично видели в Блоке 6) для распознавания «плохих» записей в логе.
- Ban** (бан) — собственно блокировка IP-адреса.
- Ban time** — на сколько времени блокируется IP при превышении лимита попыток.
- Find time** — временное окно, в течение которого считаются неудачные попытки (например, «5 попыток за 10 минут»).
- Max retry** — максимальное количество неудачных попыток, после которого происходит бан.
Файлы конфигурации Fail2Ban. Основная конфигурация находится в /etc/fail2ban/jail.conf — но важное правило: этот файл никогда не следует редактировать напрямую, потому что при обновлении пакета он может быть перезаписан, и все ваши изменения потеряются. Вместо этого создаётся файл /etc/fail2ban/jail.local, который имеет более высокий приоритет и не затрагивается обновлениями пакета — это стандартная практика конфигурации многих Linux-программ («основной файл — только для чтения примеров, локальные настройки — в отдельном файле»).
Практика
Шаг 1. Установите Fail2Ban:
```bash
sudo apt update
sudo apt install fail2ban
```
Шаг 2. Проверьте, что служба запущена:
```bash
sudo systemctl status fail2ban
```
Что вы увидите: Active: active (running) — Fail2Ban уже работает с настройками по умолчанию (которые уже включают защиту SSH в большинстве конфигураций Ubuntu).
[Скриншот терминала]
Шаг 3. Создайте локальный файл конфигурации, скопировав из основного (стандартная практика, о которой говорилось в теории):
```bash
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
```
Шаг 4. Откройте файл jail.local для редактирования:
```bash
sudo nano /etc/fail2ban/jail.local
```
Шаг 5. Найдите секцию [DEFAULT] (используйте поиск в nano: Ctrl+W, наберите [DEFAULT], Enter) и обратите внимание на параметры (пока не меняйте — сначала изучите):
```
bantime = 10m
findtime = 10m
maxretry = 5
```
Измените bantime на более серьёзное значение (например, час) — найдите строку bantime = 10m и измените на:
```
bantime = 1h
```
Шаг 6. Найдите секцию [sshd] (Ctrl+W, наберите [sshd]) — она обычно выглядит примерно так:
```
[sshd]
port = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)s
```
Добавьте (или раскомментируйте, если строка уже есть) строку, явно включающую эту jail:
```
[sshd]
enabled = true
port = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)s
maxretry = 3
bantime = 1h
```
Здесь мы явно переопределяем maxretry только для jail SSH — теперь после 3 неудачных попыток (более строго, чем общее правило в 5) IP будет заблокирован на час.
Сохраните файл: Ctrl+O, Enter, Ctrl+X.
[Скриншот отредактированного файла]
Шаг 7. Перезапустите Fail2Ban, чтобы применить изменения:
```bash
sudo systemctl restart fail2ban
```
Шаг 8. Проверьте статус конкретной jail (модуля защиты SSH):
```bash
sudo fail2ban-client status sshd
```
Что вы увидите: информацию о текущем состоянии jail — сколько неудачных попыток зафиксировано, сколько IP-адресов заблокировано в данный момент.
[Скриншот терминала]
Шаг 9. Проверьте общий статус всех активных jail:
```bash
sudo fail2ban-client status
```
Шаг 10. Симуляция атаки для проверки работы (безопасная демонстрация). Попробуйте несколько раз подключиться по SSH с заведомо неправильным паролем от localhost, чтобы увидеть Fail2Ban в действии:
```bash
ssh sshtest_fake_user@localhost
```
(Пользователя sshtest_fake_user не существует — SSH запросит пароль, введите что угодно неправильное, повторите 3-4 раза для срабатывания правила maxretry = 3, установленного на шаге 6.)
Шаг 11. Проверьте, заблокирован ли ваш собственный localhost-адрес (127.0.0.1) после нескольких неудачных попыток:
```bash
sudo fail2ban-client status sshd
```
Что вы увидите: в поле Banned IP list может появиться 127.0.0.1 — это подтверждает, что Fail2Ban зафиксировал ваши «атаки» и заблокировал источник.
[Скриншот с забаненным IP]
Внимание: если вы забанили localhost, это временно заблокирует и ваши собственные легитимные попытки подключения по SSH к самому себе. Для учебной среды это не страшно, но важно понимать: эту команду разблокировки нужно знать заранее, прежде чем баните себя на реальном сервере, к которому у вас нет другого доступа.
Шаг 12. Разблокируйте IP вручную (важная команда для администратора — иногда легитимный пользователь блокируется по ошибке, например, забыв пароль несколько раз подряд):
```bash
sudo fail2ban-client set sshd unbanip 127.0.0.1
```
Что произойдёт: указанный IP немедленно удаляется из списка заблокированных.
Шаг 13. Проверьте, что разблокировка сработала:
```bash
sudo fail2ban-client status sshd
```
Разбор команд
Команда fail2ban-client
- Назначение:** взаимодействие с работающей службой Fail2Ban — проверка статуса, управление банами.
- Синтаксис:**
fail2ban-client [опции] команда - Основные команды:**
status— общий статус, список активных jail.status ИМЯ_JAIL— подробный статус конкретной jail.set ИМЯ_JAIL unbanip IP— разблокировать конкретный IP в конкретной jail.set ИМЯ_JAIL banip IP— заблокировать IP вручную (полезно, если вы точно знаете источник атаки, но Fail2Ban ещё не среагировал).reload— перечитать конфигурацию без полного перезапуска службы.- Реальные примеры использования:**
sudo fail2ban-client status sshd— ежедневная проверка активности атак на SSH.sudo fail2ban-client set sshd unbanip 198.51.100.20— разблокировать сотрудника, который случайно ввёл неправильный пароль несколько раз.
Файл jail.local — ключевые параметры
bantime— длительность блокировки (можно указывать в секундах, минутахm, часахh, дняхd; специальное значение-1означает блокировку навсегда).findtime— временное окно для подсчёта неудачных попыток.maxretry— количество неудачных попыток до блокировки.enabled— включена ли конкретная jail (true/false).ignoreip— список IP-адресов, которые никогда не блокируются (полезно добавить сюда свой собственный постоянный IP-адрес, чтобы случайно не заблокировать себя).
Возможные ошибки
- Ошибка:** администратор случайно блокирует сам себя на реальном удалённом сервере и полностью теряет доступ.
Почему возникает: несколько неудачных попыток входа подряд (например, забытый пароль, опечатка, неправильный ключ) в пределах findtime достигают порога maxretry.
Как определить: SSH-соединение внезапно перестаёт устанавливаться, хотя раньше работало.
Как исправить: если есть доступ через консоль провайдера (см. Блок 20) — войти через неё и выполнить sudo fail2ban-client set sshd unbanip ВАШ_IP. Если консольного доступа нет — придётся ждать истечения bantime, либо обращаться в техподдержку провайдера.
Как избежать: добавить свой постоянный (статический) IP-адрес в параметр ignoreip в jail.local, чтобы Fail2Ban никогда не блокировал доверенный источник; использовать SSH-ключи вместо паролей (тогда неверных попыток аутентификации почти не возникает случайно).
- Ошибка:** Fail2Ban установлен, но jail для SSH не активна.
Почему возникает: в некоторых конфигурациях по умолчанию enabled = false для отдельных jail, и требуется явное включение.
Как определить: sudo fail2ban-client status не показывает sshd в списке активных jail.
Как исправить: убедиться, что в jail.local для секции [sshd] стоит enabled = true, и перезапустить службу.
Практические задания
- Настройте параметр
ignoreipв файлеjail.local, добавив туда127.0.0.1/8(loopback-диапазон — вспомните урок 12.2 про CIDR-нотацию), чтобы никогда не блокировать себя при тестах на localhost. Перезапустите Fail2Ban и убедитесь, что этот адрес больше не блокируется, даже при повторении неудачных попыток из шага 10 практики. - Изучите файл логов, который читает Fail2Ban для jail
sshd(посмотрите значениеlogpathв конфигурации, вспомните, как мы смотрели логи черезjournalctlв Блоке 10) — найдите там реальные записи о неудачных попытках входа. - Придумайте (и опишите в конспекте, не обязательно настраивать по-настоящему) параметры jail для гипотетической защиты веб-приложения, требующего входа по паролю: сколько попыток вы бы разрешили, на какое время блокировали, и почему именно такие значения кажутся вам разумным компромиссом между безопасностью и удобством легитимных пользователей.
Проверка знаний
Вопрос 1. Почему конфигурацию Fail2Ban рекомендуется вносить в файл jail.local, а не редактировать jail.conf напрямую?
Ответ: Файл jail.conf — это файл, поставляемый вместе с пакетом Fail2Ban, и он может быть перезаписан при обновлении пакета, из-за чего все внесённые в него изменения будут потеряны. Файл jail.local имеет более высокий приоритет, не затрагивается обновлениями пакета и предназначен именно для локальных пользовательских настроек — это стандартная практика для многих конфигурируемых программ в Linux.
Вопрос 2. Какие два параметра работают вместе, чтобы определить, когда IP-адрес считается источником атаки, и как они взаимодействуют?
Ответ: maxretry (максимальное количество неудачных попыток) и findtime (временное окно для подсчёта этих попыток). Fail2Ban блокирует IP-адрес, если он совершил maxretry неудачных попыток аутентификации в пределах периода findtime. Например, при maxretry = 3 и findtime = 10m — три неудачные попытки за 10 минут приводят к блокировке; та же попытка на четвёртой минуте после успешного 10-минутного окна уже не будет считаться подряд идущей.
Итоги урока
Вы изучили: принцип действия Fail2Ban, термины jail/filter/ban/findtime/maxretry, структуру файлов конфигурации (jail.conf vs jail.local).
Вы умеете: устанавливать и настраивать Fail2Ban, изменять параметры конкретной jail, проверять статус блокировок, вручную банить и разбанивать IP-адреса.
В следующем уроке потребуется: понимание, что firewall и Fail2Ban — это внешние слои защиты; теперь мы «закалим» саму настройку SSH-сервера, чтобы устранить возможность подбора пароля как таковую.
Урок 14.4. Безопасный OpenSSH: хардненинг сервера
Настроить SSH-сервер по лучшим практикам безопасности: отключить вход root напрямую, отключить аутентификацию по паролю (оставив только ключи), изменить порт по умолчанию, ограничить круг пользователей, которым разрешён вход.
Теория
Мы уже умеем создавать SSH-ключи (урок 13.3) и знаем, как работает аутентификация по ключу. Теперь настроим сам SSH-сервер так, чтобы использование ключей стало не просто возможностью, а единственным способом входа — устранив саму возможность подбора пароля.
Файл конфигурации SSH-сервера — /etc/ssh/sshd_config. Важно не путать его с ~/.ssh/config из урока 13.4 — это два совершенно разных файла:
~/.ssh/config— настройки клиента (как именно вы подключаетесь к серверам), находится в домашней папке пользователя./etc/ssh/sshd_config— настройки сервера (как сервер принимает подключения), находится в системной директории и требует прав root для редактирования.
Ключевые параметры для хардненинга SSH-сервера:
1. PermitRootLogin — запрет прямого входа root.
По умолчанию (или в некоторых системах) может быть разрешён прямой вход под пользователем root по SSH. Это серьёзный риск: root — самая ценная цель для атаки (полные права над системой), и её имя всегда одно и то же — «root» — поэтому атакующим не нужно даже угадывать имя пользователя, только пароль. Рекомендуемая настройка:
```
PermitRootLogin no
```
Это заставляет администраторов входить под обычным пользователем и использовать sudo для получения повышенных прав — именно та модель, которую мы используем с самого начала курса (Блок 8) и которая соответствует принципу наименьших привилегий.
2. PasswordAuthentication — отключение входа по паролю.
Это, возможно, самая важная настройка хардненинга SSH. Если у вас настроена аутентификация по ключам (Блок 13, урок 13.3), можно и нужно полностью отключить возможность входа по паролю:
```
PasswordAuthentication no
```
После этого единственный способ войти на сервер — иметь приватный ключ, соответствующий одному из публичных ключей в authorized_keys. Перебор пароля становится в принципе невозможным — не «затруднённым», а именно невозможным, потому что сама возможность аутентификации по паролю отсутствует на уровне протокола.
⚠️ Критически важное предупреждение. Прежде чем отключать PasswordAuthentication, обязательно убедитесь, что вы можете войти на сервер по ключу! Если вы отключите аутентификацию по паролю, не настроив предварительно рабочий вход по ключу, вы немедленно и полностью потеряете доступ к серверу после перезапуска SSH-службы. Это одна из самых частых и болезненных ошибок начинающих администраторов. Правильный порядок действий:
- Настроить SSH-ключи (урок 13.3).
- Проверить, что вход по ключу реально работает (открыть новую SSH-сессию, не закрывая текущую!).
- Только после успешной проверки — отключать
PasswordAuthentication. - Не закрывать текущую («старую») SSH-сессию, пока не убедитесь, что новая сессия с новыми настройками работает корректно.
3. Port — изменение порта по умолчанию.
Порт 22 — это то место, куда автоматические сканеры и боты обращаются в первую очередь (это стандартный, всем известный порт SSH). Смена порта на нестандартный (например, 2222 или любое другое число от 1024 до 65535) не является настоящей защитой в криптографическом смысле — это называется «security through obscurity» («безопасность через неясность/сокрытие») и само по себе ненадёжно. Но на практике это резко снижает количество автоматических попыток подключения в логах (большинство ботов не сканируют все 65535 портов, а проверяют только стандартный 22), что уменьшает нагрузку на сервер и на Fail2Ban, и облегчает анализ логов (там остаются в основном только целенаправленные, а не массовые автоматические попытки).
```
Port 2222
```
Важно: при изменении порта не забудьте открыть новый порт в UFW (sudo ufw allow 2222/tcp) до того, как перезапустите SSH — иначе firewall заблокирует подключения на новый порт.
4. AllowUsers — ограничение круга пользователей.
Можно явно указать список пользователей, которым разрешён вход по SSH — все остальные учётные записи, даже если у них есть пароль, не смогут войти через SSH:
```
AllowUsers admin deploy
```
5. MaxAuthTries — ограничение числа попыток аутентификации в рамках одного соединения.
```
MaxAuthTries 3
```
Ограничивает, сколько раз в рамках одного SSH-соединения можно попробовать ввести неправильные учётные данные, прежде чем соединение будет разорвано.
6. X11Forwarding — если не используется, лучше отключить.
```
X11Forwarding no
```
Уменьшает поверхность атаки, если проброс графических приложений через SSH не нужен.
Проверка синтаксиса конфигурации перед перезапуском. SSH предоставляет команду для проверки корректности синтаксиса файла конфигурации до его применения — это критически важная привычка, чтобы не сломать доступ из-за опечатки:
```bash
sudo sshd -t
```
Если команда не выводит ничего — синтаксис корректен. Если есть ошибка — она будет показана, и текущая (рабочая) конфигурация не будет нарушена, пока вы не исправите ошибку и не перезапустите службу.
Практика
Шаг 1. Убедитесь, что у вас уже настроен и проверен вход по SSH-ключу (из урока 13.3). Если нет — вернитесь и настройте перед продолжением этого урока. Это абсолютное условие для безопасного выполнения следующих шагов.
Шаг 2. Сделайте резервную копию текущего файла конфигурации перед любыми изменениями (важнейшая привычка администратора):
```bash
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.backup
```
Шаг 3. Откройте файл конфигурации SSH-сервера:
```bash
sudo nano /etc/ssh/sshd_config
```
Шаг 4. Найдите и измените (или добавьте, если строки нет, либо она закомментирована символом # — уберите # и измените значение) следующие параметры:
```
PermitRootLogin no
PasswordAuthentication no
MaxAuthTries 3
X11Forwarding no
```
Сохраните файл: Ctrl+O, Enter, Ctrl+X.
[Скриншот отредактированного файла]
Шаг 5. ОБЯЗАТЕЛЬНЫЙ ШАГ. Проверьте синтаксис файла перед применением:
```bash
sudo sshd -t
```
Если появилась ошибка — вернитесь на шаг 3 и исправьте её. Если вывод пуст — синтаксис корректен, можно продолжать.
Шаг 6. Прежде чем перезапускать SSH, откройте новое, отдельное окно терминала (не закрывая текущее!) и убедитесь, что вход по ключу работает:
```bash
ssh -i ~/.ssh/id_ed25519 ваш_пользователь@localhost
```
Успешный вход без пароля подтверждает, что ключевая аутентификация настроена правильно, и можно безопасно отключать пароль. Выйдите из этой тестовой сессии (exit), но не закрывайте основной терминал, из которого вы редактировали конфигурацию.
Шаг 7. Только теперь перезапустите SSH-службу, чтобы применить новые настройки:
```bash
sudo systemctl restart ssh
```
Шаг 8. Критически важная проверка. Немедленно, не закрывая текущий терминал, откройте ещё одно новое окно терминала и попробуйте подключиться заново:
```bash
ssh ваш_пользователь@localhost
```
Что должно произойти: вход без запроса пароля (по ключу). Если что-то пошло не так и подключение не удаётся — у вас всё ещё есть доступ через изначальный, не закрытый терминал, откуда можно откатить изменения:
```bash
sudo cp /etc/ssh/sshd_config.backup /etc/ssh/sshd_config
sudo systemctl restart ssh
```
Именно поэтому мы никогда не закрываем изначальную сессию до полной проверки — это стандартная и обязательная практика при изменении настроек SSH на любом реальном сервере.
[Скриншот успешного подключения после хардненинга]
Шаг 9. Убедитесь, что вход по паролю действительно отключён — попробуйте явно запросить аутентификацию по паролю (используя параметр, отключающий использование ключей для этой конкретной попытки):
```bash
ssh -o PubkeyAuthentication=no ваш_пользователь@localhost
```
Что вы увидите: SSH сразу откажет в соединении (Permission denied (publickey)) — не будет даже спрашивать пароль, потому что аутентификация по паролю отключена на сервере.
[Скриншот отказа в парольной аутентификации]
Шаг 10. (Опционально, для практики — можно пропустить на постоянной основе, если ваша учебная среда единственная и смена порта усложнит дальнейшую практику). Продемонстрируем смену порта: добавьте в конфигурацию альтернативный порт временно:
```bash
sudo ufw allow 2222/tcp
sudo nano /etc/ssh/sshd_config
```
Измените или добавьте:
```
Port 22
Port 2222
```
(Временно оставляем оба порта активными для безопасной демонстрации, чтобы не потерять доступ.)
```bash
sudo sshd -t
sudo systemctl restart ssh
```
Проверьте подключение на новый порт:
```bash
ssh -p 2222 ваш_пользователь@localhost
```
После проверки верните конфигурацию к единственному порту 22 (или, если хотите продолжать использовать 2222 как основной — уберите строку Port 22 и не забудьте sudo ufw delete allow 22/tcp только после полной уверенности, что переход на новый порт завершён успешно).
Разбор команд
Команда sshd -t
- Назначение:** проверить синтаксис файла конфигурации SSH-сервера без применения изменений и без перезапуска службы.
- Синтаксис:**
sudo sshd -t [-f путь_к_конфигу] - Почему это важно:** ошибка синтаксиса в
sshd_config, если её не проверить заранее, может привести к тому, что служба SSH не сможет перезапуститься вообще — а значит, при следующем перезапуске сервера (или ручном перезапуске службы) вы полностью потеряете удалённый доступ.
Ключевые параметры /etc/ssh/sshd_config — сводная таблица:
| Параметр | Рекомендуемое значение | Назначение |
|---|---|---|
| PermitRootLogin | no | Запретить прямой вход root |
| PasswordAuthentication | no | Разрешить вход только по ключу |
| Port | нестандартный (напр. 2222) | Снизить количество автоматических атак |
| MaxAuthTries | 3 | Ограничить попытки в рамках сессии |
| X11Forwarding | no (если не нужен) | Уменьшить поверхность атаки |
| AllowUsers | список конкретных пользователей | Явное ограничение круга допущенных |
| PermitEmptyPasswords | no (обычно по умолчанию) | Запретить пустые пароли |
| Protocol | 2 (в современных версиях всегда 2) | Использовать только безопасную версию SSH-протокола |
Возможные ошибки
- Ошибка:** полная потеря доступа к серверу после отключения
PasswordAuthentication.
Почему возникает: ключевая аутентификация не была настроена или проверена до отключения парольной, либо публичный ключ не был правильно добавлен в authorized_keys на сервере.
Как определить: после перезапуска SSH все попытки подключения выдают Permission denied (publickey), и никакая комбинация пароля не помогает, потому что аутентификация по паролю отключена на уровне протокола.
Как исправить: если сохранена изначальная открытая сессия (как мы делали в практике) — откатить sshd_config из резервной копии. Если сессия уже закрыта и других способов входа нет — потребуется консольный доступ к серверу через провайдера (Блок 20) для ручного исправления файла конфигурации.
Как избежать: строго следовать порядку действий из практики: проверить ключ → не закрывать текущую сессию → перезапустить → проверить в новом окне → только потом закрыть старую сессию.
- Ошибка:** после смены порта SSH-сервер становится недоступен.
Почему возникает: новый порт не был открыт в UFW перед перезапуском SSH, либо провайдер VPS (в реальных облачных средах) имеет собственный внешний firewall (security group), который тоже нужно настроить отдельно от UFW на самом сервере — об этом подробнее в Блоке 20.
Как исправить: открыть новый порт в UFW: sudo ufw allow НОВЫЙ_ПОРТ/tcp; для облачных провайдеров — также проверить настройки security group/firewall в панели управления провайдера.
Как избежать: всегда открывать новый порт в firewall до изменения Port в sshd_config и перезапуска службы.
Практические задания
- Выполните полный хардненинг SSH-сервера на своей системе по описанной в практике последовательности (обязательно с сохранением резервной копии и проверкой в отдельном окне терминала перед закрытием исходной сессии).
- Настройте
AllowUsers, указав только своего пользователя, и убедитесь, что попытка входа под другим (тестовым) пользователем через SSH отклоняется, даже если у него настроен правильный ключ или пароль. - Изучите (
cat /etc/ssh/sshd_config | grep -v "^#" | grep -v "^$"— команда выведет только не закомментированные и не пустые строки, используя знакомую нам из Блока 6 логикуgrep) итоговую активную конфигурацию вашего SSH-сервера после всех изменений и составьте в конспекте таблицу: параметр → значение → что он делает.
Проверка знаний
Вопрос 1. Почему крайне важно не закрывать текущую SSH-сессию при изменении настроек SSH-сервера, пока не проверено новое подключение в отдельном окне?
Ответ: Потому что если новая конфигурация содержит ошибку (опечатка, неправильно настроенный ключ, забытый открытый порт в firewall и т.д.), а текущая сессия уже закрыта — вы можете полностью и безвозвратно потерять удалённый доступ к серверу. Сохранённая открытая сессия служит «страховкой»: если что-то пошло не так, через неё можно откатить изменения (восстановить резервную копию конфигурации и перезапустить службу), не прибегая к консольному доступу провайдера.
Вопрос 2. Является ли смена порта SSH с 22 на нестандартный настоящей мерой безопасности в криптографическом смысле, и зачем её тогда применяют?
Ответ: Нет, это не криптографическая защита — принцип называется «security through obscurity» и сам по себе ненадёжен, поскольку злоумышленник, целенаправленно атакующий конкретный сервер, легко может просканировать все порты и найти SSH на любом из них. Тем не менее, смена порта резко снижает количество автоматических, массовых попыток подключения от ботов, которые обычно проверяют только стандартный порт 22 — это снижает нагрузку на сервер, объём «шума» в логах и нагрузку на Fail2Ban, облегчая выявление реально целенаправленных попыток атаки.
Итоги урока
Вы изучили: файл /etc/ssh/sshd_config и его отличие от клиентского ~/.ssh/config, ключевые параметры хардненинга (PermitRootLogin, PasswordAuthentication, Port, MaxAuthTries, AllowUsers, X11Forwarding), концепцию «security through obscurity».
Вы умеете: безопасно изменять конфигурацию SSH-сервера с проверкой синтаксиса и резервным копированием, отключать вход по паролю, менять порт SSH, ограничивать круг допущенных пользователей.
В следующем уроке потребуется: понимание важности регулярных обновлений системы (упомянутое в уроке 14.1) — теперь мы автоматизируем этот процесс для обновлений безопасности.
Урок 14.5. Автоматические обновления безопасности: `unattended-upgrades`
Настроить автоматическую установку обновлений безопасности, чтобы система оставалась защищённой от известных уязвимостей даже без ручного вмешательства администратора.
Теория
Мы уже знаем (Блок 9), как вручную обновлять систему командами apt update и apt upgrade. Но в реальной практике администрирования множества серверов ручное обновление каждого сервера при появлении новой уязвимости — не масштабируется. Уязвимости обнаруживаются постоянно, и разрыв между публикацией патча (исправления) и его установкой на ваш сервер — это окно, в течение которого система уязвима.
unattended-upgrades — официальный пакет Ubuntu, который автоматически устанавливает обновления (по умолчанию — только обновления безопасности, что является разумным компромиссом) без участия администратора, по расписанию.
Почему по умолчанию только обновления безопасности, а не вообще все обновления? Это важное архитектурное решение. Обычные обновления пакетов (новые версии программ с новыми функциями) иногда могут менять поведение системы, требовать ручной настройки, или даже содержать регрессии (новые ошибки взамен старых). Автоматическая установка любых обновлений без контроля администратора рискует непредсказуемо сломать работающую систему. Обновления безопасности, напротив, обычно точечные — они исправляют конкретную уязвимость, не меняя остального поведения системы, поэтому их автоматическая установка считается безопасной практикой.
Как работает unattended-upgrades:
- Пакет устанавливает systemd-таймер (мы говорили о таймерах вскользь в Блоке 10 — это механизм, похожий на cron, но встроенный в systemd), который запускает проверку обновлений на регулярной основе (обычно ежедневно).
- Проверяются доступные обновления, но устанавливаются только те, что помечены как относящиеся к каналу безопасности (
-securityв имени репозитория Ubuntu). - Если для применения обновления требуется перезагрузка системы (например, обновилось ядро) — по умолчанию
unattended-upgradesне перезагружает сервер автоматически, но можно настроить автоматическую перезагрузку в удобное время (например, ночью), что многие администраторы и делают для критически важных обновлений ядра. - Все действия логируются — можно проверить, что и когда было обновлено.
Компромисс между безопасностью и стабильностью. Автоматизация обновлений безопасности — это применение принципа «регулярные обновления» из урока 14.1 в масштабируемом виде. Важно понимать: это не заменяет периодическую ручную проверку системы администратором, а дополняет её — снижает окно уязвимости между выходом патча и его установкой, но не отменяет необходимость следить за системой в целом.
Практика
Шаг 1. Установите пакет:
```bash
sudo apt update
sudo apt install unattended-upgrades apt-listchanges
```
Шаг 2. Включите автоматическую настройку через интерактивный диалог:
```bash
sudo dpkg-reconfigure --priority=low unattended-upgrades
```
Что произойдёт: появится диалоговое окно (в текстовом интерфейсе) с вопросом, включить ли автоматические обновления. Выберите «Yes».
[Скриншот диалога dpkg-reconfigure]
Шаг 3. Изучите основной файл конфигурации, который определяет, что именно обновляется автоматически:
```bash
sudo nano /etc/apt/apt.conf.d/50unattended-upgrades
```
Найдите секцию Unattended-Upgrade::Allowed-Origins (в начале файла) — она обычно выглядит так:
```
Unattended-Upgrade::Allowed-Origins {
"${distro_id}:${distro_codename}-security";
"${distro_id}ESMApps:${distro_codename}-apps-security";
"${distro_id}ESM:${distro_codename}-infra-security";
// "${distro_id}:${distro_codename}-updates";
// "${distro_id}:${distro_codename}-proposed";
// "${distro_id}:${distro_codename}-backports";
};
```
Обратите внимание: строки с -security активны (не закомментированы), а строка -updates (обычные, не связанные с безопасностью, обновления) закомментирована символом // — это подтверждает описанный в теории принцип «по умолчанию только обновления безопасности».
Шаг 4. Найдите и изучите параметр автоматической перезагрузки (обычно ниже в том же файле, найдите через Ctrl+W → Automatic-Reboot):
```
//Unattended-Upgrade::Automatic-Reboot "false";
```
Если хотите включить автоматическую перезагрузку при необходимости (например, для обновлений ядра) — раскомментируйте и измените на "true", и задайте удобное время:
```
Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time "03:00";
```
Это означает: если после установки обновлений требуется перезагрузка — она произойдёт автоматически в 3 часа ночи (время наименьшей нагрузки на сервер, если он используется преимущественно днём).
Сохраните файл: Ctrl+O, Enter, Ctrl+X.
[Скриншот файла конфигурации]
Шаг 5. Проверьте второй важный файл — он определяет, как часто запускаются проверки:
```bash
cat /etc/apt/apt.conf.d/20auto-upgrades
```
Что вы увидите примерно следующее:
```
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";
```
Значение "1" означает «выполнять каждый день» (значение — это количество дней между запусками; "0" означало бы «отключено»).
Шаг 6. Проверьте статус и логи работы unattended-upgrades:
```bash
systemctl status unattended-upgrades
```
Что вы увидите: Active: active (running) — служба работает в фоне и будет действовать по расписанию, определяемому системным таймером.
Шаг 7. Запустите обновление вручную в тестовом режиме, чтобы увидеть, что произойдёт, без реального внесения изменений (--dry-run — тот же принцип, что мы видели у rsync в уроке 13.7):
```bash
sudo unattended-upgrade --dry-run --debug
```
Что вы увидите: подробный вывод о том, какие пакеты были бы обновлены, если бы это было реальным запуском. Это позволяет проверить работу механизма, не дожидаясь автоматического запуска по расписанию.
[Скриншот dry-run вывода]
Шаг 8. Изучите журнал уже прошедших автоматических обновлений (если система уже успела выполнить хотя бы один цикл):
```bash
cat /var/log/unattended-upgrades/unattended-upgrades.log
```
Разбор команд
Команда unattended-upgrade
- Назначение:** запустить процесс проверки и установки автоматических обновлений (обычно вызывается автоматически по расписанию, но можно запустить вручную).
- Синтаксис:**
sudo unattended-upgrade [опции] - Основные параметры:**
--dry-run— тестовый запуск без реальной установки.--debug— подробный вывод для диагностики.-v— verbose-режим.
Команда dpkg-reconfigure
- Назначение:** повторно запустить интерактивную настройку уже установленного пакета (многие пакеты в Debian/Ubuntu поддерживают такую настройку через специальную систему
debconf). - Синтаксис:**
sudo dpkg-reconfigure [--priority=уровень] имя_пакета - Параметр
--priority=low** — показать все вопросы настройки, включая менее важные (по умолчанию некоторые второстепенные вопросы могут быть скрыты).
Ключевые файлы конфигурации:
/etc/apt/apt.conf.d/50unattended-upgrades— что именно обновляется (какие репозитории), настройки перезагрузки, уведомлений по почте и т.д./etc/apt/apt.conf.d/20auto-upgrades— включён ли механизм в принципе, и с какой периодичностью./var/log/unattended-upgrades/— логи выполненных обновлений.
Возможные ошибки
- Ошибка:** автоматическая перезагрузка происходит в неудобное время, прерывая работу сервера.
Почему возникает: параметр Automatic-Reboot-Time установлен на время, совпадающее с реальной пиковой нагрузкой на сервер (например, для сервера с пользователями в другом часовом поясе).
Как определить: сервер оказывается недоступен на несколько минут в неожиданное время (стоит проверить логи и системное время перезагрузок: last reboot).
Как исправить: изменить Automatic-Reboot-Time на действительно наименее загруженное время для конкретного случая использования сервера, либо вообще отключить автоматическую перезагрузку и делать её вручную после уведомления.
Как избежать: заранее продумать часовой пояс и паттерн использования сервера при настройке времени автоматической перезагрузки.
- Ошибка:**
unattended-upgradesне устанавливает обновления, хотя они точно есть.
Почему возникает: обновление относится к обычному каналу (-updates), а не к каналу безопасности (-security), и, соответственно, не входит в Allowed-Origins по умолчанию.
Как определить: sudo apt list --upgradable показывает доступные обновления, но unattended-upgrade --dry-run их не упоминает.
Как исправить: это ожидаемое поведение по умолчанию — обычные обновления по-прежнему нужно устанавливать вручную (sudo apt update && sudo apt upgrade) или явно раскомментировать соответствующую строку в Allowed-Origins, осознанно принимая описанный в теории риск.
Практические задания
- Настройте
unattended-upgradesна своей системе по шагам практики и выполните тестовый запуск--dry-run --debug, изучив вывод. - Найдите в файле
/etc/apt/apt.conf.d/50unattended-upgradesпараметр, отвечающий за автоматическое удаление больше не нужных пакетов зависимостей после обновлений (подсказка: ищите словоAutoRemove), и объясните в конспекте, зачем такая функция может быть полезна (вспомните командуapt autoremoveиз Блока 9). - Изучите, можно ли настроить
unattended-upgradesдля отправки уведомлений по электронной почте о выполненных обновлениях (параметрUnattended-Upgrade::Mailв том же файле) — опишите в конспекте, зачем администратору может понадобиться такая функция, даже если обновления устанавливаются автоматически.
Проверка знаний
Вопрос 1. Почему unattended-upgrades по умолчанию устанавливает только обновления безопасности, а не любые доступные обновления пакетов?
Ответ: Обновления безопасности обычно точечно исправляют конкретную уязвимость, не меняя остального поведения программы, поэтому их автоматическая установка считается относительно безопасной. Обычные обновления могут содержать новые функции, изменения поведения или даже новые ошибки (регрессии) — автоматическая установка таких изменений без контроля администратора рискует непредсказуемо сломать работающую систему, поэтому такие обновления по умолчанию оставляются на усмотрение администратора и ручную установку.
Вопрос 2. Зачем нужен параметр Automatic-Reboot-Time, и почему важно тщательно выбирать его значение?
Ответ: Некоторые обновления (например, обновление ядра Linux) требуют перезагрузки системы для полного применения. Automatic-Reboot-Time задаёт конкретное время, когда такая перезагрузка выполнится автоматически, если она необходима. Важно выбирать время наименьшей нагрузки на сервер (например, глубокую ночь по часовому поясу основной аудитории сервера), чтобы кратковременная недоступность сервиса во время перезагрузки причинила минимум неудобств пользователям.
Итоги урока
Вы изучили: принцип работы unattended-upgrades, разницу между каналом безопасности и обычными обновлениями, файлы конфигурации 50unattended-upgrades и 20auto-upgrades, параметры автоматической перезагрузки.
Вы умеете: устанавливать и настраивать автоматические обновления безопасности, проверять их работу через --dry-run, изучать логи выполненных обновлений.
В следующем уроке потребуется: понимание всех предыдущих мер защиты этого блока (firewall, Fail2Ban, SSH-хардненинг, автообновления) — теперь мы соберём их в единую картину регулярного аудита безопасности.
Урок 14.6. Аудит безопасности и типичные ошибки администраторов
Освоить базовые практики регулярного аудита безопасности системы, научиться искать признаки компрометации, и изучить (чтобы избегать) самые распространённые ошибки, которые допускают начинающие администраторы Linux.
Теория
Настроить защиту один раз — это только начало. Безопасность — это непрерывный процесс, а не разовое действие. В этом уроке мы соберём воедино инструменты аудита и рассмотрим типичные ошибки, чтобы вы могли не только защищать систему, но и регулярно проверять, что защита продолжает работать эффективно.
Что включает регулярный аудит безопасности сервера:
- Проверка неудачных попыток входа. Регулярный просмотр логов SSH и статуса Fail2Ban показывает интенсивность атак на ваш сервер и подтверждает, что защита срабатывает.
- Проверка списка пользователей и их прав. Со временем на сервере могут накапливаться неиспользуемые учётные записи (например, оставшиеся от временных сотрудников или тестовых развёртываний) — их нужно периодически проверять и удалять.
- Проверка открытых портов. Убедиться, что список слушающих портов (
ss -tulnp, изучено в Блоке 12) соответствует ожидаемому — никакая незнакомая служба не должна внезапно появиться в списке.
- Проверка целостности важных файлов. В более продвинутых сценариях используются специальные инструменты (например, AIDE — Advanced Intrusion Detection Environment), которые отслеживают изменения в системных файлах и предупреждают, если что-то было изменено без ведома администратора — это может быть признаком компрометации.
- Проверка запущенных процессов. Периодический просмотр
ps auxилиtop/htop(Блок 11) на предмет незнакомых, подозрительных процессов — особенно с высоким потреблением ресурсов (например, признак незаконного крипто-майнинга, о котором мы упоминали в уроке 14.1) или запущенных из необычных мест (например, из/tmp).
- Проверка статуса и логов Fail2Ban и обновлений. Убедиться, что автоматизированные системы защиты действительно работают, а не «тихо сломались» когда-то в прошлом.
Полезные команды для быстрого аудита:
```bash
who
w
last
lastb
```
Команда last читает специальный лог-файл /var/log/wtmp и показывает историю всех входов в систему — кто, когда, с какого IP-адреса, как долго была активна сессия. Команда lastb делает то же самое, но для неудачных попыток входа (читает /var/log/btmp) — это прямой источник информации о попытках подбора пароля, если аутентификация по паролю ещё разрешена (хотя, как мы помним из урока 14.4, лучшая практика — отключить её полностью).
Типичные ошибки начинающих администраторов (обобщение всего блока, и не только):
- Работа от root постоянно, а не через
sudo. Мы говорили об этом ещё в Блоке 8 — постоянная работа от суперпользователя увеличивает потенциальный ущерб от любой ошибки (случайной или вызванной вредоносным ПО).
- Включение firewall без предварительного разрешения SSH. Разобрано в уроке 14.2 — классическая ошибка, приводящая к потере доступа.
- Отключение
PasswordAuthenticationбез предварительной проверки работающего входа по ключу. Разобрано в уроке 14.4.
- Игнорирование обновлений безопасности («работает — не трогай») — оставляет систему уязвимой для давно исправленных, публично известных уязвимостей.
- Использование одного и того же пароля/ключа на множестве разных серверов — компрометация одного сервера автоматически ставит под угрозу все остальные.
- Хранение приватных ключей без passphrase на рабочих машинах, особенно ноутбуках, которые можно потерять физически или которые могут быть украдены.
- Излишне широкие права доступа к файлам («на всякий случай» выставить
777вместо разбора реально нужных прав — вспомните урок 8.6) — классическая ошибка новичков, у которых что-то «не работает» из-за прав, и вместо диагностики они просто открывают доступ всем.
- Отсутствие резервных копий конфигурации перед изменениями — мы подчёркивали важность
cp файл файл.backupперед редактированием критичных файлов конфигурации (урок 14.4) неспроста.
- Игнорирование логов — установить защитные механизмы и никогда не проверять, работают ли они на практике и что показывают их логи.
- Открытие портов «на всякий случай» без понимания, зачем они на самом деле нужны — нарушение принципа минимизации поверхности атаки (урок 14.1).
Что делать при подозрении на компрометацию системы (общий план, детально это не тема начального курса, но важно знать первые шаги):
- Не паниковать, но действовать быстро и методично.
- Изолировать систему от сети, если это возможно и не критично для бизнеса (иногда лучше сначала собрать улики).
- Сохранить логи и состояние системы для последующего анализа (не перезаписывать, не перезагружать без необходимости — некоторые улики хранятся только в оперативной памяти).
- Сменить все пароли и ключи, к которым мог получить доступ злоумышленник.
- Изучить логи (
last,lastb,journalctl, логи Fail2Ban) на предмет необычной активности. - В серьёзных случаях — обратиться к специалистам по реагированию на инциденты (incident response) — это отдельная профессиональная область.
- После устранения угрозы — провести анализ причин (как злоумышленник получил доступ) и закрыть эту уязвимость, чтобы предотвратить повторение.
Практика
Шаг 1. Проверьте, кто сейчас подключён к системе:
```bash
who
w
```
Что вы увидите: who — список текущих сессий (пользователь, терминал, время входа); w — то же самое, но с дополнительной информацией о текущей нагрузке системы и выполняемых командах.
[Скриншот терминала]
Шаг 2. Изучите историю входов в систему:
```bash
last -10
```
Что вы увидите: последние 10 записей о входах — пользователь, откуда (IP или tty для локальной консоли), когда, как долго длилась сессия.
[Скриншот терминала]
Шаг 3. Проверьте неудачные попытки входа (если аутентификация по паролю ещё была разрешена в какой-то момент, или если вы всё ещё практиковались с ней в предыдущих уроках):
```bash
sudo lastb -10
```
Шаг 4. Проведите быструю проверку открытых портов и сопоставьте с ожиданиями:
```bash
sudo ss -tulnp
```
Составьте в уме (или в конспекте) список: «порт 22 — SSH, это ожидаемо; порт ... — а это что?».
Шаг 5. Проверьте статус всех защитных механизмов, настроенных в этом блоке, одной последовательностью команд:
```bash
echo "=== UFW ==="
sudo ufw status verbose
echo "=== Fail2Ban ==="
sudo fail2ban-client status
echo "=== SSH конфигурация ==="
sudo grep -E "^PermitRootLogin|^PasswordAuthentication|^Port" /etc/ssh/sshd_config
echo "=== Автообновления ==="
systemctl is-active unattended-upgrades
```
Что вы увидите: сводный отчёт о состоянии всех настроенных в этом блоке защитных механизмов сразу.
[Скриншот сводного отчёта]
Шаг 6. Проверьте текущие процессы на предмет чего-то неожиданного, отсортировав по использованию CPU (мы делали похожее в Блоке 11):
```bash
ps aux --sort=-%cpu | head -10
```
Шаг 7. Создайте простой скрипт-«чеклист» аудита для регулярного использования (полноценные скрипты будем подробно разбирать в Блоке 15, но простейший вариант попробуем уже сейчас):
```bash
nano ~/security_check.sh
```
Содержимое:
```bash
#!/bin/bash
echo "======================================"
echo " ОТЧЁТ АУДИТА БЕЗОПАСНОСТИ"
echo " Дата: $(date)"
echo "======================================"
echo ""
echo "--- Статус UFW ---"
sudo ufw status
echo ""
echo "--- Статус Fail2Ban ---"
sudo fail2ban-client status sshd
echo ""
echo "--- Последние входы ---"
last -5
echo ""
echo "--- Открытые порты ---"
sudo ss -tulnp
echo ""
echo "--- Доступные обновления ---"
apt list --upgradable 2>/dev/null | grep -v "Listing..."
echo "======================================"
echo " КОНЕЦ ОТЧЁТА"
echo "======================================"
```
Сохраните (Ctrl+O, Enter, Ctrl+X), сделайте исполняемым и запустите:
```bash
chmod +x ~/security_check.sh
./security_check.sh
```
[Скриншот вывода скрипта аудита]
Разбор команд
Команда who
- Назначение:** показать пользователей, в данный момент вошедших в систему.
- Синтаксис:**
who [опции]
Команда w
- Назначение:** расширенная версия
who— дополнительно показывает загрузку системы и то, что делает каждый пользователь прямо сейчас. - Синтаксис:**
w [пользователь]
Команда last
- Назначение:** показать историю входов в систему (успешных).
- Синтаксис:**
last [-N] [пользователь] - Параметры:**
-N— показать только последние N записей; можно указать конкретного пользователя для фильтрации:last admin. - Источник данных:** файл
/var/log/wtmp.
Команда lastb
- Назначение: показать историю неудачных** попыток входа.
- Синтаксис:**
sudo lastb [-N](требует root, поскольку файл с этими данными недоступен для чтения обычным пользователям по соображениям приватности и безопасности). - Источник данных:** файл
/var/log/btmp.
Возможные ошибки
- Ошибка:** после настройки всех защитных механизмов администратор теряет бдительность и перестаёт проверять логи и статусы.
Почему возникает: ложное чувство полной защищённости после первоначальной настройки («я всё настроил один раз, теперь можно забыть»).
Как определить: это не техническая ошибка с явным сообщением, а поведенческая — её можно «определить» только осознанной саморефлексией администратора.
Как исправить/избежать: выработать привычку регулярного (например, еженедельного) запуска аудита — как в скрипте из практики этого урока; для более продвинутого мониторинга в будущем можно настроить автоматические уведомления (мы коснёмся мониторинга подробнее в Блоке 18).
Практические задания
- Запустите скрипт
~/security_check.sh, созданный в практике, и сохраните его вывод в файл с датой в названии:./security_check.sh > ~/audit_$(date +%Y%m%d).txt. Изучите результат и отметьте в конспекте любые моменты, которые хотели бы улучшить. - Составьте в конспекте свой собственный чек-лист «10 пунктов проверки безопасности сервера», основываясь на материале всего блока (можно использовать список типичных ошибок из теории как отправную точку, но переформулируйте его в позитивные утверждения — «что должно быть настроено», а не «чего не нужно делать»).
- Изучите вывод команды
lastна своей системе подробнее — найдите там записи о собственных сессиях, которые вы создавали в практике уроков этого и предыдущего блока, и сопоставьте время с тем, что вы помните о своей работе.
Проверка знаний
Вопрос 1. Почему безопасность сервера нельзя «настроить один раз и забыть», даже если все меры защиты из этого блока правильно применены?
Ответ: Потому что ландшафт угроз постоянно меняется: появляются новые уязвимости, меняются методы атак, могут накапливаться забытые учётные записи или неиспользуемые открытые порты, а защитные механизмы (firewall, Fail2Ban, автообновления) сами могут «тихо сломаться» из-за ошибок конфигурации, конфликтов при обновлениях или иных причин. Регулярный аудит — единственный способ убедиться, что защита продолжает реально работать, а не просто была настроена когда-то в прошлом.
Вопрос 2. В чём разница между источниками данных для команд last и lastb, и какая из них полезнее для обнаружения попытки атаки перебором?
Ответ: last читает /var/log/wtmp и показывает успешные входы в систему. lastb читает /var/log/btmp и показывает неудачные попытки входа. Для обнаружения атаки перебором полезнее lastb — большое количество неудачных попыток за короткое время, особенно с одного и того же IP-адреса или с попытками входа под несуществующими пользователями (admin, root, test и т.д.) — явный признак автоматизированной атаки.
Итоги урока
Вы изучили: компоненты регулярного аудита безопасности, команды who/w/last/lastb, типичные ошибки начинающих администраторов Linux, общий план действий при подозрении на компрометацию системы.
Вы умеете: проверять текущие и прошлые сессии входа в систему, выявлять неудачные попытки аутентификации, составлять и запускать простой скрипт для сводного аудита безопасности.
В следующем блоке потребуется: всё, что вы изучили о безопасности — Блок 15 посвящён bash-скриптам, и мы будем регулярно писать скрипты, автоматизирующие в том числе задачи, связанные с безопасностью и обслуживанием сервера (например, автоматизированные бэкапы и проверки).
Мини-проект блока
Задача: применить весь материал блока последовательно к одной системе (вашей учебной машине или виртуальной машине, если вы её используете отдельно от основной рабочей системы) и задокументировать результат.
Что нужно сделать (строго в этом порядке, с соблюдением всех предупреждений из уроков):
- Аудит «до»: запустите созданный в уроке 14.6 скрипт
~/security_check.sh(или соберите информацию вручную) и сохраните результат какaudit_before.txt— это будет ваша точка отсчёта.
- Настройте SSH-ключи, если ещё не сделано (Блок 13), и обязательно проверьте, что вход по ключу работает, прежде чем двигаться дальше.
- Настройте UFW: разрешите SSH, задайте политики по умолчанию (
deny incoming,allow outgoing), включите firewall. Разрешите дополнительно порты 80 и 443 (для будущего веб-сервера из Блока 19).
- Установите и настройте Fail2Ban: создайте
jail.local, настройтеmaxretryиbantimeдля jailsshdна своё усмотрение (обоснуйте выбранные значения в документации проекта), добавьте свой рабочий IP-адрес (или127.0.0.1/8для учебных целей) вignoreip.
- Хардненинг SSH-сервера: сделайте резервную копию
sshd_config, отключитеPermitRootLoginиPasswordAuthentication, установитеMaxAuthTries 3. Строго следуйте протоколу безопасного применения изменений (не закрывать исходную сессию до проверки).
- Настройте автоматические обновления безопасности через
unattended-upgrades, проверьте работу через--dry-run.
- Аудит «после»: снова запустите
~/security_check.sh, сохраните какaudit_after.txt.
- Напишите итоговый отчёт (
~/hardening_report.md, можно текстовым файлом) со сравнением состояния «до» и «после»: что было изменено, зачем, какие риски это устраняет. Включите явный список: «если бы я не настроил X, то злоумышленник мог бы сделать Y».
Критерий готовности: сервер проходит финальную проверку — SSH работает только по ключу, firewall активен с корректными правилами, Fail2Ban отслеживает попытки входа, автообновления безопасности включены, и у вас есть письменный отчёт, объясняющий каждое изменение.
Важное напоминание перед стартом: выполняйте шаги строго по порядку и не пропускайте проверочные действия («не закрывать сессию», «dry-run перед реальным запуском» и т.д.) — именно в этих деталях и заключается разница между безопасным администрированием и случайной потерей доступа к своей же системе.
Контрольные вопросы
- Объясните принцип «глубокоэшелонированной защиты» на примере конкретных механизмов, настроенных в этом блоке (перечислите минимум 3 независимых слоя).
- Какую команду нужно выполнить в UFW до включения политики
default deny incoming, чтобы не потерять доступ по SSH, и почему порядок действий здесь критичен? - Опишите, что такое jail в Fail2Ban, и объясните взаимодействие параметров
maxretryиfindtimeна конкретном числовом примере. - Перечислите как минимум 4 параметра файла
/etc/ssh/sshd_config, связанных с безопасностью, и объясните назначение каждого. - Почему нельзя закрывать текущую SSH-сессию сразу после изменения критичных настроек SSH-сервера и его перезапуска? Опишите правильную последовательность действий.
- В чём разница между обновлениями из канала
-securityи обычными обновлениями-updatesс точки зрения того, что устанавливаетunattended-upgradesпо умолчанию, и почему сделан именно такой выбор? - Назовите источники данных (файлы логов) для команд
lastиlastb, и объясните, для чего каждая из них полезна при аудите безопасности.
Выводы по блоку
Этот блок — один из самых практически важных во всём курсе. Вы прошли путь от понимания фундаментальных принципов безопасности до реальной, работающей многослойной защиты сервера: firewall, отражающий нежелательный сетевой трафик; Fail2Ban, автоматически реагирующий на попытки перебора; жёстко настроенный SSH, где перебор пароля физически невозможен; автоматические обновления, закрывающие уязвимости без ручного вмешательства; и, наконец, привычка регулярного аудита, которая превращает разовую настройку в постоянный процесс.
Важно понимать: абсолютной безопасности не существует — задача администратора не «сделать сервер неуязвимым», а последовательно применять принцип глубокоэшелонированной защиты, минимизировать поверхность атаки и оставаться внимательным. Ошибки, которые мы разобрали (потеря доступа при неправильном порядке действий, работа от root, игнорирование обновлений), — это те грабли, на которые наступает практически каждый начинающий администратор. Теперь вы знаете, как их избежать.
Материал этого блока будет использоваться в оставшейся части курса постоянно: в Блоке 17 (безопасность контейнеров Docker во многом опирается на те же принципы), в Блоке 19 (защита веб-сервера и баз данных), в Блоке 20 (полный хардненинг реального продакшн-сервера при развёртывании), и в финальном экзамене Блока 21, где безопасность будет одним из критериев оценки итогового проекта.
Список изученных тем
- Основы информационной безопасности: категории угроз, принципы (наименьшие привилегии, глубокоэшелонированная защита, минимизация поверхности атаки, регулярные обновления, мониторинг).
- UFW: политики по умолчанию,
allow/deny/reject/limit, работа с портами и IP-адресами, критичный порядок действий при включении. - Fail2Ban: принцип действия, jail/filter/ban/findtime/maxretry, файлы
jail.conf/jail.local, командыfail2ban-client. - Хардненинг SSH:
/etc/ssh/sshd_config,PermitRootLogin,PasswordAuthentication,Port,MaxAuthTries,AllowUsers, безопасный протокол внесения изменений,sshd -t. unattended-upgrades: принцип автоматических обновлений безопасности, разница каналов-securityи-updates, автоматическая перезагрузка.- Аудит безопасности: команды
who,w,last,lastb, типичные ошибки администраторов, план действий при подозрении на компрометацию.
Рекомендации перед переходом
Убедитесь, что вы умеете:
- Объяснить, зачем нужен каждый из настроенных механизмов защиты (firewall, Fail2Ban, SSH-хардненинг, автообновления), а не просто повторить команды механически.
- Безопасно вносить изменения в критичные конфигурационные файлы (резервная копия → проверка синтаксиса → проверка в отдельной сессии → только потом закрытие старой).
- Провести базовый аудит системы и понять, что означает каждый пункт в выводе.
В Блоке 15 мы начнём писать bash-скрипты — и весь материал этого блока пригодится напрямую: мы будем автоматизировать резервное копирование, регулярные проверки безопасности и многое другое, превращая ручные последовательности команд в надёжные, повторяемые скрипты.