Защита SSH-сервера и Fail2ban: полное руководство по безопасности Linux

Кибербезопасность 24 марта 2026 12 мин чтения Автор: Евгений Семёнов ...
Защита SSH и Fail2ban на Linux

Любой Linux-сервер с открытым SSH-портом живёт под непрерывным огнём брутфорса — тысячи попыток в день, без выходных. Fail2ban спасает, но только если настроен правильно. Мы собрали десятки реальных граблей из практики наших администраторов и сложили всё в одно руководство — чтобы вы не наступали на то, на что уже наступили мы.

Из нашей практики: на серверах клиентов ITfresh мы фиксируем от 5 000 до 50 000 попыток подбора пароля SSH в сутки. Голый сервер без Fail2ban и нормально настроенного sshd — это не вопрос «взломают ли», а вопрос «когда». По нашим наблюдениям, в среднем хватает 72 часов.

Как правильно настроить SSH для максимальной безопасности?

Начнём с ужесточения самого SSH-демона. Открываем /etc/ssh/sshd_config и правим под себя:

# Меняем порт (снижает автосканирование на 95%)
Port 2222

# Запрещаем вход root по паролю
PermitRootLogin prohibit-password

# Только SSH-ключи, никаких паролей
PasswordAuthentication no
PubkeyAuthentication yes

# Ограничиваем пользователей
AllowUsers admin deploy

# Отключаем устаревшие протоколы
Protocol 2

# Тайм-ауты
ClientAliveInterval 300
ClientAliveCountMax 2
LoginGraceTime 30

# Отключаем X11 и агент-форвардинг
X11Forwarding no
AllowAgentForwarding no

# Логирование
LogLevel VERBOSE
# Генерируем SSH-ключ на клиенте
ssh-keygen -t ed25519 -C "admin@company.com"

# Копируем на сервер
ssh-copy-id -p 2222 admin@server.example.com

# Проверяем вход по ключу, затем отключаем пароли
sudo systemctl restart sshd
Важно: перед отключением PasswordAuthentication убедитесь, что вход по ключу работает! Иначе потеряете доступ к серверу. Держите открытой вторую SSH-сессию для подстраховки.

Как установить и настроить Fail2ban с нуля?

# Установка
apt update && apt install -y fail2ban

# Никогда не редактируйте jail.conf — создавайте jail.local
cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

Базовая конфигурация в /etc/fail2ban/jail.local — отправная точка, от которой уже танцуем дальше:

[DEFAULT]
# Ваши IP, которые никогда не банить
ignoreip = 127.0.0.1/8 ::1 192.168.1.0/24 10.0.0.0/8

# Время бана (1 час)
bantime = 3600

# Окно наблюдения
findtime = 600

# Количество попыток до бана
maxretry = 5

# Действие: бан + отправка уведомления
action = %(action_mwl)s

# Метод бана
banaction = iptables-multiport

[sshd]
enabled = true
port = 2222
filter = sshd[mode=aggressive]
logpath = /var/log/auth.log
maxretry = 3
bantime = 86400
Из нашей практики: для SSH ставьте maxretry = 3 и bantime = 86400 (24 часа). Три попытки — достаточно для легитимного пользователя с опечаткой, но слишком мало для брутфорса.

Почему Fail2ban не ловит атаки на Dovecot?

Пожалуй, самая частая жалоба в комментариях — фильтр Dovecot просто не срабатывает. Причин обычно несколько:

1. Неправильный regex в фильтре

В свежих версиях Dovecot формат логов поменялся, и старые regex тихо перестают работать. Проще использовать встроенные режимы — они обновляются вместе с пакетом:

# /etc/fail2ban/jail.local
[dovecot]
enabled = true
port = pop3,pop3s,imap,imaps,submission,465,sieve
filter = dovecot[mode=aggressive]
logpath = /var/log/mail.log
maxretry = 3
bantime = 3600

2. Ошибка «No failure-id group in regex»

Эта ошибка говорит об одном: в regex нет группы захвата для IP-адреса. Без неё Fail2ban просто не знает, кого банить. Смотрим:

# Тестируем фильтр на реальных логах
fail2ban-regex /var/log/mail.log /etc/fail2ban/filter.d/dovecot.conf

# Должны увидеть строки типа:
# Lines: 1523 lines, 0 ignored, 47 matched, 1476 missed

3. Auth-worker с SQL-бэкендом не логирует IP

Если пользователи Dovecot хранятся в SQL, auth-worker иногда не пишет IP в лог вообще — и Fail2ban остаётся слепым:

