Защита 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
maxretry = 3 и bantime = 86400 (24 часа). Три попытки — достаточно для легитимного пользователя с опечаткой, но слишком мало для брутфорса.Почему Fail2ban не ловит атаки на Dovecot?
Самая частая проблема из комментариев: фильтр Dovecot не срабатывает. Причины:
1. Неправильный regex в фильтре
В новых версиях Dovecot формат логов изменился. Используйте встроенные режимы:
# /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-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
Если используете SQL для хранения пользователей Dovecot, auth-worker может не писать IP в лог:
# Убедитесь, что в /etc/dovecot/conf.d/10-logging.conf
auth_verbose = yes
auth_verbose_passwords = sha1:6
Dovecot банит собственный IP сервера — как исправить?
Классическая проблема: Dovecot при внутренних LMTP-запросах логирует ошибку аутентификации с IP 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
}
ignoreip перед запуском!Как настроить Fail2ban для Postfix?
Postfix подвергается SASL-брутфорсу — подбору паролей через SMTP-аутентификацию:
[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
Дополнительно настройте 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
action = %(action_mwl)s в секции [DEFAULT].Продвинутая конфигурация: рецидивисты и GeoIP
Для злостных нарушителей используйте jail recidive — он банит IP, которые попадают в бан повторно:
[recidive]
enabled = true
logpath = /var/log/fail2ban.log
filter = recidive
banaction = iptables-allports
bantime = 604800 # 1 неделя
findtime = 86400 # Окно 24 часа
maxretry = 3 # 3 бана за сутки = бан на неделю
Блокировка по странам (если все клиенты в РФ):
# Устанавливаем 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
Для максимальной безопасности добавьте 2FA через 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
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-сервера
- SSH-ключи вместо паролей —
PasswordAuthentication no - Нестандартный порт —
Port 2222 - Fail2ban с
maxretry = 3для SSH - Fail2ban для Postfix/Dovecot (если есть почта)
ignoreip— ваши сети и 127.0.0.1AllowUsers— только нужные пользователи- 2FA (Google Authenticator) для критичных серверов
- Автоматические обновления безопасности:
apt install unattended-upgrades - Мониторинг логов и уведомления о банах
- Регулярный аудит
/var/log/auth.log
Нужен аудит безопасности сервера?
Специалисты ITfresh проведут полный аудит безопасности вашего Linux-сервера: проверят SSH, настроят Fail2ban, firewall и мониторинг. Работаем удалённо по всей России.