Строим VPN-туннель в локальную сеть с помощью «WireGuard»

Безопасный удаленный доступ к сервисам в локальной сети.

VPN (англ. Virtual Private Network, «виртуальная частная сеть») — обобщённое название технологий, позволяющих обеспечить одно или несколько сетевых соединений (логическую сеть) поверх другой сети (например Интернет).

Википедия

Наиболее популярные решения с открытым исходным кодом для построения виртуальных частных сетей — «OpenVPN» и «IPSec». В релиз ядра Linux 5.6, который состоялся 30 марта 2020 года, вошла еще одна реализация технологии VPN — «WireGuard». Это молодой набирающий популярность проект.

Основные преимущества «WireGuard»:

  • Высокая производительность (бенчмарки можно посмотреть тут)
  • Простая настройка
  • Современная криптография
  • Качественный код

В этой инструкции мы настроим VPN-туннель в локальную сеть с помощью «WireGuard» и обеспечим доступ из интернета к узлам LAN с различных устройств.

Адресация в LAN - 192.168.100.0/24, VPN-сети назначим диапазон 10.0.0.0/24.

Схема сети
Схема сети

Настройка сервера

Для размещения сервера потребуется VPS. При выборе необходимо обратить внимание на технологию виртуализации: предпочтительно KVM, можно XEN, а вот OpenVZ следует избегать. Дело в том, что в WireGuard реализован как модуль ядра, а в OpenVZ ядро очень старое. Я буду использовать самый дешевый виртуальный сервер c операционной системой Ubuntu 20.04 (KVM 512 МБ RAM 20 ГБ SSD 1 CPU - такая конфигурация вполне подойдет).

Залогинимся на сервер с правами пользователя root и выполним следующие команды:

# устанавливаем Wireguard apt update && apt upgrade apt install wireguard # разрешаем проброс пакетов echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf sysctl -p # генерируем ключи для сервера: wg genkey | tee /etc/wireguard/privatekey | wg pubkey | tee /etc/wireguard/publickey

Создадим конфигурационный файл /etc/wireguard/wg0.conf со следующим содержимым:

[Interface] Address = 10.0.0.1/24 PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE ListenPort = 51820 PrivateKey = <SERVER_PRIVATE_KEY>

Параметры PostUp/PostDown содержат правила iptables, которые будут применены при запуске/остановке сервиса. Обратите внимание на название сетевого интерфейса — оно должно соответствовать общедоступному сетевому адаптеру, в моем случае это eth0. Вывести список адаптеров можно командой:

ip a

Выберите из списка тот, которому соответствует внешний IP-адрес. <SERVER_PRIVATE_KEY> - заменяем содержимым файла /etc/wireguard/privatekey.

Запустим VPN-сервис и добавим его в автозагрузку:

wg-quick up wg0 systemctl enable wg-quick@wg0

Убедимся, что служба запустилась корректно:

root@wg-server:/etc/wireguard# wg show wg0 interface: wg0 public key: <SERVER_PUBLIC_KEY> private key: (hidden) listening port: 51820

Настройка клиента в LAN

Если ваш роутер поддерживает WireGuard (Zyxel KeeneticOS >=3.3, Mikrotik RouterOS >=7.1beta2, OpenWRT) — можно настроить VPN-клиент прямо на нем. Я буду использовать для этой цели сервер Ubuntu 20.04 (локальный адрес 192.168.100.7).

Первый этап настройки аналогичен конфигурации серверной части. Выполняем с правами root-пользователя:

# устанавливаем WireGuard apt update && apt upgrade apt install wireguard # разрешаем проброс пакетов echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf sysctl -p # генерируем ключи для клиента wg genkey | tee /etc/wireguard/privatekey | wg pubkey | tee /etc/wireguard/publickey

Редактируем /etc/wireguard/wg0.conf:

[Interface] PrivateKey = <PEER_LAN_PRIVATE_KEY> Address = 10.0.0.2/32 PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o wlp2s0 -j MASQUERADE PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o wlp2s0 -j MASQUERADE [Peer] PublicKey = <SERVER_PUBLIC_KEY> Endpoint = <SERVER_IP>:51820 AllowedIPs = 10.0.0.0/24 PersistentKeepalive = 20

<PEER_LAN_PRIVATE_KEY> — заменяем содержимым /etc/wireguard/privatekey, <SERVER_PUBLIC_KEY> — /etc/wireguard/publickey с сервера, <SERVER_IP> — внешний IP-адрес сервера. Правила iptables в PostUp/PostDown необходимы для того, чтобы наш клиент выступал в роли шлюза в LAN. Указываем в правилах тот сетевой интерфейс, на который назначен локальный адрес (192.168.100.7, в моем случае это wlp2s0). Уточните его путем исполнения команды:

ip a

В параметре AllowedIPs задаются адреса, маршрутизация к которым будет осуществляться через VPN-интерфейс. В поле PersistentKeepalive — периодичность проверки доступности соединения в секундах. Запускаем службу и добавляем в автозагрузку:

wg-quick up wg0 systemctl enable wg-quick@wg0

На сервере добавляем в файл /etc/wireguard/wg0.conf блок:

... [Peer] # PEER_LAN PublicKey = <PEER_LAN_PUBLIC_KEY> AllowedIPs = 10.0.0.2/32, 192.168.100.0/24

Где <PEER_LAN_PUBLIC_KEY> — /etc/wireguard/publickey клиента. Перезапустим службу и убедимся, что все настроено корректно:

systemctl restart wg-quick@wg0 root@wg-server:/etc/wireguard# wg show wg0 interface: wg0 public key: <SERVER_PUBLIC_KEY> private key: (hidden) listening port: 51820 peer: <CLIENT_PUBLIC_KEY> endpoint: <CLIENT_IP>:42946 allowed ips: 10.0.0.2/32, 192.168.100.0/24 latest handshake: 2 minutes, 8 seconds ago transfer: 3.24 KiB received, 828 B sent root@wg-server:/etc/wireguard# ping -c 3 10.0.0.2 PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data. 64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=31.1 ms 64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=120 ms 64 bytes from 10.0.0.2: icmp_seq=3 ttl=64 time=40.9 ms --- 10.0.0.2 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2002ms rtt min/avg/max/mdev = 31.093/63.987/119.950/39.774 ms root@wg-server:/etc/wireguard# ping -c 3 192.168.100.5 PING 192.168.100.5 (192.168.100.5) 56(84) bytes of data. 64 bytes from 192.168.100.5: icmp_seq=1 ttl=63 time=31.8 ms 64 bytes from 192.168.100.5: icmp_seq=2 ttl=63 time=119 ms 64 bytes from 192.168.100.5: icmp_seq=3 ttl=63 time=40.0 ms --- 192.168.100.5 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2002ms rtt min/avg/max/mdev = 31.834/63.573/118.915/39.273 ms

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

root@wg-lan-client:/etc/wireguard# wg show wg0 interface: wg0 public key: <CLIENT_PUBLIC_KEY> private key: (hidden) listening port: 42946 peer: <SERVER_PUBLIC_KEY> endpoint: <SERVER_IP>:51820 allowed ips: 10.0.0.0/24 latest handshake: 8 seconds ago transfer: 21.34 KiB received, 83.03 KiB sent persistent keepalive: every 21 seconds root@wg-lan-client:/etc/wireguard# ping -c 3 10.0.0.1 PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data. 64 bytes from 10.0.0.1: icmp_seq=1 ttl=64 time=32.0 ms 64 bytes from 10.0.0.1: icmp_seq=2 ttl=64 time=32.6 ms 64 bytes from 10.0.0.1: icmp_seq=3 ttl=64 time=32.2 ms --- 10.0.0.1 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 5ms rtt min/avg/max/mdev = 32.013/32.265/32.586/0.316 ms

Настройка удаленных клиентов

Сборки WireGuard доступны для основных платформ: Linux, Windows, Mac, Android, FreeBSD, OpenWRT и др. Рассмотрим настройку VPN-клиента на десктопах под управлением Linux и Windows, а так же на Android-смартфоне.

Удаленный Linux клиент

На клиенте выполняем с правами root:

# устанавливаем Wireguard apt update && apt upgrade apt install wireguard # генерируем ключи wg genkey | tee /etc/wireguard/peer_1_privatekey | wg pubkey | tee /etc/wireguard/peer_1_publickey

Конфигурационный файл /etc/wireguard/wg0.conf:

[Interface] PrivateKey = <PEER_1_PRIVATE_KEY> Address = 10.0.0.3/32 DNS = 8.8.8.8 [Peer] PublicKey = <SERVER_PUBLIC_KEY> Endpoint = <SERVER_IP>:51820 AllowedIPs = 0.0.0.0/0 # AllowedIPs = 10.0.0.0/24, 192.168.100.0/24 PersistentKeepalive = 20

<PEER_1_PRIVATE_KEY> — заменяем содержимым /etc/wireguard/peer_1_privatekey, <SERVER_PUBLIC_KEY> — /etc/wireguard/publickey с сервера.

Обратите внимание на строку «AllowedIPs = 0.0.0.0/0» - в данной конфигурации весь трафик будет маршрутизироваться через VPN-адаптер. Это может понадобиться для сокрытия реального IP при работе в интернет или для защиты трафика при подключении к недоверенным сетям (например публичные Wi-Fi точки доступа). В этом случае указываем «DNS = 8.8.8.8» (8.8.8.8 - DNS-сервер Google), чтобы DNS-запросы выполнялись через защищенное VPN-соединение.

Если VPN-туннель необходим только для доступа к LAN 192.168.100.0/24 - убираем строчку «DNS = 8.8.8.8» и в параметре AllowedIPs меняем «0.0.0.0/0» на «10.0.0.0/24, 192.168.100.0/24».

# запускаем службу wg-quick up wg0 # добавляем в автозапуск systemctl enable wg-quick@wg0

На сервере в конфигурационный файл /etc/wireguard/wg0.conf добавляем блок:

... [Peer] PublicKey = <PEER_1_PUBLIC_KEY> AllowedIPs = 10.0.0.3/32

Где <PEER_1_PUBLIC_KEY> — содержимое файла /etc/wireguard/peer_1_publickey клиента и перезапускаем службу:

systemctl restart wg-quick@wg0

Возвращаемся на клиент и проверяем доступность узлов в LAN через VPN-туннель:

root@wg-peer1:/etc/wireguard# wg show wg0 interface: wg0 public key: <PEER_1_PUBLIC_KEY> private key: (hidden) listening port: 34022 peer: <SERVER_PUBLIC_KEY> endpoint: <SERVER_IP>:51820 allowed ips: 10.0.0.0/24, 192.168.100.0/24 latest handshake: 44 seconds ago transfer: 6.91 KiB received, 8.96 KiB sent persistent keepalive: every 20 seconds root@wg-peer1:/etc/wireguard# ping -c 3 192.168.100.5 PING 192.168.100.5 (192.168.100.5) 56(84) bytes of data. 64 bytes from 192.168.100.5: icmp_seq=1 ttl=62 time=66.3 ms 64 bytes from 192.168.100.5: icmp_seq=2 ttl=62 time=65.7 ms 64 bytes from 192.168.100.5: icmp_seq=3 ttl=62 time=67.2 ms --- 192.168.100.5 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2003ms rtt min/avg/max/mdev = 65.748/66.387/67.157/0.582 ms

Удаленный Windows клиент

Скачиваем WireGuard для Windows с официального сайта и устанавливаем.

На сервере сгенерируем ключи для Windows-клиента:

wg genkey | tee /etc/wireguard/peer_2_windows_privatekey | wg pubkey | tee /etc/wireguard/peer_2_windows_publickey

Добавим блок Peer в файл /etc/wireguard/wg0.conf:

...​ [Peer] PublicKey = <PEER_2_PUBLIC_KEY> AllowedIPs = 10.0.0.4/32

Перезапустим сервер:

systemctl restart wg-quick@wg0

Конфигурационный файл windows.conf:

[Interface] PrivateKey = <PEER_2_PRIVATE_KEY> Address = 10.0.0.4/32 [Peer] PublicKey = <SERVER_PUBLIC_KEY> Endpoint = <SERVER_IP>:51820 AllowedIPs = 10.0.0.0/24, 192.168.100.0/24 PersistentKeepalive = 20

В приложении WireGuard открываем конфигурационный файл и нажимаем кнопку «подключение».

Строим VPN-туннель в локальную сеть с помощью «WireGuard»
Строим VPN-туннель в локальную сеть с помощью «WireGuard»

Конфигурационные файлы можно генерировать и на клиентах, а после отправлять открытые части ключей на сервер.

Удаленный Android клиент

Приложение для Android доступно в Google Play.

Генерируем ключи для клиента и добавляем Peer в конфигурационный файл сервера.

wg genkey | tee /etc/wireguard/peer_3_android_privatekey | wg pubkey | tee /etc/wireguard/peer_3_android_publickey

/etc/wireguard/wg0.conf:

... [Peer] PublicKey = <PEER_3_PUBLIC_KEY> AllowedIPs = 10.0.0.5/32

Не забываем перезапускать сервер после каждого изменения конфигурации:

systemctl restart wg-quick@wg0

Создадим конфигурационный файл для Android клиента mobile.conf:

[Interface] PrivateKey = <PEER_3_PRIVATE_KEY> Address = 10.0.0.5/32 [Peer] PublicKey = <SERVER_PUBLIC_KEY> Endpoint = <SERVER_IP>:51820 AllowedIPs = 10.0.0.0/24, 192.168.100.0/24 PersistentKeepalive = 20

Устанавливаем пакет qrencode:

sudo apt install qrencode

И генерируем QR-код с конфигурацией для PEER_3:

Строим VPN-туннель в локальную сеть с помощью «WireGuard»

В Android-приложении выбираем пункт меню «сканировать QR-код»:

Строим VPN-туннель в локальную сеть с помощью «WireGuard»

И подключаемся к VPN-туннелю:

Строим VPN-туннель в локальную сеть с помощью «WireGuard»

Распространенные проблемы

1. Соединение не устанавливается, «0 B received»

wg show wg0 interface: wg0 public key: <CLIENT_PRIVATE_KEY> private key: (hidden) listening port: 42658 peer: <SERVER_PUBLIC_KEY> endpoint: 80.249.145.4:51821 allowed ips: 10.0.0.0/24 transfer: 0 B received, 1.16 KiB sent persistent keepalive: every 20 second

Возможные причины и решения:

  • Сетевое соединение блокируется межсетевым экраном - проверьте настройки iptables на сервере и Linux клиентах, брандмауэра Windows, межсетевого экрана маршрутизатора;
  • UDP трафик блокируется интернет провайдером - WireGuard не поддерживает TCP, в этом случае стоит рассмотреть альтернативные решения, например openVPN в режиме TCP (либо туннелировать UDP, что не всегда целесообразно);
  • Ошибка в IP-адресе или PORT сервера - проверьте значение параметра «Endpoint» в конфигурационном файле;
  • Ошибка в ключах - проверьте ключи, в конфигурации сервера - открытые части ключей клиентов и приватная часть ключа сервера, в конфигурации клиентов - открытая часть ключа сервера, приватная часть ключа клиента.

2. При указании параметра DNS возникает ошибка «resolvconf: command not found»

root@wg-peer1:/etc/wireguard# wg-quick up wg0 [#] ip link add wg0 type wireguard [#] wg setconf wg0 /dev/fd/63 [#] ip -4 address add 10.0.0.2/32 dev wg0 [#] ip link set mtu 1420 up dev wg0 [#] resolvconf -a wg0 -m 0 -x /usr/bin/wg-quick: line 32: resolvconf: command not found [#] ip link delete dev wg0

Установите пакет openresolv:

apt install openresolv

WireGuard - оптимальное решение для организации удаленного доступа к сетям малых офисов и домашним сетям. Он прост в настройке, работает на всех распространенных платформах и обладает хорошей производительностью.

1212
11 комментариев

Для нетехнарей все просто. Арендуйте самый простой сервер например на cloud hetzner за 3 евро в месяц, поставьте Ubuntu 20.04

Зайдите на него под рутом и выполните две команды из инструкции (по ссылке находиться скрипт который очень упрощает инсталляцию)

Дел на 10-15 минут.

2
Ответить

Привет
Строка в конфиге
iptables -A FORWARD -i %i -j ACCEPT; - не сработало у меня
Заменил на - iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT;
iptables D FORWARD -i %i -j ACCEPT;
Заменил на - iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT;

Может быть кому пригодится

2
Ответить

Ты спас меня! Еще бы объяснить почему у тебя работает а у автора нет

Ответить

Комментарий недоступен

Ответить

Ответил комментом ниже. Уверен у вас все получится.

Ответить

Платить деньги технарям, очевидно же

Ответить

F А у меня клиенты работают на андроид и линух, но не на винде. Не создается при установке адаптер. И непонятно, куда копать :(

Ответить