# Убедитесь, что в /etc/dovecot/conf.d/10-logging.conf
auth_verbose = yes
auth_verbose_passwords = sha1:6

Dovecot банит собственный IP сервера — как исправить?

Классика жанра, которую мы видели не раз: Dovecot при внутренних LMTP-запросах пишет ошибку аутентификации с адресом 127.0.0.1 — и Fail2ban радостно банит локалхост. Почта встаёт колом. Лечится в два шага.

# Решение 1: добавить в ignoreip
[DEFAULT]
ignoreip = 127.0.0.1/8 ::1

# Решение 2: исправить Dovecot — не логировать LMTP как ошибку
# /etc/dovecot/conf.d/20-lmtp.conf
protocol lmtp {
  mail_plugins = $mail_plugins
  auth_verbose = no
}
Из комментариев: один администратор потерял доступ к серверу на 2 часа, потому что Fail2ban забанил 127.0.0.1. Всегда проверяйте ignoreip перед запуском!

Как настроить Fail2ban для Postfix?

Postfix тоже под ударом — SASL-брутфорс через SMTP-аутентификацию встречается не реже SSH-атак:

[postfix-sasl]
enabled = true
port = smtp,465,587,submission
filter = postfix[mode=auth]
logpath = /var/log/mail.log
maxretry = 3
bantime = 3600
findtime = 300

Для дополнительного слоя защиты добавьте фильтр на попытки авторизации несуществующих пользователей — «unknown user»:

# /etc/fail2ban/filter.d/postfix-unknown.conf
[Definition]
failregex = ^%(__prefix_line)sNOQUEUE: reject: RCPT from .*\[\].*: 550 5\.1\.1
            ^%(__prefix_line)swarning: .*\[\]: SASL (?:LOGIN|PLAIN|CRAM-MD5) authentication failed
ignoreregex =

# Активируем
[postfix-unknown]
enabled = true
port = smtp,465,587
filter = postfix-unknown
logpath = /var/log/mail.log
maxretry = 5
bantime = 7200

Как использовать Fail2ban с UFW вместо iptables?

Клиенты регулярно пишут: «Поставил UFW, Fail2ban перестал работать». Это решается одной строчкой конфига:

# /etc/fail2ban/jail.local
[DEFAULT]
banaction = ufw

# Проверяем, что action.d/ufw.conf существует
ls /etc/fail2ban/action.d/ufw.conf

# Если файла нет — обновите fail2ban
apt install --reinstall fail2ban
# После бана проверяем правила UFW
ufw status numbered

# Fail2ban добавляет правила в начало списка:
# [ 1] Anywhere   DENY IN   203.0.113.50

Как защитить PostfixAdmin и веб-панели от брутфорса?

PostfixAdmin, Roundcube и прочие веб-морды — отдельная история. Их тоже ломают, причём целенаправленно:

# Кастомный фильтр для nginx auth
# /etc/fail2ban/filter.d/nginx-auth.conf
[Definition]
failregex = ^ .* "(POST|GET) /postfixadmin/login\.php.*" (401|403)
            ^ .* "(POST|GET) /roundcube/.*" (401|403)
ignoreregex =

# /etc/fail2ban/jail.local
[nginx-auth]
enabled = true
port = http,https
filter = nginx-auth
logpath = /var/log/nginx/access.log
maxretry = 5
bantime = 3600

Поверх Fail2ban поставьте rate limiting прямо в nginx — лишним не будет:

# /etc/nginx/conf.d/rate-limit.conf
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;

# В блоке location для логин-страниц
location /postfixadmin/login.php {
    limit_req zone=login burst=3 nodelay;
    # ... остальная конфигурация
}

Как мониторить работу Fail2ban?

# Статус всех jail'ов
fail2ban-client status

# Подробности по конкретному jail
fail2ban-client status sshd

# Список забаненных IP
fail2ban-client status sshd | grep "Banned IP"

# Разбанить конкретный IP
fail2ban-client set sshd unbanip 192.168.1.100

# Логи Fail2ban
tail -f /var/log/fail2ban.log

# Статистика банов за последние 24 часа
grep "Ban " /var/log/fail2ban.log | grep "$(date +%Y-%m-%d)" | wc -l
Из нашей практики: настройте отправку email-уведомлений о банах. Это помогает вовремя заметить целенаправленную атаку: action = %(action_mwl)s в секции [DEFAULT].

Продвинутая конфигурация: рецидивисты и GeoIP

Для особо настойчивых атакующих есть jail recidive. Попал в бан дважды — получаешь бан на несколько недель:

[recidive]
enabled = true
logpath = /var/log/fail2ban.log
filter = recidive
banaction = iptables-allports
bantime = 604800    # 1 неделя
findtime = 86400    # Окно 24 часа
maxretry = 3        # 3 бана за сутки = бан на неделю

Если все ваши клиенты работают из РФ, гео-блокировка режет шум примерно на 80%. Настраивается так:

# Устанавливаем GeoIP
apt install -y geoip-bin geoip-database

# Скрипт для бана не-RU IP
#!/bin/bash
# /opt/scripts/geoip-check.sh
IP=$1
COUNTRY=$(geoiplookup "$IP" | awk -F': ' '{print $2}' | cut -c1-2)
if [ "$COUNTRY" != "RU" ] && [ "$COUNTRY" != "IP" ]; then
    echo "Blocked: $IP ($COUNTRY)"
    iptables -A INPUT -s "$IP" -j DROP
fi

Двухфакторная аутентификация для SSH

На критичных серверах мы рекомендуем добавить двухфакторку через Google Authenticator — даже если ключ утечёт, этого будет мало:

# Установка
apt install -y libpam-google-authenticator

# Настройка для пользователя
google-authenticator
# Ответьте: y, y, n, y

# /etc/pam.d/sshd — добавьте в начало
auth required pam_google_authenticator.so

# /etc/ssh/sshd_config
ChallengeResponseAuthentication yes
AuthenticationMethods publickey,keyboard-interactive

systemctl restart sshd
Важно: сначала настройте 2FA на тестовом аккаунте. Сохраните резервные коды! Без них при потере телефона вы потеряете доступ к серверу.

Port knocking — скрытый SSH-порт

Port knocking — нишевая, но рабочая техника. SSH-порт вообще не виден снаружи, пока не отправишь правильную последовательность пакетов-«стуков»:

# Установка
apt install -y knockd

# /etc/knockd.conf
[options]
    UseSyslog

[openSSH]
    sequence    = 7000,8000,9000
    seq_timeout = 5
    command     = /sbin/iptables -A INPUT -s %IP% -p tcp --dport 2222 -j ACCEPT
    tcpflags    = syn

[closeSSH]
    sequence    = 9000,8000,7000
    seq_timeout = 5
    command     = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 2222 -j ACCEPT
    tcpflags    = syn

# Закрываем SSH по умолчанию
iptables -A INPUT -p tcp --dport 2222 -j DROP

# Стучим с клиента
knock server.example.com 7000 8000 9000
ssh -p 2222 admin@server.example.com

Аудит: кто пытался взломать ваш сервер?

# Топ-10 атакующих IP за последний месяц
grep "Failed password" /var/log/auth.log | \
  awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head -10

# Страны атакующих
grep "Failed password" /var/log/auth.log | \
  awk '{print $(NF-3)}' | sort -u | while read ip; do
    echo "$ip - $(geoiplookup $ip | cut -d: -f2)"
  done

# Успешные входы
grep "Accepted" /var/log/auth.log | tail -20

# Сколько атак отразил Fail2ban
grep "Ban" /var/log/fail2ban.log | wc -l

Подробнее об аудите серверов — в статье Аудит перезагрузок Windows Server.

Чек-лист безопасности SSH-сервера

  1. SSH-ключи вместо паролей — PasswordAuthentication no, и пароли можно забыть как страшный сон
  2. Нестандартный порт — Port 2222 отсекает примерно 90% автоматических сканеров
  3. Fail2ban с maxretry = 3 для SSH — три попытки, и до свидания
  4. Fail2ban для Postfix и Dovecot — если крутите почту, это не опция, а обязательная программа
  5. ignoreip — внесите свои подсети и 127.0.0.1, иначе рискуете забанить сами себя
  6. AllowUsers — только те, кому действительно нужен SSH, и никого лишнего
  7. 2FA через Google Authenticator — обязательно для серверов с чувствительными данными
  8. Автоматические обновления безопасности: apt install unattended-upgrades — патчи не должны ждать, пока руки дойдут
  9. Мониторинг логов с уведомлениями о банах — чтобы знать о волне атак раньше, чем она докатится
  10. Регулярный аудит /var/log/auth.log — раз в неделю хотя бы пробегитесь глазами
IT-аутсорсинг для бизнеса

Нужен аудит безопасности сервера?

Специалисты ITfresh проведут полный аудит безопасности вашего Linux-сервера: проверят SSH, настроят Fail2ban, firewall и мониторинг. Работаем удалённо по всей России.

200+серверов под защитой
0взломов за 3 года
24/7мониторинг

Читайте также

Комментарии