MAATRIX / Блог / WireGuard на FreeBSD: пошаговая установка

WireGuard на FreeBSD: пошаговая установка

MAATRIX

Если вы привыкли поднимать WireGuard на Linux, переход на FreeBSD может слегка озадачить: другой пакетный менеджер, другой firewall, другая логика загрузки модулей ядра. Хорошая новость в том, что сам WireGuard на FreeBSD работает не хуже, а местами даже стабильнее — драйвер if_wg встроен прямо в ядро, без userspace-прослойки. Ниже — рабочая пошаговая установка сервера, от чистой системы до поднятого туннеля с клиентом.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Почему WireGuard на FreeBSD — это нативный модуль ядра

На Linux WireGuard либо давно живёт в ядре, либо (на старых системах) собирается как отдельный модуль через DKMS. На FreeBSD ситуация иная: реализация if_wg(4) разрабатывалась отдельно от Linux-варианта и была интегрирована в базовую систему начиная с FreeBSD 13. Это значит, что на актуальных релизах (13.x и 14.x) модуль либо уже встроен в GENERIC-ядро, либо доступен как if_wg.ko, который подгружается одной командой — пересобирать ядро не нужно.

Практическая разница с userspace-реализациями (wireguard-go и т.п.) в том, что пакеты обрабатываются в контексте ядра, без лишних переключений контекста между kernel- и user-space. Для VPS с ограниченным CPU это ощутимо снижает накладные расходы, особенно при большом числе одновременных подключений.

Инструменты управления (wg, wg-quick) при этом остаются такими же userspace-утилитами, что и на Linux — устанавливаются отдельным портом/пакетом и работают с тем же форматом конфигов Interface/Peer. Если вы уже настраивали WireGuard на Ubuntu или другой Linux-дистрибутив, синтаксис конфигурации будет знаком — отличаются в основном системные детали: загрузка модуля, firewall и rc-скрипты.

Подготовка сервера

Возьмите свежий VPS с FreeBSD 13.x или 14.x — свежий релиз даёт актуальную версию if_wg и меньше шансов упереться в баги ранних портов. Первым делом обновите систему и коллекцию пакетов:

freebsd-update fetch install
pkg update && pkg upgrade -y

Если pkg ещё не инициализирован (на минимальных образах бывает), выполните pkg bootstrap и подтвердите установку.

Проверьте версию ядра и наличие модуля:

uname -a
kldstat | grep if_wg

Если строки if_wg в выводе kldstat нет — не страшно, модуль просто ещё не загружен, это нормально для свежей системы.

Арендуйте сервер под свои задачи!

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Установка wireguard-tools и загрузка модуля if_wg

Ставим userspace-утилиты из пакетов:

pkg install wireguard-tools

Пакет принесёт бинарники wg и wg-quick, а также man-страницы. Модуль ядра if_wg в большинстве сборок FreeBSD 13+ идёт в составе базовой системы, поэтому отдельно ставить его пакетом обычно не нужно — достаточно загрузить:

kldload if_wg

Проверить, что модуль встал:

kldstat | grep if_wg

Чтобы модуль подхватывался при каждой перезагрузке, добавьте строку в /boot/loader.conf:

if_wg_load="YES"

Если при kldload система ругается, что модуль не найден — значит используемое ядро собрано без опции WITHOUT_MODULES для этого драйвера или это очень старый релиз без if_wg вообще. В таком случае проще взять более свежий образ FreeBSD, чем пересобирать ядро вручную.

Генерация ключей и конфигурация сервера

Создайте директорию для конфигов (обычно /usr/local/etc/wireguard, её создаёт пакет, но на всякий случай проверьте права):

mkdir -p /usr/local/etc/wireguard
chmod 700 /usr/local/etc/wireguard
cd /usr/local/etc/wireguard

Сгенерируйте пару ключей сервера:

wg genkey | tee server_private.key | wg pubkey > server_public.key
chmod 600 server_private.key

Создайте конфиг wg0.conf:

[Interface]
Address = 10.66.66.1/24
ListenPort = 51820
PrivateKey = <содержимое server_private.key>
PostUp   = pfctl -e; pfctl -f /etc/pf.conf
PostDown = pfctl -d

[Peer]
# клиент добавится ниже

Формат идентичен Linux-конфигу — секции Interface и Peer, те же ключи. Разница только в PostUp/PostDown: на FreeBSD для NAT и форвардинга обычно используется pf, а не iptables/nftables.

Настройка клиента и обмен ключами

На стороне клиента (это может быть другой FreeBSD-сервер, Linux-машина, роутер или десктоп) сгенерируйте свою пару ключей тем же способом:

wg genkey | tee client_private.key | wg pubkey > client_public.key

Добавьте peer-секцию клиента в серверный wg0.conf:

[Peer]
PublicKey  = <client_public.key>
AllowedIPs = 10.66.66.2/32

А в конфиге клиента укажите сервер:

[Interface]
PrivateKey = <client_private.key>
Address    = 10.66.66.2/24

[Peer]
PublicKey  = <server_public.key>
Endpoint   = <IP-сервера>:51820
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25

PersistentKeepalive важен, если клиент сидит за NAT — без него туннель может «засыпать», и сервер перестаёт видеть входящий трафик, пока клиент сам не отправит пакет. Если клиенту нужен полный туннель (весь трафик через VPN), оставляйте AllowedIPs = 0.0.0.0/0, ::/0; если нужен только доступ к конкретной сети — сузьте маску до нужных подсетей.

Автозапуск, форвардинг и NAT через pf

Включите форвардинг пакетов — без этого сервер не сможет маршрутизировать трафик клиентов дальше в интернет. Добавьте в /etc/sysctl.conf:

net.inet.ip.forwarding=1

И примените сразу, не дожидаясь перезагрузки:

sysctl net.inet.ip.forwarding=1

Настройте NAT в /etc/pf.conf (замените vtnet0 на реальное имя внешнего интерфейса — узнать его можно через ifconfig):

ext_if = "vtnet0"
wg_net = "10.66.66.0/24"

nat on $ext_if from $wg_net to any -> ($ext_if)

Включите pf в автозагрузку и запустите:

sysrc pf_enable="YES"
service pf start

Для автозапуска самого туннеля пропишите в /etc/rc.conf:

wireguard_enable="YES"
wireguard_interfaces="wg0"

и включите сервис:

service wireguard start

Если в вашей версии порта rc-скрипта wireguard нет (бывает в старых сборках пакета), поднимайте туннель напрямую через wg-quick:

wg-quick up wg0

и добавьте эту команду в /etc/rc.local для автозапуска — рабочий, хоть и менее «нативный» способ.

Диагностика и типичные проблемы

Первым делом смотрите статус интерфейса:

wg show wg0
ifconfig wg0

Если в выводе wg show у peer’а нет latest handshake — туннель не установился. Частые причины на FreeBSD:

СимптомВероятная причинаЧто проверить
if_wg не грузитсястарое ядро/образuname -r, попробовать другой релиз
handshake не проходитзакрыт порт 51820/udp во внешнем firewallправила pf или security group у провайдера
туннель есть, интернета нетне включён net.inet.ip.forwardingsysctl net.inet.ip.forwarding
туннель есть, NAT не работаетнет правила nat в pf.conf или неверный ext_ififconfig, pfctl -s nat
после ребута туннель не поднимаетсяне прописан автозапускrc.conf, /boot/loader.conf

Если конфиг выглядит корректным, а ключи вы точно скопировали без пробелов и переносов строк — проверьте синхронизацию времени (ntpd/chronyd): WireGuard использует криптографию с привязкой ко времени, и сильно рассинхронизированные часы иногда мешают handshake, хотя это скорее редкий крайний случай, чем частая причина. С похожими симптомами на Linux-серверах мы разбирались отдельно в статье про частые ошибки WireGuard на сервере — логика диагностики там во многом совпадает.

Арендуйте сервер под свои задачи!

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Нужно ли пересобирать ядро FreeBSD для WireGuard?

Нет, начиная с FreeBSD 13 драйвер if_wg доступен как модуль, который просто подгружается через kldload if_wg или автозагрузку в /boot/loader.conf. Пересборка ядра не требуется.

Чем отличается wg-quick на FreeBSD от Linux-версии?

Логика та же — единый конфиг Interface/Peer и одна команда для поднятия интерфейса. Различия в основном в системных хуках: на FreeBSD PostUp/PostDown обычно управляют pf, а не iptables, и автозапуск идёт через rc.conf, а не systemd.

Можно ли использовать jail с WireGuard на FreeBSD?

Технически да, но проще и надёжнее поднимать WireGuard на хостовой системе, а трафик из джейлов пускать через неё — вариант с интерфейсом внутри jail требует дополнительной настройки VNET и обычно не нужен для типовой задачи VPN-сервера.

Что делать, если пакет wireguard-tools не находится через pkg?

Проверьте, что репозиторий пакетов доступен (pkg update без ошибок) и что вы используете актуальный релиз FreeBSD — для совсем старых веток пакет мог быть исключён из репозитория в пользу встроенного варианта.

Безопасно ли открывать UDP-порт WireGuard наружу?

Да, это штатный режим работы протокола: без валидного ключа сервер не отвечает на пакеты вообще, что затрудняет сканирование порта. Тем не менее стоит закрыть все остальные ненужные порты через pf и использовать нестандартный ListenPort, если хотите снизить фоновый шум от automated-сканеров.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →