Архив заметок

VPN на базе WireGuard и FreeBSD

Просмотров: 7784Комментарии: 0
FreeBSD

Небольшая зарисовка сети

У меня есть VPS для экспериментирования этого хозяйства. Цель: проверка возможности доступа с домашнего компа и/или телефона на интернет ресурсы через зашифрованный VPN-туннель.

% uname -srm
FreeBSD 12.0-RELEASE-p9 amd64

Кстати! Сразу оговорюсь, что мое небольшое руководство основано на этом источнике. Камрад описал похожую схему, а так же вариант с объединением двух сетей именно для ОС FreeBSD.

Посмотрим, насколько древние порты:

root@proxy:/usr/ports # svnlite info
Path: .
Working Copy Root Path: /usr/ports
URL: https://svn.freebsd.org/ports/head
Relative URL: ^/head
Repository Root: https://svn.freebsd.org/ports
Repository UUID: 35697150-7ecd-e111-bb59-0022644237b5
Revision: 511883
Node Kind: directory
Schedule: normal
Last Changed Author: amdmi3
Last Changed Rev: 511883
Last Changed Date: 2019-09-12 15:50:55 +0200 (Thu, 12 Sep 2019)

На всякий случай обновим:

root@proxy:/usr/ports # svnlite up && make fetchindex

Найдем и установим wireguard и libqrencode. Последняя прога на основе конфига для android устройства или iphone генерирует QR код в консоли, дабы было удобнее добавлять настройки в телефон с помощью камеры. Об этом чуть позже.

root@proxy:/usr/ports # whereis wireguard libqrencode
wireguard: /usr/ports/net/wireguard
libqrencode: /usr/ports/graphics/libqrencode
root@proxy:/usr/ports # portmaster -ad net/wireguard graphics/libqrencode

Установщик создаст пустую папку /usr/local/etc/wireguard. Надо создать несколько конфигурационных файлов, сгенерировать ключи и создать сетевой интерфейс. Обо всем по порядку.

Вот как делается это в Linux:

walkthrough.gif

Во FreeBSD пойдем следующими шагами. В папке wireguard создаем ключи:

root@proxy:/usr/local/etc/wireguard # umask 077
root@proxy:/usr/local/etc/wireguard # wg genkey > freebsd.private
root@proxy:/usr/local/etc/wireguard # wg pubkey < freebsd.private > freebsd.public
root@proxy:/usr/local/etc/wireguard # wg genkey > ios.private
root@proxy:/usr/local/etc/wireguard # wg pubkey < ios.private > ios.public

Дальше создадим конфиг для интерфейса:

ee wg0.conf

Со следующим содержимым

root@proxy:/usr/local/etc/wireguard # cat wg0.conf
[Interface]
Address = 10.0.1.1/24
PrivateKey = <содержимое freebsd.private>
ListenPort = 51820

[Peer]
PublicKey = <содержимое ios.public>
AllowedIPs = 10.0.1.2/32
Endpoint = wg.example.com:51820

В строке Endpoint указываем ip или имя хоста на внешнем интерфейсе, так как wg0 считаем как внутренний.

Далее запилим ios.conf:

root@proxy:/usr/local/etc/wireguard # cat ios.conf
[Interface]
Address = 10.0.1.2/32
PrivateKey = <содержимое ios.private>
DNS = 9.22.15.8

[Peer]
PublicKey = <содержимое freebsd.public>
AllowedIPs = 0.0.0.0/0
Endpoint = wg.example.com:51820

После этого добавляем в автозагрузку /etc/rc.conf:

wireguard_enable="YES"
wireguard_interfaces="wg0"

И запускаем:

root@proxy:/usr/local/etc/wireguard # service wireguard start
root@proxy:/usr/local/etc/wireguard # ifconfig wg0
wg0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> metric 0 mtu 1500
        options=80000<LINKSTATE>
        inet 10.0.1.1 --> 10.0.1.1 netmask 0xff000000
        groups: tun
        nd6 options=101<PERFORMNUD,NO_DAD>
        Opened by PID 583
root@proxy:/usr/local/etc/wireguard # netstat -rnfinet
Routing tables

Internet:
Destination        Gateway            Flags     Netif Expire
default            21.22.11.1      UGS      vtnet0
10.0.1.1           link#3             UH          wg0
10.0.1.2/32        wg0                US          wg0
127.0.0.1          link#2             UH          lo0
21.22.11.0/24      link#1             U           vtnet0
21.22.11.14        link#1             UHS         lo0

Теперь надо настроить файервол. Я выбрал PF, мне с ним проще. До его настройки надо настроить возможность операционки NATить траффик. нас интересует опция net.inet.ip.forwarding.

root@proxy:/usr/local/etc/wireguard # sysctl -a | grep forward
kern.smp.forward_signal_enabled: 1
net.inet.ip.forwarding: 1
net.inet6.ip6.forwarding: 1

Если значение 0, то в файле /etc/sysctl.conf прописываем 1 и перегрузим демона:

root@proxy:/usr/local/etc/wireguard # service sysctl restart

Загрузим модуль файервола:

root@proxy:/usr/local/etc/wireguard # kldload pf
root@proxy:/usr/local/etc/wireguard # kldstat
Id Refs Address                Size Name
 1    7 0xffffffff80200000  243d250 kernel
 2    1 0xffffffff82819000     2678 intpm.ko
 3    1 0xffffffff8281c000      b10 smbus.ko
 4    1 0xffffffff8281d000    327e8 pf.ko

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

root@proxy:/usr/local/etc/wireguard # cat /etc/rc.conf | grep pf
pf_enable="YES"
pf_rules="/etc/pf.conf"

Внимание! Если у вас продуктивный сервер, то к настройке межсетевого экрана надо подойти со всей серьезностью и ответственностью. Данное руководство исключительно ознакомительное.

И настроим конфиг /etc/pf.conf:

root@proxy:/usr/local/etc/wireguard # cat /etc/pf.conf
ext_if="vtnet0"
int_if="wg0"
set skip on lo0
scrub in all
nat on $ext_if from $int_if:network to any -> ($ext_if)
pass all

Можно обезопасить и изменить таким образом:

block all
pass in on $int_if from any to any
pass out on $ext_if from $ext_if to any
pass in on $ext_if proto tcp from any to $ext_if port ssh
pass in on $ext_if proto udp from any to $ext_if port 51820
pass in inet proto icmp all icmp-type echoreq

Активируем правила:

root@proxy:/usr/local/etc/wireguard # pfctl -f /etc/pf.conf

Основная часть настроена, теперь устанавливаем приложение из AppStore или Google Playmarket. Запускам программу для генерации QR кода и указываем наш конфиг для устройства.

root@proxy:/usr/local/etc/wireguard # qrencode -t ansi < ios.conf

Получится примерно такое изображение:

Желательно развернуть на весь экран, так как в небольшом окне не отображается полностью QR код.

Открываем приложение не телефоне, выбираем Create from QR code и скаринуем наш QR код в терминале.

Результат:

Вы можете войти под своим логином или зарегистрироваться на сайте.