2 min read

Связка PF + Blocklistd для SSH

Если ваш сервер смотрит в мир с открытым 22-м портом, вы знаете: боты начинают атаку через секунды после аптайма. Традиционный fail2ban на Python — это классика, но во FreeBSD есть более элегантное, нативное и «легкое» решение: blocklistd.

В этой статье мы настроим «двухслойную броню»: PF будет отсекать сетевой флуд, а blocklistd — наказывать за неверные пароли.


Зачем нам два слоя?

  1. Слой PF (Защита от флуда): Мгновенно блокирует IP, который пытается открыть слишком много соединений в секунду. Это защищает сам сервис sshd от перегрузки.
  2. Слой Blocklistd (Защита от перебора): Блокирует тех, кто заходит медленно и аккуратно, но постоянно вводит неправильный пароль.

1. Настройка PF (Packet Filter)

Отредактируйте /etc/pf.conf. Мы добавим таблицу для «скорострелов» и якорь для умной блокировки.

PF

# Глобальные опции
set skip on lo0
set block-policy drop

# 1. Таблица для ручной блокировки и защиты от флуда
table <bruteforce> persist

# 2. Якорь для blocklistd
anchor "blocklistd/*" in quick

# ==========================================
# ПРАВИЛА ФИЛЬТРАЦИИ
# ==========================================

# Блокируем всё по дефолту
block in all
# Мгновенный бан из таблицы
block in quick from <bruteforce>

pass out all keep state

# Разрешаем SSH с лимитом на соединения (5 коннектов за 3 сек)
pass in proto tcp from any to any port 22 flags S/SA keep state \
    (max-src-conn 15, max-src-conn-rate 5/3, \
    overload <bruteforce> flush global)

# Разрешаем Веб и ICMP
pass in proto tcp from any to any port { 80, 443 }
pass in inet proto icmp all icmp-type echoreq

Примените конфиг:

Bash

pfctl -nf /etc/pf.conf && pfctl -f /etc/pf.conf

2. Настройка blocklistd

Создайте или отредактируйте /etc/blocklistd.conf:

Plaintext

# [адрес:порт]    [тип]      [протокол] [владелец] [название_якоря] [nfail] [время_бана]
[local]
ssh              stream     tcp        * * 3       24h
ftp              stream     tcp        * * 3       24h
* * * * * 3       60

Здесь 3 — количество провалов авторизации до бана на 24h.


3. Настройка SSHD

Во FreeBSD 15 поддержка blocklistd встроена в базовый sshd. Просто включите её в /etc/ssh/sshd_config:

Plaintext

UseBlocklist yes

4. Запуск системы

Добавим сервисы в автозагрузку и запустим их:

Bash

sysrc pf_enable="YES"
sysrc blocklistd_enable="YES"
sysrc sshd_enable="YES"

service pf restart
service blocklistd start
service sshd restart

5. Мониторинг: Кто в бане?

Теперь у вас есть две точки контроля.

Проверка "умных" банов (за пароли):

Bash

blocklistctl dump

Если в колонке id стоит OK, значит IP заблокирован. Вы можете увидеть это правило в PF:

Bash

pfctl -a "blocklistd/22" -sr

Проверка "глупых" банов (за флуд):

Посмотреть список IP, которые пытались открыть слишком много соединений:

Bash

pfctl -t bruteforce -T show

Итог

Такая конфигурация делает ваш сервер максимально неудобной целью. PF берет на себя черную работу по фильтрации сетевого шума, а blocklistd точечно выбивает тех, кто пытается подобрать ключи к вашей системе.