Продовжую налаштування свого домашнього сервера на FreeBSD 14.3, де планується мати NAS.
В попередньому пості FreeBSD: знайомство з Packet Filter (PF) firewall познайомились з фаєрволами, наступний крок – це налаштувати VPN для доступу.
Основна ідея – поєднати (нарешті!) мій “офіс” і квартиру, а пізніше, можливо, ще і підключити сервер, на якому зараз працює rtfm.co.ua – аби бекапи блогу і баз даних зберігати відразу на ZFS пулі з RAID домашнього сервера.
Зміст
WireGuard vs OpenVPN
Коли діло дійшло до вибору який конкретно VPN сервер вибрати, то я спочатку думав взяти OpenVPN – бо працюю з ним не один рік, і на RTFM про нього навіть є якісь матеріали.
Але, трохи подумавши вирішив, що для домашнього VPN рішення типу OpenVPN або Pritunl будуть трохи оверхедом, і можна спробувати WireGuard.
Системи дуже різні, але якщо коротко, то:
- WireGuard набагато менший по коду – наприклад, Linux-реалізація це близько 4000 строк в ядрі, тоді як в OpenVPN це близько 100,000 строк в user space
- WireGuard працює як модуль ядра – обробка пакетів і криптографія виконуються безпосередньо в kernel space, а OpenVPN є user space сервісом і працює через TCP або UDP socket та взаємодіє з ядром через стандартний мережевий стек ядра
- туди ж – шифрування, бо WireGuard має вбудовану криптографію, яка є частиною самого протоколу і працює в kernel space, а OpenVPN використовує стандартний SSL/TLS стек (OpenSSL, LibreSSL тощо) в user space, що додає складність і накладні витрати CPU/RAM
- модель роботи WireGuard – peer-to-peer, тобто протокол не має вбудованих ролей “сервер” чи “клієнт”, є лише Peers з ключами і дозволеними IP, тоді як OpenVPN побудований навколо класичної клієнт-серверної архітектури
В результаті WireGuard можна сприймати не як окремий сервіс, а як зашифрований мережевий інтерфейс, тоді як OpenVPN залишається класичним прикладним VPN-сервісом.
Навіть офіційний документ по WireGuard названий “Next Generation Kernel Network Tunnel“.
Архітектура мережі
Отже, що в мене є:
- “офіс”: окрема локальна мережа 192.168.0.0/24, на вході – роутер TP-LINK Archer AX12
- в цій мережі є робочий ноутбук з Arch Linux і Lenovo ThinkCentre з FreeBSD
- на FreeBSD буде NAS, NFS і, власне, саме WireGuard
- хоча Archer AX12 має власні вбудовані OpenVPN і WireGuard – але хочеться зробити самому, руками, плюс все ж більше контролю
- дома: там мережа 192.168.100.0/24, на вході точно такий же роутер Archer AX12
- там єдиний клієнт – це домашній ноутбук з Arch Linux
І що я хочу зробити:
- на FreeBSD буде WireGuard в ролі VPN-сервера
- на роутері Archer AX12 буде NAT port-forwarding для підключення до WireGuard на FreeBSD
- мережа VPN – 10.8.0.1/24
- на FreeBSD – Paket Filter firewall для контролю трафіка
- обидва ноутбуки повинні мати доступ один до одного і до майбутнього NAS на FreeBSD
Як це в результаті виглядає схематично:
Запуск WireGuard на FreeBSD
У FreeBSD (власне, як і в Linux) WireGuard – це kernel module + userspace tools: основна “робоча” частина завантажується як модуль ядра, а для роботи з ним встановлюється окремий пакет.
Встановлюємо wireguard-tools:
root@setevoy-nas:/home/setevoy # pkg install wireguard-tools
Завантажуємо модуль:
root@setevoy-nas:/home/setevoy # kldload if_wg
Перевіряємо:
root@setevoy-nas:/home/setevoy # kldstat | grep wg 8 1 0xffffffff82a47000 2f5c0 if_wg.ko
Додаємо запуск WireGuard в /etc/rc.conf:
root@setevoy-nas:/home/setevoy # sysrc wireguard_enable=YES wireguard_enable: -> YES root@setevoy-nas:/home/setevoy # sysrc wireguard_interfaces=wg0 wireguard_interfaces: -> wg0
Поки не запускаємо – переходимо до налаштування мережі.
Network configuration
Далі треба налаштувати систему на роутинг пакетів між фізичним інтерфейсом та інтерфейсом WireGuard, і оновити конфіг фаєрвола.
Конфігурація IP forwarding
Додаємо IP forwarding з інтерфейсу wg0 (якого ще нема, з’явиться під час запуску WireGuard) на інтерфейс LAN, em0.
Оновлюємо автозапуск в /etc/rc.conf:
root@setevoy-nas:/usr/local/etc/wireguard # sysrc gateway_enable="YES" gateway_enable: NO -> YES
Аби переадресація запрацювала зараз, без ребуту – вмикаємо її одразу з sysctl:
root@setevoy-nas:/usr/local/etc/wireguard # sysctl net.inet.ip.forwarding=1 net.inet.ip.forwarding: 0 -> 1
Перевіряємо:
root@setevoy-nas:/usr/local/etc/wireguard # sysctl net.inet.ip.forwarding net.inet.ip.forwarding: 1
Наступний крок – налаштування Packet Filter.
Конфігурація Packet Filter
Отже, що у нас є:
- мережа VPN: 10.8.0.0/24
- мережа офісу, де FreeBSD/VPN: 192.168.0.0/24
- FreeBSD LAN IP: 192.168.0.2
- роутити інтернет через VPN не потрібно – тільки трафік між мережами дома і офісу
Конфіг pf зараз – мінімалістичний, з попереднього поста:
allowed_tcp_ports = "{ 22 }"
allowed_clients = "{ 192.168.0.0/24, 192.168.1.0/24 }"
set skip on lo
block all
# allow ssh only from specific hosts
pass in proto tcp from $allowed_clients to any port $allowed_tcp_ports keep state
# allow all outgoing traffic
pass out all keep state
Що до нього треба додати:
- дозволити вхідні UDP-з’єднання на порт WireGuard (51820) для handshake
- дозволити трафік з VPN-мережі 10.8.0.0/24 до самого FreeBSD-хоста (ping, SSH)
- дозволити транзитний трафік з VPN-мережі 10.8.0.0/24 до локальних мереж офісу і дому (192.168.0.0/24 та 192.168.100.0/24)
- дозволити ICMP і SSH з VPN-мережі та домашньої мережі до FreeBSD-хоста
- дозволити вихідний трафік з FreeBSD
Я додав макроси в конфіг, але поки пишу і тестую – вказую всі порти та адреси явно прямо в конфігу, простіше читати.
Тепер /etc/pf.conf буде виглядати так:
##################
### Interfaces ###
##################
# lan_if = "em0"
# wg_if = "wg0"
################
### Networks ###
################
# lan_net = "192.168.0.0/24"
# home_net = "192.168.100.0/24"
# wg_net = "10.8.0.0/24"
# vpn_nets = "{ 10.8.0.0/24, 192.168.100.0/24 }"
################
### Services ###
################
# ssh_ports = "{ 22 }"
# wg_port = "51820"
######################
### Basic settings ###
######################
# do not filter loopback traffic
set skip on lo
######################
### Default policy ###
######################
# block everything by default
block all
#######################
### Inbound traffic ###
#######################
### SSH
# allow SSH from Office LAN (192.168.0.0/24) to FreeBSD host
pass in log on em0 proto tcp from 192.168.0.0/24 to (em0) port 22 keep state
# allow SSH from Home network (192.168.100.0/24) to FreeBSD host
pass in log on em0 proto tcp from 192.168.100.0/24 to (em0) port 22 keep state
# allow SSH from VPN clients to FreeBSD host
pass in on wg0 proto tcp from 10.8.0.0/24 to (wg0) port 22 keep state
### VPN
# allow WireGuard handshake (UDP/51820) on LAN interface
pass in on em0 proto udp to (em0) port 51820 keep state
# allow VPN clients (10.8.0.0/24) to access FreeBSD host itself
# this allows ping, ssh, etc. to the wg0 address
pass in on wg0 from 10.8.0.0/24 to (wg0) keep state
# allow VPN clients to access Office LAN (192.168.0.0/24)
pass in on wg0 from 10.8.0.0/24 to 192.168.0.0/24 keep state
# allow VPN clients to access Home network (192.168.100.0/24)
pass in on wg0 from 10.8.0.0/24 to 192.168.100.0/24 keep state
# allow ICMP (ping) from VPN clients to FreeBSD host
pass in on wg0 proto icmp from 10.8.0.0/24 to (wg0) keep state
# allow ICMP (ping) from Home network to FreeBSD host
pass in on em0 proto icmp from 192.168.100.0/24 to (em0) keep state
############################
### outbound traffic ###
############################
# allow all outbound traffic from FreeBSD
pass out keep state
Перевіряємо синтаксис:
root@setevoy-nas:/home/setevoy # pfctl -vnf /etc/pf.conf
set skip on { lo }
block drop all
pass in log on em0 inet proto tcp from 192.168.0.0/24 to (em0) port = ssh flags S/SA keep state
pass in log on em0 inet proto tcp from 192.168.100.0/24 to (em0) port = ssh flags S/SA keep state
pass in on wg0 inet from 10.8.0.0/24 to (wg0) flags S/SA keep state
pass in on wg0 inet proto icmp from 10.8.0.0/24 to (wg0) keep state
pass in on wg0 inet from 10.8.0.0/24 to 192.168.0.0/24 flags S/SA keep state
pass in on wg0 inet from 10.8.0.0/24 to 192.168.100.0/24 flags S/SA keep state
pass in on em0 inet proto icmp from 192.168.100.0/24 to (em0) keep state
pass in on em0 proto udp from any to (em0) port = 51820 keep state
pass out all flags S/SA keep state
Виконуємо reload:
root@setevoy-nas:/home/setevoy # service pf reload Reloading pf rules.
Тепер можемо підготувати запуск WireGuard.
Конфігурація WireGuard
Тут все дуже просто – створити ключі, написати конфіг-файл.
Створення ключів
Комунікація і криптографія у WireGuard побудована на стандартній схемі асиметричних ключів:
- на “сервері” зберігається приватний ключі
- на клієнті вказується публічний
- під час handshake клієнт переконується, що підключився саме до того сервера, публічний ключ якого він знає
- а далі, з цими ключами, відбувається і шифрування даних
Див. Key Exchange and Data Packets.
Слово “сервер” все ж беру в лапки, бо, як було зазначено вище – WireGuard це P2P, а не client-server.
Після установки wireguard-tools створюється каталог /usr/local/etc/wireguard – переходимо туди, і з wg genkey створюємо приватний та публічний ключ:
root@setevoy-nas:/home/setevoy # cd /usr/local/etc/wireguard root@setevoy-nas:/usr/local/etc/wireguard # wg genkey | tee server.key | wg pubkey > server.pub
Міняємо права доступу до приватного ключа:
root@setevoy-nas:/usr/local/etc/wireguard # chmod 600 server.key
Перевіряємо:
root@setevoy-nas:/usr/local/etc/wireguard # chmod 600 server.key root@setevoy-nas:/usr/local/etc/wireguard # ll total 12 -rw------- 1 root wheel 45 Dec 17 15:58 server.key -rw-r--r-- 1 root wheel 45 Dec 17 15:58 server.pub
Базовий конфіг для WireGuard
Можна створити кілька різних конфігурацій в /usr/local/etc/wireguard/, кожен на власному порті та/або IP та з власним ключем і мати кілька різних VPN-підключень, а керувати ними використовуючи ім’я файлу – wg0, wg1, etc.
Є навіть генератори конфігу – https://www.wireguardconfig.com.
Документація по синтаксису – Wireguard Configuration File Format.
Отримуємо приватний ключ:
root@setevoy-nas:/usr/local/etc/wireguard # cat server.key cLS***GQ=
Створюємо файл /usr/local/etc/wireguard/wg0.conf – поки тільки “сервер”:
[Interface] Address = 10.8.0.1/24 ListenPort = 51820 PrivateKey = cLS***sGQ=
Блок Interface визначає параметри WireGuard-інтерфейсу wg0 – його IP-адресу, UDP-порт і приватний ключ, який використовується для шифрування трафіку.
Тут жеж можна вказати які DNS використовувати, чи робити апдейт в таблицях маршрутизації клієнтів (default – true) і запуск скриптів з PreUp, PostUp, PreDown, PostDown.
Запускаємо сам WireGuard:
root@setevoy-nas:/home/setevoy # wg-quick up wg0 [#] ifconfig wg create name wg0 [#] wg setconf wg0 /dev/stdin [#] ifconfig wg0 inet 10.8.0.1/24 alias [#] ifconfig wg0 mtu 1420 [#] ifconfig wg0 up [+] Backgrounding route monitor
Перевіряємо інтерфейс:
root@setevoy-nas:/home/setevoy # ifconfig wg0
wg0: flags=10080c1<UP,RUNNING,NOARP,MULTICAST,LOWER_UP> metric 0 mtu 1420
options=80000<LINKSTATE>
inet 10.8.0.1 netmask 0xffffff00
groups: wg
nd6 options=109<PERFORMNUD,IFDISABLED,NO_DAD>
Та статус WireGuard:
root@setevoy-nas:/home/setevoy # wg show interface: wg0 public key: xLWA/FgF3LBswHD5Z1uZZMOiCbtSvDaUOOFjH4IF6W8= private key: (hidden) listening port: 51820
Поки у нас нема ніяких клієнтів – переходимо до них.
TP-Link Dynamic DNS та NAT port-forwarding
Аби з дому підключатись до хосту з FreeBSD і WireGuard – на роутері в офісі додаємо форвард портів:
- protocol: UDP
- зовнішній порт на роутері: 51830 (трохи замаскувати від ботів)
- куди форвардити: 192.168.0.2 (хост з FreeBSD)
- на який порт форвардити: 51830 (WireGuard на
em0на FreeBSD)
На TP-Link Archer AX12 це виглядає так:
Якщо Internet IP в офісі динамічний – в Archer AX12 є можливість налаштування Dynamic DNS:
Хоча в мене він статичний, але DDNS заради інтересу налаштував з https://www.noip.com.
Запуск WireGuard на Arch Linux
В Linux все аналогічно – в ядрі є модулі, нам треба тільки встановити пакет з утилітами.
Перевіряємо модулі:
root@setevoy-home:/home/setevoy # lsmod | grep wireguard wireguard 122880 0 curve25519_x86_64 36864 1 wireguard libcurve25519_generic 45056 2 curve25519_x86_64,wireguard ip6_udp_tunnel 16384 1 wireguard udp_tunnel 32768 1 wireguard
Встановлюємо пакет:
root@setevoy-home:/home/setevoy # pacman -S wireguard-tools
Переходимо в /etc/wireguard/, створюємо ключі:
root@setevoy-home:/home/setevoy # cd /etc/wireguard/ root@setevoy-home:/etc/wireguard # wg genkey | tee client1.key | wg pubkey > client1.pub
Міняємо права доступу на приватний ключ:
root@setevoy-home:/etc/wireguard # chmod 600 client1.key
Тепер можемо додавати Peers – клієнтів.
Для цього нам потрібно додати ключі на клієнті та на сервері:
- на сервері:
- в
Interface–PrivateKey: це/usr/local/etc/wireguard/server.keyна хості FreeBSD - в
Peer–PublicKey: це/etc/wireguard/client1.pubна ноутбуці з Arch Linux
- в
- на клієнті:
- в
Interface–PrivateKey: це/etc/wireguard/client1.key - в
Peer–PublicKey: це/usr/local/etc/wireguard/server.pub
- в
Описуємо конфіг на клієнті, файл /etc/wireguard/wg0.conf:
[Interface] PrivateKey = 0Cu***UWU= Address = 10.8.0.3/24 [Peer] PublicKey = xLWA/FgF3LBswHD5Z1uZZMOiCbtSvDaUOOFjH4IF6W8= Endpoint = setevoy-***.ddns.me:51830 AllowedIPs = 10.8.0.1/32, 192.168.0.0/24 PersistentKeepalive = 25
Тут в AllowedIPs вказуємо мережі в які, по-перше, буде доступ взагалі, по-друге – вони будуть додані в таблиці маршрутизації (“Acts as a routing table and access control list“).
Запускаємо на клієнті:
[root@setevoy-wg-test setevoy]# wg-quick up wg0 [#] ip link add dev wg0 type wireguard [#] wg setconf wg0 /dev/fd/63 [#] ip -4 address add 10.8.0.3/24 dev wg0 [#] ip link set mtu 1420 up dev wg0 [#] ip -4 route add 10.8.0.3/32 dev wg0 [#] ip -4 route add 192.168.0.0/24 dev wg0
Тут:
ip -4 address add:Interface - Addressзаданий дляwg0ip -4 route add 10.8.0.3/32та192.168.0.0/24: додані нові роути через інтерфейсwg0для мереж VPN та офісної локалки
Перевіряємо:
root@setevoy-home:/etc/wireguard # ip r s 10.8.0.0/24 10.8.0.0/24 dev wg0 proto kernel scope link src 10.8.0.3 root@setevoy-home:/etc/wireguard # ip r s 192.168.0.0/24 192.168.0.0/24 dev wg0 scope link
Додаємо Peer на сервері, файл /usr/local/etc/wireguard/wg0.conf тепер буде таким:
[Interface] Address = 10.8.0.1/24 ListenPort = 51820 PrivateKey = cLS***sGQ= [Peer] PublicKey = d7yqxOky4qOI/NTl/qbUnijfICwmbe/e/ulSVuQKLhk= AllowedIPs = 10.8.0.3/32, 192.168.100.0/24
Перезапускаємо:
root@setevoy-nas:/usr/local/etc/wireguard # wg-quick down wg0 [#] ifconfig wg0 destroy root@setevoy-nas:/usr/local/etc/wireguard # wg-quick up wg0 [#] ifconfig wg create name wg0 [#] wg setconf wg0 /dev/stdin [#] ifconfig wg0 inet 10.8.0.1/24 alias [#] ifconfig wg0 mtu 1420 [#] ifconfig wg0 up [#] route -q -n add -inet 10.8.0.2/32 -interface wg0 [+] Backgrounding route monitor
Перевіряємо статус на клієнті:
root@setevoy-home:/etc/wireguard # wg show interface: wg0 public key: d7yqxOky4qOI/NTl/qbUnijfICwmbe/e/ulSVuQKLhk= private key: (hidden) listening port: 36864 peer: xLWA/FgF3LBswHD5Z1uZZMOiCbtSvDaUOOFjH4IF6W8= endpoint: 178.***.***.184:51830 allowed ips: 10.8.0.1/32, 192.168.0.0/24 latest handshake: 1 minute, 44 seconds ago transfer: 4.35 KiB received, 5.84 KiB sent persistent keepalive: every 25 seconds
Головне, на що звертаємо увагу, це “latest handshake” – значить клієнт до сервера підєднався.
Перевіряємо на сервері:
root@setevoy-nas:/home/setevoy # wg show interface: wg0 public key: xLWA/FgF3LBswHD5Z1uZZMOiCbtSvDaUOOFjH4IF6W8= private key: (hidden) listening port: 51820 peer: d7yqxOky4qOI/NTl/qbUnijfICwmbe/e/ulSVuQKLhk= endpoint: 178.***.***.236:56432 allowed ips: 192.168.100.0/24, 10.8.0.3/32 latest handshake: 15 seconds ago transfer: 1.69 KiB received, 3.87 KiB sent
Перевіряємо SSH з клієнта на сервер:
root@setevoy-home:/etc/wireguard # ssh [email protected] ([email protected]) Password for setevoy@setevoy-nas: ... FreeBSD 14.3-RELEASE (GENERIC) releng/14.3-n271432-8c9ce319fef7 Welcome to FreeBSD! ... setevoy@setevoy-nas:~ $
Або:
[setevoy@setevoy-home ~]$ ssh 192.168.0.2 ([email protected]) Password for setevoy@setevoy-nas:
Додаємо профайл wg0 в автозапуск:
[setevoy@setevoy-home ~]$ sudo systemctl enable wg-quick@wg0 Created symlink '/etc/systemd/system/multi-user.target.wants/[email protected]' → '/usr/lib/systemd/system/[email protected]'.
В принципі, на цьому вже майже все готове – доступ є, все працює.
Але чого хочеться ще – це мати прямий доступ з домашнього ноута на робочий і з робочого на домашній, бо на робочому ноуті VPN нема – він там і не потрібен, бо FreeBSD/NAS в тій самій локальній мережі.
Конфігурація cross-LAN доступу
Тож що треба зробити – це налаштувати прямий доступ між ноутами в домашній мережі 192.168.100.0/24 і офісній 192.168.0.0/24, бо зараз з робочого ноутбука на ноутбук вдома і навпаки доступ не працює.
Картина зараз така:
- IP ноута в офісі: 192.168.0.165
- IP ноута вдома: 192.168.100.205
- на робочому ноуті WireGuard нема
- з офісу на домашній ноут конекта нема
- з дому на робочий ноут конекта нема
- з дому на FreeBSD конект є
Налаштування Routing tables
Поки робимо – закоментуємо block all в /etc/pf.conf, потім до нього повернемось.
В результаті того, що зараз будемо робити – вийде ось така схема: тут головне – це маршрути, спеціально робив схемою, аби те, що буде описано далі було простіше зрозуміти:
Перевіряємо роути з домашнього ноута на FreeBSD:
root@setevoy-home:/etc/wireguard # ip route get 192.168.0.2 192.168.0.2 dev wg0 src 10.8.0.3 uid 0
І на робочий ноут:
root@setevoy-home:/etc/wireguard # ip route get 192.168.0.165 192.168.0.165 dev wg0 src 10.8.0.3 uid 0
Трафік йде через wg0, і Source Address для пакета задається як 10.8.0.3.
А на робочому ноуті роут на домашній ноут йде через 192.168.0.1:
[setevoy@setevoy-work ~] $ ip route get 192.168.100.205 192.168.100.205 via 192.168.0.1 dev wlan0 src 192.168.0.165 uid 1000
Тут 192.168.0.1 – дефолтний гейтвей, роутер в офісі, який нічого не знає про домашню мережу 192.168.100.0/24.
Тому перше – додаємо роут в домашню мережу через хост з FreeBSD:
[setevoy@setevoy-work ~] $ sudo ip route add 192.168.100.0/24 via 192.168.0.2
Перевіряємо ще раз:
[setevoy@setevoy-work ~] $ ip route get 192.168.100.205 192.168.100.205 via 192.168.0.2 dev wlan0 src 192.168.0.165 uid 1000
Тепер є контакт з офісу додому:
[setevoy@setevoy-work ~] $ ping 192.168.100.205 -c 1 PING 192.168.100.205 (192.168.100.205) 56(84) bytes of data. 64 bytes from 192.168.100.205: icmp_seq=1 ttl=63 time=62.0 ms --- 192.168.100.205 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms
Але з домашнього все ще нема, бо з дому ми шлемо:
- з домашнього ноута з IP 192.168.100.205
- через FreeBSD з IP 192.168.0.2
- на робочий ноутбук з IP 192.168.0.165
- через FreeBSD з IP 192.168.0.2
Але у нас з домашнього ноутбука задається Source IP як 10.8.0.3:
root@setevoy-home:/etc/wireguard # ip route get 192.168.0.165 192.168.0.165 dev wg0 src 10.8.0.3 uid 0
Бо маршрут в 192.168.0.0/24 заданий через VPN інтерфейс wg0:
root@setevoy-home:/etc/wireguard # ip r s 192.168.0.0/24 192.168.0.0/24 dev wg0 scope link
А у wg0 заданий IP 10.8.0.3:
root@setevoy-home:/etc/wireguard # ip a s wg0
20: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN group default qlen 1000
link/none
inet 10.8.0.3/24 scope global wg0
А робочий ноут нічого про мережу 10.8.0.0/24 не знає і не може повернути відповідь.
Тому на робочому ноуті додаємо ще один маршрут:
[setevoy@setevoy-work ~] $ sudo ip route add 10.8.0.0/24 via 192.168.0.2 dev wlan0
Перевіряємо:
[setevoy@setevoy-work ~] $ ip r s 10.8.0.0/24 10.8.0.0/24 via 192.168.0.2 dev wlan0
І тепер з домашнього ноута на робочий доступ теж є:
root@setevoy-home:/etc/wireguard # ping -c1 192.168.0.165 PING 192.168.0.165 (192.168.0.165) 56(84) bytes of data. 64 bytes from 192.168.0.165: icmp_seq=1 ttl=63 time=6.19 ms --- 192.168.0.165 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms
Аби ці роути додати постійно – можна зробити з NetworkManager CLI.
Видаляємо те, що додали вручну:
[setevoy@setevoy-work ~] $ sudo ip route del 10.8.0.0/24 via 192.168.0.2 [setevoy@setevoy-work ~] $ sudo ip route del 192.168.100.0/24 via 192.168.0.2
Знаходимо ім’я підключення:
[setevoy@setevoy-work ~] $ nmcli connection show NAME UUID TYPE DEVICE setevoy-tp-link-21-5 3a12a60d-7b37-4c20-b573-d27c47a94ae5 wifi wlan0 ...
Додаємо роути:
[setevoy@setevoy-work ~] $ nmcli connection modify setevoy-tp-link-21-5 +ipv4.routes "10.8.0.0/24 192.168.0.2,192.168.100.0/24 192.168.0.2"
Перевіряємо:
[setevoy@setevoy-work ~] $ nmcli connection show setevoy-tp-link-21-5 | grep ipv4.routes
ipv4.routes: { ip = 10.8.0.0/24, nh = 192.168.0.2 }; { ip = 192.168.100.0/24, nh = 192.168.0.2 }
Перезапускаємо підключення:
[setevoy@setevoy-work ~] $ sudo nmcli connection down setevoy-tp-link-21-5 && sudo nmcli connection up setevoy-tp-link-21-5 Connection 'setevoy-tp-link-21-5' successfully deactivated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/15) Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/16)
Перевіряємо роути тепер:
[setevoy@setevoy-work ~] $ ip route get 10.8.0.3 10.8.0.3 via 192.168.0.2 dev wlan0 src 192.168.0.165 uid 1000 [setevoy@setevoy-work ~] $ ip route get 192.168.100.205 192.168.100.205 via 192.168.0.2 dev wlan0 src 192.168.0.165 uid 1000
Тепер у нас є ping з офісного ноутбука на домашній:
[setevoy@setevoy-work ~] $ ping -c1 192.168.100.205 PING 192.168.100.205 (192.168.100.205) 56(84) bytes of data. 64 bytes from 192.168.100.205: icmp_seq=1 ttl=63 time=5.95 ms --- 192.168.100.205 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms
І з домашнього на робочий:
root@setevoy-home:/etc/wireguard # ping -c1 192.168.0.165 PING 192.168.0.165 (192.168.0.165) 56(84) bytes of data. 64 bytes from 192.168.0.165: icmp_seq=1 ttl=63 time=5.67 ms --- 192.168.0.165 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms
Налаштування Packet Filter
Але якщо ми включимо block all в pf, то підключення з офісу на домашній ноут зламається, бо у нас зараз правила тільки для FreeBSD host:
... # allow SSH from Office LAN (192.168.0.0/24) to FreeBSD host pass in log on em0 proto tcp from 192.168.0.0/24 to (em0) port 22 keep state ... # allow ICMP (ping) from Home network to FreeBSD host pass in on em0 proto icmp from 192.168.100.0/24 to (em0) keep state ...
Тут:
- перше правило – дозволяє SSH з офісної мережі на IP інтерфейсу
em0хоста з FreeBSD - друге – дозволяє ping з домашньої мережі на IP інтерфейсу
em0хоста з FreeBSD
Тому додаємо ще два правила – з SSH і ping з офісу додому:
... # allow SSH from Office network to Home network pass in on em0 proto tcp from 192.168.0.0/24 to 192.168.100.0/24 port 22 keep state ... # allow ICMP from Home network to Office network pass in on em0 proto icmp from 192.168.0.0/24 to 192.168.100.0/24 keep state ...
Перевіряємо, перечитуємо конфіг pf:
root@setevoy-nas:/usr/local/etc/wireguard # pfctl -vnf /etc/pf.conf && service pf reload
set skip on { lo }
block drop log all
pass in log on em0 inet proto tcp from 192.168.0.0/24 to (em0) port = ssh flags S/SA keep state
pass in log on em0 inet proto tcp from 192.168.100.0/24 to (em0) port = ssh flags S/SA keep state
pass in on wg0 inet from 10.8.0.0/24 to (wg0) flags S/SA keep state
pass in on wg0 inet proto icmp from 10.8.0.0/24 to (wg0) keep state
pass in on wg0 inet from 10.8.0.0/24 to 192.168.0.0/24 flags S/SA keep state
pass in on wg0 inet from 10.8.0.0/24 to 192.168.100.0/24 flags S/SA keep state
pass in on em0 inet proto tcp from 192.168.0.0/24 to 192.168.100.0/24 port = ssh flags S/SA keep state
pass in on em0 inet proto icmp from 192.168.0.0/24 to 192.168.100.0/24 keep state
pass in on em0 proto udp from any to (em0) port = 51820 keep state
pass out all flags S/SA keep state
Reloading pf rules.
І тепер у нас є пінг з дому в офіс:
root@setevoy-home:/etc/wireguard # ping -c1 192.168.0.165 PING 192.168.0.165 (192.168.0.165) 56(84) bytes of data. 64 bytes from 192.168.0.165: icmp_seq=1 ttl=63 time=8.09 ms --- 192.168.0.165 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms
Є SSH ssh з дому в офіс:
root@setevoy-home:/etc/wireguard # ssh 192.168.0.165 [email protected]'s password:
Є пінг з офісу додому:
[setevoy@setevoy-work ~] $ ping -c1 192.168.100.205 PING 192.168.100.205 (192.168.100.205) 56(84) bytes of data. 64 bytes from 192.168.100.205: icmp_seq=1 ttl=63 time=60.5 ms --- 192.168.100.205 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms
І є SSH з офісу додому:
[setevoy@setevoy-work ~] $ ssh 192.168.100.205 [email protected]'s password:
Все працює.
Весь конфіг /etc/pf.conf тепер такий:
##################
### Interfaces ###
##################
# lan_if = "em0"
# wg_if = "wg0"
################
### Networks ###
################
# lan_net = "192.168.0.0/24"
# home_net = "192.168.100.0/24"
# wg_net = "10.8.0.0/24"
# vpn_nets = "{ 10.8.0.0/24, 192.168.100.0/24 }"
################
### Services ###
################
# ssh_ports = "{ 22 }"
# wg_port = "51820"
######################
### Basic settings ###
######################
# do not filter loopback traffic
set skip on lo
######################
### Default policy ###
######################
# block everything by default
block log all
#######################
### Inbound traffic ###
#######################
### SSH
# allow SSH from Office LAN (192.168.0.0/24) to FreeBSD host
pass in log on em0 proto tcp from 192.168.0.0/24 to (em0) port 22 keep state
# allow SSH from Home network (192.168.100.0/24) to FreeBSD host
pass in log on em0 proto tcp from 192.168.100.0/24 to (em0) port 22 keep state
# allow SSH from VPN clients to FreeBSD host
pass in on wg0 proto tcp from 10.8.0.0/24 to (wg0) port 22 keep state
### NEW
# allow SSH from Office netwrok to Home network
pass in on em0 proto tcp from 192.168.0.0/24 to 192.168.100.0/24 port 22 keep state
### TEST
# allow Office LAN to reach Home LAN via WireGuard
#pass in on em0 from 192.168.0.0/24 to 192.168.100.0/24 keep state
#pass out on wg0 from 192.168.0.0/24 to 192.168.100.0/24 keep state
# allow Home LAN to reach Office LAN via WireGuard
#pass in on wg0 from 192.168.100.0/24 to 192.168.0.0/24 keep state
#pass out on em0 from 192.168.100.0/24 to 192.168.0.0/24 keep state
### VPN
# allow WireGuard handshake (UDP/51820) on LAN interface
pass in on em0 proto udp to (em0) port 51820 keep state
# allow VPN clients (10.8.0.0/24) to access FreeBSD host itself
# this allows ping, ssh, etc. to the wg0 address
pass in on wg0 from 10.8.0.0/24 to (wg0) keep state
# allow VPN clients to access Office LAN (192.168.0.0/24)
pass in on wg0 from 10.8.0.0/24 to 192.168.0.0/24 keep state
# allow VPN clients to access Home network (192.168.100.0/24)
pass in on wg0 from 10.8.0.0/24 to 192.168.100.0/24 keep state
#
#pass in on em0 from 192.168.0.0/24 to 192.168.100.0/24 keep state
#pass in on wg0 from 192.168.100.0/24 to 192.168.0.0/24 keep state
### ICMP
# allow ICMP from VPN clients to FreeBSD host
pass in on wg0 proto icmp from 10.8.0.0/24 to (wg0) keep state
# allow ICMP from Home network to FreeBSD host
#pass in on em0 proto icmp from 192.168.100.0/24 to (em0) keep state
# allow ICMP from Home network to Office network
pass in on em0 proto icmp from 192.168.0.0/24 to 192.168.100.0/24 keep state
############################
### outbound traffic ###
############################
# allow all outbound traffic from FreeBSD
pass out keep state
Активні підключення в pftop:
Тут:
In 192.168.0.165:50286=>192.168.0.2:22: SSH робочий ноут на FreeBSDIn 178.***.***.236:56432=>192.168.0.2:51820: підключення з дому через NAT Port-forwarding на офісному роутері до VPN на FreeBSDIn 10.8.0.3:39442=>192.168.0.165:22: SSH з дому на робочий ноутOut 10.8.0.1:50589=>10.8.0.3:22: SSH з FreeBSD на домашній
P.S. Який це дикий кайф – оцей во “traditional networking” а не ці всі AWS VPC і його subnets…



