Обзор
FreeBSD исторически проектировалась с акцентом на безопасность. Base system включает инструменты, которые в Linux требуют отдельных пакетов: встроенный аудит, MAC framework, securelevel, blocklistd, интегрированный OpenSSH с поддержкой blocklistd, файловые флаги immutable/append-only. Всё это — часть системы, а не надстройки.
Статья организована от практичного к продвинутому: сначала SSH и базовый hardening (то, что нужно сделать на каждом VPS в первый час), затем брутфорс-защита, firewall-аспекты безопасности, аудит и MAC framework. Многие темы пересекаются с предыдущими статьями (sysctl, pf, jails) — здесь они собраны в единую картину безопасности.
SSH: первая линия обороны
Конфигурация sshd
OpenSSH входит в base system FreeBSD. Конфигурация — /etc/ssh/sshd_config. Ключевые настройки для production:
# /etc/ssh/sshd_config
# Аутентификация
PermitRootLogin no # запретить прямой вход root
PubkeyAuthentication yes # разрешить ключи
PasswordAuthentication no # отключить пароли (после настройки ключей!)
KbdInteractiveAuthentication no # отключить keyboard-interactive
PermitEmptyPasswords no
# Ограничение доступа
AllowUsers deployer admin # только перечисленные пользователи
# или AllowGroups sshusers # по группе
# Таймауты и лимиты
LoginGraceTime 30 # секунд на аутентификацию (дефолт 120)
MaxAuthTries 3 # попыток аутентификации
MaxSessions 5 # сессий на соединение
ClientAliveInterval 300 # keepalive каждые 5 мин
ClientAliveCountMax 2 # 2 пропуска = разрыв
# Протокол
X11Forwarding no # если не нужен
AllowTcpForwarding no # если не нужен проброс портов
AllowAgentForwarding no # если не нужен
PrintMotd no
# Blocklistd интеграция (base system)
UseBlocklist yes
Порядок действий: сначала настроить ключи и проверить вход, потом отключать пароли. Потеря доступа при PasswordAuthentication no без рабочего ключа — классическая ошибка.
Ключи и Ed25519
# На клиенте — генерация ключа
ssh-keygen -t ed25519 -C "user@host"
# Копирование на сервер
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server
# На сервере — проверка прав
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
Ed25519 предпочтительнее RSA: короче, быстрее, устойчивее к side-channel атакам. RSA-4096 — приемлемый fallback для совместимости со старыми клиентами.
doas vs sudo
FreeBSD base system не включает sudo (это сторонний пакет). Альтернатива из OpenBSD — doas(1), значительно проще и минималистичнее:
pkg install doas
# /usr/local/etc/doas.conf
permit persist :wheel # группа wheel может выполнять команды от root
permit nopass deployer cmd service # deployer может перезапускать сервисы без пароля
persist должен кэшировать аутентификацию, чтобы не вводить пароль на каждую команду, — но именно на FreeBSD порт security/doas этого не умеет: механизм опирается на ioctl TIOCCHKVERAUTH, которого в ядре FreeBSD нет, и пароль спрашивается каждый раз. Кому нужен работающий persist — ставит security/opendoas, форк OpenDoas с собственной реализацией timestamp-файлов. doas.conf — один файл с простым синтаксисом, в отличие от sudoers с его визивигами и потенциальными ошибками.
sudo тоже доступен (pkg install sudo), и для сложных сценариев с гранулярными правилами он мощнее. Для типичного VPS с 1-3 администраторами doas достаточен.
Базовый hardening: sysctl и rc.conf
Собираем в одном месте все security-relevant настройки из предыдущих статей.
/etc/sysctl.conf
# Видимость процессов: пользователи не видят чужие процессы
security.bsd.see_other_uids=0
security.bsd.see_other_gids=0
security.bsd.see_jail_proc=0
# Непривилегированные пользователи не могут читать dmesg и отлаживать процессы
security.bsd.unprivileged_read_msgbuf=0
security.bsd.unprivileged_proc_debug=0
# ASLR — рандомизация адресного пространства
kern.elf64.aslr.enable=1
kern.elf64.aslr.pie_enable=1
kern.elf32.aslr.enable=1
kern.elf32.aslr.pie_enable=1
# Рандомизация PID
kern.randompid=1
# Отключить core dumps (могут содержать чувствительные данные)
kern.coredump=0
# Stack guard page
security.bsd.stack_guard_page=1
/etc/rc.conf
# Очистка /tmp при загрузке
clear_tmp_enable="YES"
# Отключить sendmail (если не нужен)
sendmail_enable="NONE"
sendmail_submit_enable="NO"
sendmail_outbound_enable="NO"
sendmail_msp_queue_enable="NO"
# Syslogd: не слушать сеть (если не syslog-сервер)
syslogd_flags="-ss"
# Включить PF
pf_enable="YES"
pflog_enable="YES"
/etc/ttys — запрет прямого root-входа на консоль
Заменить secure на insecure для всех терминалов:
ttyv0 "/usr/libexec/getty Pc" xterm on insecure
После этого root не может войти напрямую через консоль — только через su/doas от обычного пользователя. Это создаёт audit trail: в логах видно, кто именно стал root.
Защита от брутфорса
Три подхода, от встроенного до стороннего, с разными trade-off'ами.
PF overload tables (встроенный)
PF имеет встроенный механизм автоматического блокирования по rate-limiting (описан в статье о сети):
table <bruteforce> persist
block quick from <bruteforce>
pass in on $ext_if proto tcp to port ssh \
flags S/SA keep state \
(max-src-conn 5, max-src-conn-rate 3/30, \
overload <bruteforce> flush global)
Это работает на L4 — считает TCP-соединения, не заглядывая в протокол аутентификации. Достаточно для SSH, но не видит неудачные логины на уровне приложения. Нет экспоненциального backoff'а.
Для автоматической очистки таблицы от старых записей:
# /etc/crontab (очищать записи старше 24 часов)
0 * * * * root /sbin/pfctl -t bruteforce -T expire 86400
blocklistd (base system)
blocklistd(8) — демон из base system FreeBSD (портирован из NetBSD). Принципиально отличается от fail2ban/sshguard: вместо парсинга логов использует API (libblocklist), через который приложения напрямую сообщают о неудачных попытках аутентификации. FreeBSD-шный sshd уже поддерживает это API.
В FreeBSD 15.0 весь набор переименован вслед за upstream: blacklistd стал blocklistd, libblacklist — libblocklist, конфиг переехал в /etc/blocklistd.conf, переменная rc.conf — blocklistd_enable. Старые имена сохранены как алиасы и продолжают работать, печатая предупреждение; в 14.x актуальны ещё они. Переименовать нужно и файлы конфигурации, и якоря firewall.
# /etc/ssh/sshd_config
UseBlocklist yes
# /etc/rc.conf
blocklistd_enable="YES"
# /etc/blocklistd.conf
# adr/mask:port type proto owner name nfail duration
[local]
ssh stream * * * 3 24h
ftp stream * * * 3 24h
smtp stream * * * 3 24h
* * * * * 3 60
Конфигурация читается так: после 3 неудачных попыток (nfail) на порт ssh — заблокировать источник на 24 часа (последнее поле, duration). Правила демон создаёт сам, но выкладывает их в якорь: по умолчанию — в PF-anchor blocklistd, который должен быть объявлен в pf.conf (anchor "blocklistd/*" in on $ext_if), иначе блокировки никуда не попадут. Пятое поле правила позволяет задать своё имя якоря.
Преимущества перед fail2ban/sshguard: работает через API, а не парсит логи (не сломается при изменении формата логов); входит в base system (нет внешних зависимостей); интеграция с sshd на уровне кода.
Недостаток: работает только с приложениями, поддерживающими libblocklist API. На практике это прежде всего sshd; ftpd, второй классический потребитель API, из base удалён в 15.0 и живёт теперь в порту ftp/freebsd-ftpd. Для защиты nginx, postfix, dovecot — нужен sshguard или fail2ban.
sshguard (сторонний)
sshguard (security/sshguard) — лёгкий демон, парсящий логи и блокирующий атакующих через firewall backend. Поддерживает PF, IPFW, IPFILTER, а на Linux — iptables/nftables. Отдельных портов под каждый backend (sshguard-pf, sshguard-ipfilter) больше нет: остался один порт, а backend выбирается строкой BACKEND в конфиге.
pkg install sshguard
sysrc sshguard_enable="YES"
Читать логи sshguard умеет сам — через FILES или LOGREADER в конфиге. Старый рецепт с pipe в /etc/syslog.conf (auth.info;authpriv.info |exec /usr/local/sbin/sshguard) порт прямо называет нерекомендуемым и неподдерживаемым.
В PF добавить таблицу и правило:
table <sshguard> persist
block in quick on $ext_if proto tcp from <sshguard> to any port ssh
sshguard использует экспоненциальный backoff: первая блокировка — 120 сек, вторая — 240, третья — 480 и т.д. Поддерживает permanent blacklist для упорных атакующих.
Конфигурация /usr/local/etc/sshguard.conf:
BACKEND="/usr/local/libexec/sshg-fw-pf"
LOGREADER="LANG=C /usr/bin/tail -n 0 -F /var/log/auth.log"
THRESHOLD=30
BLOCK_TIME=120
DETECTION_TIME=1800
BLACKLIST_FILE=120:/var/db/sshguard/blacklist.db
Выбор подхода
Минимальный VPS с SSH: PF overload + PasswordAuthentication no — достаточно.
VPS с несколькими сервисами: blacklistd для SSH + PF overload для остальных.
Сервер с множеством сервисов (mail, web, ftp): sshguard или fail2ban — парсят логи всех сервисов.
Файловые флаги: immutable и append-only
FreeBSD поддерживает расширенные файловые флаги через chflags(1):
chflags schg /etc/rc.conf # system immutable — даже root не может изменить
chflags sappnd /var/log/auth.log # system append-only — можно добавлять, нельзя перезаписывать
chflags noschg /etc/rc.conf # снять флаг
Флаги schg (system immutable) и sappnd (system append-only) работают в связке с securelevel. При securelevel ≥ 1 снять эти флаги невозможно без перезагрузки в single-user mode. Это защищает критичные файлы от модификации даже при компрометации root.
ls -lo /etc/rc.conf # посмотреть флаги (колонка flags)
Практическое применение: установить schg на ключевые конфиги (/etc/rc.conf, /etc/ssh/sshd_config, /boot/loader.conf) и sappnd на лог-файлы. При securelevel 1 атакующий с root-доступом не сможет подчистить логи или изменить конфигурацию.
Securelevel
Подробно описан в статье о sysctl, здесь — security-контекст.
# /etc/rc.conf
kern_securelevel_enable="YES"
kern_securelevel="1"
Securelevel 1 на production-сервере закрывает конкретные вектора атак: загрузку вредоносных kernel modules (kldload), прямой доступ к памяти (/dev/mem, /dev/kmem), снятие флагов immutable/append-only. Securelevel 3 дополнительно запрещает изменение правил firewall — полезно, если хочешь гарантировать, что даже скомпрометированный root не отключит PF.
Ограничение: securelevel можно понизить только перезагрузкой в single-user mode. Это означает, что легитимное обслуживание (изменение immutable-файлов) тоже требует перезагрузки. Для VPS, где физический доступ к консоли ограничен, это нужно учитывать.
MAC Framework: Mandatory Access Control
MAC — pluggable framework для модулей принудительного контроля доступа. В отличие от DAC (стандартные UNIX-права, где владелец файла решает, кому дать доступ), MAC-политики enforced ядром и не могут быть переопределены пользователями, включая root.
MAC поддерживается в FreeBSD с версии 5.0 (TrustedBSD project). Фреймворк модульный: каждый модуль реализует свою политику, модули комбинируются.
Практически полезные модули
mac_portacl(4) — позволяет непривилегированным пользователям привязываться к привилегированным портам (<1024). Полезно для запуска web-сервера без root:
kldload mac_portacl
sysctl security.mac.portacl.rules=uid:80:tcp:80,uid:80:tcp:443
sysctl net.inet.ip.portrange.reservedhigh=0
Пользователь с UID 80 (www) может слушать порты 80 и 443 без root-привилегий.
mac_seeotheruids(4) — более гранулярная альтернатива security.bsd.see_other_uids. Сама политика включается отдельным sysctl security.mac.seeotheruids.enabled, а поверх неё задаются послабления: primarygroup_enabled разрешает видеть процессы участников той же первичной группы, а specificgid_enabled вместе с specificgid выводит перечисленные GID из-под политики:
kldload mac_seeotheruids
sysctl security.mac.seeotheruids.enabled=1
sysctl security.mac.seeotheruids.primarygroup_enabled=1
mac_bsdextended(4) — firewall для файловой системы. Позволяет создавать правила, ограничивающие доступ пользователей/групп к файлам по аналогии с правилами PF:
kldload mac_bsdextended
ugidfw add subject uid 1001 object uid 0 mode n # UID 1001 не может обращаться к файлам root
ugidfw list # показать правила
mac_biba(4) и mac_mls(4) — реализации классических моделей целостности (Biba) и конфиденциальности (MLS) с метками. Это territory enterprise/military и выходит за рамки типичного VPS.
Когда MAC нужен на VPS
Для типичного VPS — в большинстве случаев не нужен. Стандартных UNIX-прав + jails + securelevel достаточно. MAC оправдан, когда: нужно запустить сервис на привилегированном порту без root (mac_portacl); на многопользовательской системе нужна изоляция, выходящая за рамки стандартных прав; требуется compliance с конкретными стандартами безопасности (CIS Benchmark и подобные).
Аудит: отслеживание действий
Системный аудит (audit)
FreeBSD включает BSM (Basic Security Module) аудит из base system — запись действий пользователей и системных событий:
# /etc/rc.conf
auditd_enable="YES"
# Запустить
service auditd start
Конфигурация — /etc/security/audit_control:
dir:/var/audit
dist:off
flags:lo,aa,ad,fw,fc,fd,fm
minfree:5
naflags:lo,aa
policy:cnt,argv
filesz:2M
expire-after:30d
flags определяют, какие события записываются: lo (логин/логаут), aa (аутентификация), ad (административные действия), fw (запись в файлы), fc (создание файлов), fd (удаление), fm (изменение атрибутов).
Просмотр аудит-логов:
praudit /var/audit/current # читаемый формат текущего лога
auditreduce -u root /var/audit/ | praudit # все действия root
auditreduce -m AUE_OPEN_W /var/audit/ | praudit # все операции записи
Аудит — мощный инструмент для forensics, но генерирует значительный объём данных. На VPS с ограниченным диском стоит тщательно выбирать flags и настроить ротацию (filesz, expire-after).
Логирование и newsyslog
Стандартное логирование через syslogd(8) (base system). Ключевые логи:
/var/log/auth.log # аутентификация (SSH, su, sudo)
/var/log/messages # общие системные сообщения
/var/log/security # security-события
/var/log/pflog # PF firewall (бинарный, читается через tcpdump)
Ротация логов — newsyslog(8) (base system, аналог logrotate):
# /etc/newsyslog.conf
# logfile owner:group mode count size when flags
/var/log/auth.log root:wheel 600 12 1000 * JC
/var/log/messages root:wheel 644 5 1000 * JC
J — сжатие bzip2, C — создавать файл если не существует. Ротация по размеру (KB) или времени.
Мониторинг целостности файлов
mtree(8) (base system) — создаёт спецификацию файловой иерархии и проверяет изменения:
# Создать baseline
mtree -c -K sha256 -p /etc > /root/etc.mtree
# Проверить изменения
mtree -f /root/etc.mtree -p /etc
Показывает изменённые файлы, изменения прав, owner, размера, контрольных сумм. Baseline следует хранить в безопасном месте (на отдельном носителе или под schg-флагом при securelevel ≥ 1).
freebsd-update IDS — верификация установленных файлов base system против известных хэшей:
freebsd-update IDS
Оговорка из man-страницы: доверять этому как настоящей IDS нельзя — на скомпрометированной системе сам freebsd-update может врать, так что проверку имеет смысл гонять с заведомо чистого носителя. И это работает для системы, поставленной традиционными distribution sets; если base установлен пакетами (pkgbase, доступный начиная с 15.0), сверку контрольных сумм даёт pkg check -s.
GELI: шифрование дисков
FreeBSD включает GELI (base system) для полнодискового шифрования:
geli init -s 4096 -l 256 /dev/ada0p3
geli attach /dev/ada0p3
# Работа с /dev/ada0p3.eli как с обычным устройством
На VPS полнодисковое шифрование обычно бессмысленно (провайдер имеет доступ к RAM), но шифрование отдельных разделов с чувствительными данными (бэкапы, БД) может быть оправдано для compliance.
CIS Benchmark для FreeBSD
В 2024 году вышел CIS (Center for Internet Security) FreeBSD 14 Benchmark — первый формальный документ по hardening FreeBSD от CIS. Он покрывает: управление пользователями и группами, конфигурацию сервисов, файловые системы и права, сетевые настройки, аудит и логирование.
Документ полезен как чеклист для production-серверов и для compliance-сценариев. Доступен через FreeBSD Foundation.
Практический чеклист: hardening VPS за первый час
Минимальный набор действий для нового VPS, в порядке приоритета:
- Создать непривилегированного пользователя, добавить в группу wheel, настроить SSH-ключ
- Установить doas, настроить
permit persist :wheel - В sshd_config:
PermitRootLogin no,PasswordAuthentication no - Применить sysctl hardening (see_other_uids, ASLR, randompid, coredump)
- Включить PF с default deny + overload-таблицей для SSH
- Включить blocklistd с
UseBlocklist yesв sshd_config - Отключить неиспользуемые сервисы в rc.conf
syslogd_flags="-ss"— закрыть syslog от сети- Рассмотреть securelevel 1 после стабилизации конфигурации
Отличия от Linux-подхода к безопасности
Нет SELinux/AppArmor — вместо них MAC framework с модульной архитектурой. SELinux enforces type enforcement с метками; MAC framework во FreeBSD поддерживает аналогичные модели (Biba, MLS), но используется значительно реже на practice.
Нет fail2ban в base — вместо него blocklistd (API-based подход vs парсинг логов). Для более широкой защиты — sshguard из пакетов.
Файловые флаги (schg, sappnd) + securelevel — уникальная для BSD комбинация. В Linux ближайший аналог — chattr +i, но без securelevel-механизма для enforce.
Аудит (BSM) встроен в base system. В Linux нужен auditd из отдельного пакета.
doas как альтернатива sudo — проще, из OpenBSD, минимальная attack surface.
Источники
- FreeBSD Handbook, Chapter 16 "Security": docs.freebsd.org/en/books/handbook/security/
- FreeBSD Handbook, Chapter 19 "Mandatory Access Control": docs.freebsd.org/en/books/handbook/mac/
- CIS FreeBSD 14 Benchmark: freebsdfoundation.org/project/center-for-internet-security-cis-freebsd-14-benchmark/
security(7): man.freebsd.org/cgi/man.cgi?query=security&sektion=7blocklistd(8): man.freebsd.org/cgi/man.cgi?query=blocklistd&sektion=8- FreeBSD Handbook, Chapter 34 "Firewalls" (раздел Blocklistd): docs.freebsd.org/en/books/handbook/firewalls/
sshguard(8)иsshguard-setup(7): man.freebsd.org/cgi/man.cgi?query=sshguardmac(4): man.freebsd.org/cgi/man.cgi?query=mac&sektion=4audit(4): man.freebsd.org/cgi/man.cgi?query=audit&sektion=4chflags(1): man.freebsd.org/cgi/man.cgi?query=chflags&sektion=1mtree(8): man.freebsd.org/cgi/man.cgi?query=mtree&sektion=8
Связанные заметки
- FreeBSD — сеть — PF: синтаксис правил, таблицы, overload
- FreeBSD — sysctl и конфигурация ядра — securelevel и hardening через sysctl
- FreeBSD VPS: Honeypot — практическое применение описанных здесь мер
- sudo, doas и sudo-rs — повышение привилегий: механизм setuid и сравнение реализаций
- Linux — безопасность: hardening, SELinux/AppArmor — MAC в Linux, для сравнения с MAC-фреймворком FreeBSD
- FreeBSD — сводный cheatsheet — быстрая справка по security-командам
- SSH углублённо — клиентская сторона и механика конфигурации: ProxyJump, сертификаты,
Matchиrestrict - Linux — пользователи, группы, PAM и systemd-logind — то же в Linux: shadow против master.passwd, Linux-PAM против OpenPAM
Из библиотеки института уносят только знания. Читателей здесь не считают: посещение не регистрируется, отметок в издании не остаётся, счётчиков нет ни у одного издания фонда.
Издание пополняется и пересверяется. Текст доступен на условиях CC BY-SA 4.0 — унесённое можно передавать дальше на тех же условиях.