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

VPN на базе WireGuard и FreeBSD

Просмотров: 119Комментарии: 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]
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

Теперь создадим интерфейс wg0. Я то думал, что его можно создать с помощью ifconfig, а оказывается он создается с помощью утилиты wireguard-go таким образом:

root@proxy:/usr/local/etc/wireguard # wireguard-go wg0
root@proxy:/usr/local/etc/wireguard # ifconfig wg0 inet 10.0.1.1 10.0.1.1

И пропишем маршруты:

root@proxy:/usr/local/etc/wireguard # route add -inet 10.0.1.2/32 -interface wg0

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

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

Завершим настройку интерфейса и ключей:

root@proxy:/usr/local/etc/wireguard # wg setconf wg0 wg0.conf

Если не создаются UDP сокеты, можно использовать такой хак:

root@proxy:/usr/local/etc/wireguard # ifconfig wg0 down up

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

wireguard_enable="YES"
wireguard_interfaces="wg0"

И запускаем:

root@proxy:/usr/local/etc/wireguard # service wireguard start

Теперь надо настроить файервол. Я выбрал 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 код в терминале.

Результат:

Оставьте комментарий!

grin LOL cheese smile wink smirk rolleyes confused surprised big surprise tongue laugh tongue rolleye tongue wink raspberry blank stare long face ohh grrr gulp oh oh downer red face sick shut eye hmmm mad angry zipper kiss shock cool smile cool smirk cool grin cool hmm cool mad cool cheese vampire snake excaim question

Используйте нормальные имена.

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

(обязательно)