WireGuard на FreeBSD: пошаговая установка
Если вы привыкли поднимать 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.forwarding | sysctl net.inet.ip.forwarding |
| туннель есть, NAT не работает | нет правила nat в pf.conf или неверный ext_if | ifconfig, 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 ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →