WireGuard/FreeBSD установка и настройка.

На написание этой статьи меня толкнул комментарий оставленный под другой статьей. И вот я решил проверить как сейчас обстоят дела с WireGuard на FreeBSD. Особенно после большой шумихи с портированием этого продукта на BSD. И так. Имеем:

# uname -a
FreeBSD wireguard.yakunin.dev 13.0-RELEASE-p11 FreeBSD 13.0-RELEASE
p11builder.daemonology.net:/usr/obj/usr/src/amd64.amd64/sys/GENERIC  amd64

Мы не будем собирать ядро в рамках этой статьи, все модули которые нам понадобятся будем подгружать динамически. А для того что бы все работало, нам потребуется NAT и собственно сам драйвер ядра if_wg.ko. Немного лирического отступления, всегда перед началом развертывания чего-то, лучше сразу обновить дерево портов и саму систему, благо для этого все есть.

# freebsd-update fetch && freebsd-update install

Looking up update.FreeBSD.org mirrors... 2 mirrors found.
Fetching metadata signature for 13.0-RELEASE from update1.freebsd.org... done.
Fetching metadata index... done.
Inspecting system... done.
Preparing to download files... done.

# portsnap fetch && portsnap extract

Looking up portsnap.FreeBSD.org mirrors... 4 mirrors found.
Fetching snapshot tag from ipv4.aws.portsnap.freebsd.org... done.
Fetching snapshot metadata... done.
Updating from Tue Apr 26 11:12:56 MSK 2022 to Tue Apr 26 14:10:33 MSK 2022.
Fetching 5 metadata patches... done.
Applying metadata patches... done.
Fetching 0 metadata files... done.

После этого приступим непосредственно к установке WireGuard. Ищем его среди портов, конфигурируем и ставим.

# whereis wireguard
wireguard: /usr/ports/net/wireguard

# cd /usr/ports/net/wireguard
# make config-recursive
# make install clean

После установки вдумчиво читаем посланное автором порта post-install сообщение:

For FreeBSD < 12.1 only the userland implementation wireguard-go is
available.

For FreeBSD >= 12.1 we default to use the kernel module if_wg(4).

If you experience problems with it you can switch back to wireguard-go
by removing net/wireguard-kmod and making sure net/wireguard-go is
installed.
The userland tools wg-quick(8) and wg(8) try to use kernel support if 
the kernel module is available and otherwise fall back to wireguard-go
automatically. Config files are fully compatible.

Все вроде бы понятно, нам нужен модуль ядра. Ок, идем на официальный сайт и покопавшись немного в документации находим git с последними изменениями. https://github.com/WireGuard/wireguard-freebsd читаем инструкцию и видим что все это надо собрать, не проблема, собираем:

# cd ~
# git clone https://git.zx2c4.com/wireguard-freebsd
# make -C wireguard-freebsd/src
# make -C wireguard-freebsd/src load install

После чего идем в wireguard-freebsd/src и видим там заветный if_wg.ko, он-то нам и нужен. Подкладываем его в директорию с модулями и загружаем.

# cp ~/wireguard-freebsd/src/if_wg.ko /boot/modules/if_wg.ko
# cd /boot/modules
# kldload if_wg.ko
# kldstat | grep if_wg.ko

9    1 0xffffffff82328000    35548 if_wg.ko

Отлично, модуль у нас есть. Теперь нам надо разобраться с NAT. Перед тем как запускать сервер. Хорошо, для этого так же, нам понадобятся модули ipfw. Редактируем файл loader.conf и добавляем в него следующие строчки:

# nano /boot/loader.conf

ipfw_load="YES"
ipdivert_load="YES"
ipfw_nat_load="YES"
libalias_load="YES"

Теперь при старте системы мы подключим все необходимое, но как только загрузятся эти модули мы уже не получим доступ к системе, так как политика по умолчанию у ipfw это deny all. Значит переходим созданию правил фаервола, нам для этого понадобится имя внешнего сетевого интерфейса, внешний ip адрес, и внутренняя сеть которую мы будем раздавать клиентам и которую и будем NAT-тировать. Создаем rc.firewall

# :>/etc/rc.firewall
# chmod a+x /etc/rc.firewall

Далее заносим туда следующее:

#!/bin/sh -

fwcmd="/sbin/ipfw -q"

# Замените на свой внешний интерфейс.
if_ext="vmx0"

# Замените на свой внешний IP
ext_ip="8.8.8.8"

# Сюда мы впишем значение которое у нас будет хранить сервер.
# По умолчанию значение такое же как описано тут.
vpn_net="10.252.1.0/24"

# Сбрасываем все правила при перезапуске
${fwcmd} -f flush

# Разрешаем трафик на петлевом интерфейсе
${fwcmd} add allow all from any to any via lo

# Разрешаем подключаться по SSH
${fwcmd} add allow tcp from any to me 22 via ${if_ext}

# Разрешаем подключаться на порт WireGuard.
${fwcmd} add allow udp from any to me 51820 via ${if_ext}

# Разрешаем ICMP запросы
${fwcmd} add allow icmp from any to me via ${if_ext} icmptype 3,8,12

# Разрешаем серверу выходить в мир
${fwcmd} add allow all from me to any out keep-state

# Включаем NAT
${fwcmd} nat 1 config if ${if_ext} reset deny_in same_ports unreg_only
${fwcmd} add nat 1 all from ${vpn_net} to any via ${if_ext}
${fwcmd} add nat 1 all from any to ${ext_ip} via ${if_ext}

# Разрешаем трафик на интерфейсе WireGuard
${fwcmd} add allow all from any to any via wg0

Далее внесем в все необходимые нам сервисы в автозагрузку и сконфигурируем интерфейс, добавим эти строки в конец файла /etc/rc.conf

# nano /etc/rc.conf

gateway_enable="YES"

wireguard_enable="YES"
wireguard_interfaces="wg0"

firewall_enable="YES"
firewall_script="/etc/rc.firewall"

Теперь все выглядит не плохо, в целом можно было бы создавать файл конфигурации сервера и запускать, но мне лично стало интересно есть ли какие-то UI для управления WireGuard и немного покопавшись в сети, нашел прекрасный UI написанный на Go. И так, идем по адресу: https://github.com/ngoduykhanh/wireguard-ui/releases/ и забираем оттуда последний релиз под нашу архитектуру. На момент написания это wireguard-ui-v0.3.7-freebsd-amd64.tar.gz, отлично, качаем.

# cd ~
# wget https://github.com/ngoduykhanh/wireguard-ui/releases/download/v0.3.7/wireguard-ui-v0.3.7-freebsd-amd64.tar.gz
# tar -xvf wireguard-ui-v0.3.7-freebsd-amd64.tar.gz
# mkdir /usr/local/etc/wireguard-ui && /usr/local/etc/wireguard
# mv wireguard-ui /usr/local/etc/wireguard-ui

Почитав документацию на странице разработчика и помощь по бинарному файлу, по умолчанию он слушает все интерфейсы, в целом это не плохо, но так как мы за безопасность и прочее, то по хорошему нужно запускать ui на 127.0.0.1 и далее поднять nginx сделать проксирование и добавить сертификаты к веб интерфейсу. Но в этой статье мы не будем этого касаться, думаю вы с этим справитесь сами. И так, запускаем сам сервис:

# cd /usr/local/etc/wireguard-ui
# ./wireguard-ui -bind-address 'ваш_внешний_ip:5000'

Wireguard UI
App Version	: v0.3.7
Git Commit	: ad4ca4d9bb344236a2793fee54ec24cf07d6cd8c
Git Ref		: refs/tags/v0.3.7
Build Time	: 04-26-2022 14:03:01
Git Repo	: https://github.com/ngoduykhanh/wireguard-ui
Authentication	: true
Bind address	: 8.8.8.8:5000
Email from	: 
Email from name	: WireGuard UI
⇨ http server started on 8.8.8.8:5000

В папке /usr/local/etc/wireguard-ui у вас появиться папочка db в ней будут лежать все настройки, в том числе файл db/server/users.json в котором хранится имя пользователя и пароль для входа в веб интерфейс. Сменим сразу на что-то понадежнее. Надеюсь вы не будете хранить пароль в открытом виде ;). После смены пароля перезапускаем сервис веб интерфейса и заходим по логину и паролю которые мы внесли. Заходим по ссылке http://ваш_внешний_ip:5000 и видим примерно следующее:

Заходим внутрь и видим панель, слева выбираем вкладку: Global Settings, все что нам необходимо заполнить правильно поля и путь до файла конфигурации, в нашем случае это /usr/local/etc/wireguard/wg0.conf

Меняем Endpoint Address на ваш внешний адрес, можете по вкусу поменять DNS, обязательно убедитесь что пусть до файла wg0.conf существует. После чего, в правом углу необходимо нажать на кнопку Apply Config.

При этом в каталоге /usr/local/etc/wireguard у вас появиться файл wg0.conf с примерно следующим содержанием:

# cat /usr/local/etc/wireguard/wg0.conf

# This file was generated using wireguard-ui (https://github.com/ngoduykhanh/wireguard-ui)
# Please don't modify it manually, otherwise your change might get replaced.

# Address updated at:     2022-04-26 12:39:11.55663896 +0000 UTC
# Private Key updated at: 2022-04-26 12:29:53.188045093 +0000 UTC
[Interface]
Address = 10.252.1.0/24
ListenPort = 51820
PrivateKey = тут_будет_приватный_ключ
MTU = 1450
PostUp = 
PostDown =

Отлично, теперь создадим клиента и приготовимся ко взлету. В веб интерфейсе идем во вкладку Wireguard Clients слева и в верхнем правом углу нажимаем New Client. Я рекомендую ничего не менять кроме пустых полей. То есть имя клиента и его электронного адреса.

После создания конфигурацию можно скачать как файлом так и по QR коду, что удобно при закачке на мобильные устройства. Не забывайте после всех изменений в веб интерфейсе, нажимать на кнопку Apply Config, что бы сервер внес изменения в файл. Теперь все что необходимо это перезапустить сервер и подключиться уже клиентом. Так и делаем. Я использую клиент с официального сайта. После того как сервер перезагрузился, заходим и проверяем состояние WireGuard.

# wg show

interface: wg0
  public key: 6c9f9kBstbXPdFkGASMx/7rHN5dzIqTeYPj0dXlDsSo=
  private key: (hidden)
  listening port: 51820

peer: QLgixbD/DvyCKDGas+ZiEuBU9GOHBTY9l6qga/+wy1I=
  preshared key: (hidden)
  allowed ips: 10.252.1.1/32

# ifconfig wg0

wg0: flags=80c1<UP,RUNNING,NOARP,MULTICAST> metric 0 mtu 1450
	options=80000<LINKSTATE>
	inet 10.252.1.0 netmask 0xffffff00
	groups: wg
	nd6 options=109<PERFORMNUD,IFDISABLED,NO_DAD>

Отлично. Можно подключаться клиентом:

Теперь можно проверить и ipfw и соединение с WireGuard

# ipfw show

00100    0       0 allow ip from any to any via lo
00200  296   20835 allow tcp from any to me 22,5000 via vmx0
00300 1481  355732 allow udp from any to me 51820 via vmx0
00400  142   28064 allow icmp from any to me via vmx0 icmptypes 3,8,12
00500 2631 1853027 allow ip from me to any out keep-state :default
00600 1393  245861 nat 1 ip from 10.252.1.0/24 to any via vmx0
00700 2401 1607069 nat 1 ip from any to ваш_внешний_ip via vmx0
00800 3809 1860534 allow ip from any to any via wg0
65535 6206 2169519 deny ip from any to any

# wg show

interface: wg0
  public key: 6c9f9kBstbXPdFkGASMx/7rHN5dzIqTeYPj0dXlDsSo=
  private key: (hidden)
  listening port: 51820

peer: QK6Gv6kSLafi4NP8zmTrVHz32qtFvNu2zoF8CsO33iA=
  preshared key: (hidden)
  endpoint: удаленный_адрес_клиента:59895
  allowed ips: 10.252.1.1/32
  latest handshake: 45 seconds ago
  transfer: 244.71 KiB received, 2.87 MiB sent

Вот собственно и все. Пакеты ходят все хорошо. Есть ещё один момент, каждый раз когда вы применяете конфигурацию через веб интерфейс или создаете нового клиента, вам необходимо обязательно нажимать на кнопку Apply Config и по мимо того, перезапускать сервер WireGuard. service wireguard restart иначе конфигурация не будет применена, я нарочно не стал затрагивать эту тему, на сайте разработчика написано как сделать скрипт который будет исполняться и перезапускать сервер самостоятельно по кнопе Apply Config. Маленькая подсказка: https://github.com/ngoduykhanh/wireguard-ui смотрим пункт openrc.

Если что-то пошло не так, смотрим логи, как в клиенте так и на сервере. 😉

4 комментария к “WireGuard/FreeBSD установка и настройка.

  1. Приветствую, давно работает WG решил прикрутить интерфейс графический, а вот с ним проблемы и думаю с preshared_key конкретно, ибо помудревав с ключиками руками все работает, а вот автоматом нет. у клиента есть ключ preshared_key а вот у сервера нет. у вас как то про этот ключ не упоминается, как то его можно отключить? Конфиг у wireguard-ui где то есть? куда его положить чтоб он читался, куда только не ложил его, ни в какую не читает, можно только запустить бинарник с параметрами. Извините за беспокойство, если что.

  2. Приветствую вас! После запуска wireguard-ui, у вас в той папке откуда вы его запускаете появиться папка db, об этом написано в статье, там хранится все, в том числе и ключи. Смотрите, этот сервис сам создает все конфигурационные файлы для работы, вам ничего ненужно создавать руками. Все что надо прописать пару строк в веб интерфейсе, таких как адрес сервера и т.д., все ключи и прочее создается автоматически, не забывайте только нажимать на кнопку apply config и после этого вам необходимо перезапустить сам wireguard через wg-quick down wg0 && wg-quick up wg0.

  3. После выполнения данной команды./wireguard-ui -bind-address ‘ваш_внешний_ip:5000’ появляется ошибка {«time»:»2023-01-11T23:02:21.861691568+02:00″,»level»:»FATAL»,»prefix»:»-«,»file»:»main.go»,»line»:»201″,»message»:»Cannot create server config: %!(EXTRA *fs.PathError=open /etc/wireguard/wg0.conf: no such file or directory)»}

  4. Так у вас в ошибке все написано, у вас нет каталога /etc/wireguard, внимательнее читайте статью, если все делать так как написано и именно с тем же версиями, все будет работать! 🙂

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *