FreeBSD на VDS — хороший выбор для администраторов, которым нужна предсказуемая базовая система, аккуратная документация, сильная сетевая подсистема и понятное разделение между «миром» ОС и сторонними пакетами. Но после первого входа сервер ещё не готов к боевой эксплуатации: нужно обновить базовую систему, настроить пакеты, привести в порядок SSH, включить NTP и запустить pf firewall так, чтобы случайно не отрезать себе доступ.
В этой инструкции пройдём практический минимум для нового FreeBSD VDS. Команды рассчитаны на FreeBSD RELEASE-ветки, например 13.x или 14.x. Если у вас STABLE, CURRENT или сильно кастомная сборка, логика останется похожей, но механизм обновления базовой системы может отличаться.
Главное правило первого часа на новом сервере: не включайте firewall и не перезапускайте SSH, пока не проверили конфигурацию и не оставили себе запасной путь через консоль VDS.
Что проверить сразу после первого входа
Обычно провайдер выдаёт root-доступ по SSH или временный пароль. Первым делом убедитесь, что вы действительно на нужной машине, видите версию ядра и пользовательского мира, сетевой интерфейс и маршрут по умолчанию. Для FreeBSD это особенно полезно: имя интерфейса зависит от виртуального драйвера и может быть vtnet0, em0, xn0 или другим.
freebsd-version -ku
uname -a
ifconfig
netstat -rn
sockstat -4 -l
sockstat -6 -l
Команда freebsd-version -ku показывает версии ядра и пользовательского мира. Если они отличаются после обновления, это не всегда авария: иногда нужно выполнить второй этап freebsd-update install после перезагрузки. sockstat помогает увидеть слушающие порты ещё до включения firewall.
Проверьте имя хоста. На маленьком сервере это кажется косметикой, но корректный hostname помогает в логах, мониторинге, почтовых уведомлениях и резервном копировании. В FreeBSD постоянные параметры удобно менять через sysrc, который аккуратно правит /etc/rc.conf.
hostname
sysrc hostname=vds01.example.local
service hostname restart
Если вы меняете hostname на публичное FQDN-имя, заранее убедитесь, что DNS-запись указывает на IP сервера. Для локального имени в примерах можно использовать домен из внутренней схемы именования.
Обновляем базовую систему через freebsd-update
В FreeBSD важно различать базовую систему и пакеты. Базовая система — это ядро, системные библиотеки, утилиты из base, OpenSSH, pf и многое другое. Сторонние приложения — Nginx, PostgreSQL, sudo, tmux, htop и прочие — ставятся через pkg. Поэтому обновления обычно идут в два этапа: сначала freebsd-update, затем pkg upgrade.
Для RELEASE-веток базовое обновление выглядит так:
freebsd-update fetch
freebsd-update install
Если были обновлены компоненты, требующие нового ядра, перезагрузитесь и выполните установку ещё раз:
reboot
freebsd-update install
После этого проверьте версии:
freebsd-version -ku
uname -r
Для перехода между минорными или мажорными версиями используется отдельный сценарий с ключом -r, например переход на конкретный RELEASE. Такой апгрейд лучше делать после снапшота VDS и чтения release notes: меняются ABI пакетов, драйверы, настройки сервисов и иногда синтаксис отдельных конфигураций.
freebsd-update -r 14.2-RELEASE upgrade
freebsd-update install
reboot
freebsd-update install
pkg upgrade
freebsd-update install
Последняя команда в этой цепочке нужна не всегда, но при крупных обновлениях FreeBSD часто просит выполнить несколько фаз установки. Не игнорируйте сообщения freebsd-update: они обычно прямо говорят, когда перезагружаться и когда запускать установку повторно.
Настраиваем pkg: репозиторий, обновление, аудит
pkg — основной менеджер бинарных пакетов FreeBSD. При первом запуске он может предложить bootstrap. На сервере это можно сделать явно:
env ASSUME_ALWAYS_YES=yes pkg bootstrap
pkg update
pkg upgrade
В FreeBSD есть две популярные ветки пакетов: quarterly и latest. Ветка quarterly консервативнее: меньше неожиданных изменений, удобнее для типового production-сервера. Ветка latest быстрее приносит новые версии, но требует внимательнее читать changelog приложений. Для веб-сервера, базы данных или панели управления я обычно начинаю с quarterly, а на latest перехожу только если есть понятная причина.
Проверить активный репозиторий можно так:
pkg -vv | grep -A 6 repositories
Если нужно явно задать ветку, создайте файл /usr/local/etc/pkg/repos/FreeBSD.conf. Директория может отсутствовать на чистой системе, её нужно создать:
mkdir -p /usr/local/etc/pkg/repos
edit /usr/local/etc/pkg/repos/FreeBSD.conf
Пример для quarterly:
FreeBSD: {
url: "pkg+https://pkg.FreeBSD.org/${ABI}/quarterly",
mirror_type: "srv",
signature_type: "fingerprints",
fingerprints: "/usr/share/keys/pkg",
enabled: yes
}
После смены ветки обновите индекс и синхронизируйте пакеты:
pkg update -f
pkg upgrade
Минимальный набор удобных утилит для администрирования FreeBSD VDS может выглядеть так:
pkg install sudo tmux vim-console curl ca_root_nss pftop
ca_root_nss нужен многим клиентам и языковым рантаймам для проверки TLS-сертификатов. tmux полезен при обновлениях: если SSH-сессия оборвётся, команда продолжит жить внутри терминального мультиплексора. pftop помогает наблюдать за состояниями pf.
Не забывайте про аудит уязвимых пакетов:
pkg audit -F
pkg version -vL=
pkg audit -F обновляет базу уязвимостей и проверяет установленные пакеты. pkg version -vL= показывает пакеты, которые отстают от репозитория. На production-сервере полезно выполнять эти проверки регулярно, но обновлять сервисы всё равно лучше в окно обслуживания или через заранее описанную процедуру отката.

Создаём обычного пользователя и готовим sudo
Работать постоянно под root неудобно и небезопасно. Создайте отдельного администратора, добавьте его в группу wheel, проверьте вход по SSH и только после этого ограничивайте root-доступ.
adduser
pw usermod admin -G wheel
id admin
Если используете sudo, разрешите группе wheel повышать привилегии через visudo. В файле sudoers обычно достаточно включить строку:
%wheel ALL=(ALL:ALL) ALL
В FreeBSD также есть лёгкая альтернатива — doas из пакета doas. Но в командах ниже будем считать, что используется привычный sudo, потому что он чаще встречается в смешанной инфраструктуре Linux и BSD.
SSH FreeBSD: ключи, запрет root и проверка без потери доступа
OpenSSH входит в базовую систему FreeBSD, поэтому отдельный пакет ставить не нужно. Сначала убедитесь, что служба включена в автозагрузку и работает:
sysrc sshd_enable=YES
service sshd status
Для ключевой авторизации создайте каталог .ssh у пользователя и положите публичный ключ в authorized_keys. Важно соблюсти права: OpenSSH намеренно откажется принимать ключи, если домашний каталог или файлы доступны на запись посторонним.
mkdir -p /home/admin/.ssh
edit /home/admin/.ssh/authorized_keys
chown -R admin:admin /home/admin/.ssh
chmod 700 /home/admin/.ssh
chmod 600 /home/admin/.ssh/authorized_keys
Теперь откройте новую SSH-сессию отдельным окном и проверьте вход пользователем admin. Старую root-сессию не закрывайте. Только после успешной проверки меняйте /etc/ssh/sshd_config.
Базовые параметры для публичного сервера:
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
AllowUsers admin
Параметр PermitRootLogin со значением no запрещает прямой вход root. PasswordAuthentication no отключает парольную авторизацию, а KbdInteractiveAuthentication no закрывает интерактивные схемы входа, которые на некоторых конфигурациях могут оставлять парольный путь. AllowUsers дополнительно ограничивает список пользователей, которым вообще разрешён SSH-доступ.
Перед применением проверьте синтаксис:
sshd -t
service sshd reload
Если reload в вашей версии или конфигурации не сработал, используйте перезапуск, но только при открытой резервной консоли:
service sshd restart
Посмотреть итоговые значения, которые видит демон SSH, можно через sshd -T:
sshd -T | grep permitrootlogin
sshd -T | grep passwordauthentication
sshd -T | grep kbdinteractiveauthentication
Смену порта SSH я не считаю полноценной защитой, но иногда это снижает шум в логах. Если меняете Port, сначала добавьте новый порт в firewall, перезапустите SSH, проверьте вход на новом порту, и только потом закрывайте старый. Не делайте все эти действия одной командой.
NTP: синхронизация времени для логов, TLS и пакетов
Точное время на VDS важно не только для красоты в логах. TLS-сертификаты, подписи пакетов, cron-задачи, репликация баз данных и расследование инцидентов завязаны на часы. Даже если гипервизор отдаёт гостевой системе корректное время, NTP лучше включить явно.
В FreeBSD штатно доступен ntpd. Для обычного сервера достаточно включить автозапуск и разрешить быструю синхронизацию при старте:
sysrc ntpd_enable=YES
sysrc ntpd_sync_on_start=YES
service ntpd start
Проверка состояния:
ntpq -pn
date
В выводе ntpq -pn не стоит ждать идеальной картины сразу после запуска: демону нужно время, чтобы выбрать источник и стабилизировать смещение. Если сервер находится за строгим firewall, убедитесь, что исходящий UDP/123 не заблокирован. Входящий NTP для обычного VDS открывать не нужно, если вы не строите собственный сервер времени для внутренней сети.
Если в вашей инфраструктуре уже принят chrony, его можно поставить из пакетов, но не запускайте одновременно несколько NTP-демонов. Выберите один механизм и закрепите это в документации сервера.
pf firewall: безопасный старт на VDS
pf — штатный пакетный фильтр FreeBSD. Он мощный, лаконичный и хорошо подходит для VDS: можно закрыть входящий мусор, оставить SSH, HTTP/HTTPS, ICMP для диагностики и не мешать исходящим соединениям сервера. Главная опасность при первом включении — ошибиться в имени интерфейса или забыть разрешить текущий SSH-порт.
Сначала найдите внешний интерфейс:
ifconfig
netstat -rn
В примере ниже используем vtnet0. Если у вас em0, xn0 или другое имя, замените значение переменной ext_if. Перед стартом pf держите открытой консоль VDS или хотя бы вторую SSH-сессию.
Минимальный /etc/pf.conf для сервера только с SSH:
ext_if = "vtnet0"
ssh_port = "22"
set skip on lo0
scrub in all
antispoof quick for $ext_if
block return in log all
pass out quick all keep state
pass in on $ext_if inet proto icmp all icmp-type echoreq keep state
pass in on $ext_if inet6 proto ipv6-icmp all keep state
pass in on $ext_if proto tcp to ($ext_if) port $ssh_port flags S/SA keep state
Если на этом же FreeBSD VDS будет веб-сервер, добавьте порты 80 и 443:
ext_if = "vtnet0"
ssh_port = "22"
web_ports = "{ 80, 443 }"
set skip on lo0
scrub in all
antispoof quick for $ext_if
block return in log all
pass out quick all keep state
pass in on $ext_if inet proto icmp all icmp-type echoreq keep state
pass in on $ext_if inet6 proto ipv6-icmp all keep state
pass in on $ext_if proto tcp to ($ext_if) port $ssh_port flags S/SA keep state
pass in on $ext_if proto tcp to ($ext_if) port $web_ports flags S/SA keep state
Проверьте синтаксис до включения:
pfctl -nf /etc/pf.conf
Если ошибок нет, включите автозагрузку и запустите pf:
sysrc pf_enable=YES
sysrc pflog_enable=YES
service pflog start
service pf start
Проверьте активные правила и состояния:
pfctl -sr
pfctl -si
pfctl -ss
Логи pf идут в интерфейс pflog0. Для быстрой диагностики удобно использовать tcpdump:
tcpdump -n -e -ttt -i pflog0
Если вы добавили pftop, можно посмотреть состояния в интерактивном виде:
pftop
Не усложняйте первый firewall без необходимости. На старте достаточно политики «входящее закрыто, нужные сервисы открыты, исходящее разрешено». Ограничения исходящих соединений, таблицы адресов, rate limit и защита от брутфорса полезны, но их лучше внедрять после того, как сервер уже наблюдается, резервируется и имеет понятный runbook на случай блокировки доступа.
Если параллельно администрируете Linux-серверы, полезно держать в голове различия между pf, iptables и nftables. Например, в статье про Docker, iptables и nftables разобраны типовые ловушки Linux-firewall, которые часто путают с BSD-подходом.
IPv6 и ICMP: не ломайте диагностику
На VDS часто есть IPv6, и его нельзя считать «неиспользуемым», если адрес уже назначен интерфейсу. Сервис может слушать на ::, DNS может иметь AAAA-запись, а клиенты будут пытаться подключаться по IPv6. Поэтому firewall должен явно учитывать обе семьи адресов.
Для IPv4 мы разрешили echo request, чтобы работал обычный ping. Для IPv6 важнее не только ping: ICMPv6 нужен для обнаружения соседей, Path MTU Discovery и корректной работы сети. Слишком жёсткая блокировка ICMPv6 приводит к странным таймаутам HTTPS, зависающим загрузкам и трудной диагностике.
Проверьте адреса и маршруты:
ifconfig
ping -c 3 127.0.0.1
ping6 -c 3 ::1
Проверку внешней IPv6-связности делайте только если у сервера действительно есть глобальный IPv6-адрес и маршрут. Если IPv6 не используется, лучше отключать или не публиковать его осознанно, а не оставлять «как-нибудь потом».

Автозагрузка сервисов и порядок запуска
FreeBSD хранит большинство флагов автозагрузки в /etc/rc.conf. Команда sysrc уменьшает риск опечатки и показывает итоговое значение. Для нашего базового набора стоит проверить такие параметры:
sysrc -a | grep sshd_enable
sysrc -a | grep ntpd_enable
sysrc -a | grep pf_enable
sysrc -a | grep pflog_enable
Итогово на сервере обычно должны быть включены:
sshd_enable="YES"
ntpd_enable="YES"
ntpd_sync_on_start="YES"
pf_enable="YES"
pflog_enable="YES"
После настройки полезно сделать контролируемую перезагрузку и убедиться, что сервер возвращается в сеть без ручных действий:
reboot
После входа проверьте:
service sshd status
service ntpd status
service pf status
pfctl -sr
ntpq -pn
Если после перезагрузки SSH недоступен, но консоль VDS работает, смотрите /var/log/auth.log, состояние sshd, правила pfctl -sr и актуальный IP-адрес на интерфейсе. Не начинайте с хаотичного отключения всех служб: сначала подтвердите, где именно разрыв — сеть, firewall, SSH или авторизация.
Базовая гигиена после настройки
Когда SSH, pkg, freebsd-update, NTP и firewall уже работают, стоит закрыть несколько административных хвостов. Проверьте, какие сервисы слушают сеть, и удалите лишние пакеты. На чистом FreeBSD VDS обычно не должно быть неожиданных публичных портов.
sockstat -4 -l
sockstat -6 -l
pkg autoremove
pkg clean
Посмотрите системные логи:
tail -n 100 /var/log/messages
tail -n 100 /var/log/auth.log
Для регулярного обслуживания заведите простой порядок: сначала снапшот или резервная копия важных данных, затем freebsd-update fetch install, затем pkg audit -F и pkg upgrade, затем проверка сервисов. Если сервер обслуживает сайт или базу данных, добавьте к этому проверку приложения, HTTP-коды, логи ошибок и метрики.
Отдельно проверьте права на домашние каталоги администраторов и SSH-ключи. Типичная причина ошибки Permission denied (publickey) — слишком широкие права на .ssh или файл authorized_keys.
ls -ld /home/admin
ls -ld /home/admin/.ssh
ls -l /home/admin/.ssh/authorized_keys
Нормальная отправная точка: домашний каталог не доступен на запись группе и остальным, .ssh имеет 700, authorized_keys имеет 600, владелец — сам пользователь.
Короткий чек-лист для нового FreeBSD VDS
- Проверили версию FreeBSD, имя интерфейса, маршрут по умолчанию и слушающие порты.
- Обновили базовую систему через
freebsd-updateи перезагрузились, если это требовалось. - Инициализировали
pkg, выбрали ветку пакетов и выполнилиpkg upgrade. - Создали отдельного администратора, настроили ключи и проверили вход новой SSH-сессией.
- Отключили root-вход и парольную авторизацию в SSH только после проверки ключей.
- Включили
ntpdи убедились, что время синхронизируется. - Подготовили
/etc/pf.conf, проверили его черезpfctl -nfи только потом включилиpf. - Проверили доступ после перезагрузки, логи SSH, состояние firewall и список открытых портов.
Такой базовый профиль не делает сервер «неуязвимым», но убирает самые частые проблемы первого запуска: устаревшую базовую систему, непроверенные пакеты, парольный SSH, рассинхрон времени и полностью открытый периметр. Дальше уже можно ставить веб-сервер, базу данных, мониторинг, бэкапы и прикладные сервисы — на более спокойном и контролируемом фундаменте.


