Конкурс инструкций
Разработка
Alina Iudina

Строим 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 [email protected]

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

[email protected]:/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 [email protected]

На сервере добавляем в файл /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 [email protected] [email protected]:/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 [email protected]:/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 [email protected]:/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

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

[email protected]:/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 [email protected]:/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 [email protected]

На сервере в конфигурационный файл /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 [email protected]

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

[email protected]:/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 [email protected]:/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 [email protected]

Конфигурационный файл 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 открываем конфигурационный файл и нажимаем кнопку «подключение».

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

Удаленный 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 [email protected]

Создадим конфигурационный файл для 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:

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

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

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

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»

[email protected]:/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 - оптимальное решение для организации удаленного доступа к сетям малых офисов и домашним сетям. Он прост в настройке, работает на всех распространенных платформах и обладает хорошей производительностью.

0
9 комментариев
Написать комментарий...
Евгений Рюмин

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

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

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

Ответить
Развернуть ветку
Турецкий микроскоп

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

Ответить
Развернуть ветку
Евгений Рюмин

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

Ответить
Развернуть ветку
Турецкий микроскоп

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

Ответить
Развернуть ветку
Евгений Рюмин

Я представляю это так, что современный человек умеет гуглить) Если с этим проблемы и загуглить “как зайти под рутом на ubuntu с windows/mac/other os” сложно, то можно задать вопрос под комментом, думаю найдутся добрые люди которые помогут)

Было бы намерение, и упорство, тогда человек сможет горы свернуть.

Ответить
Развернуть ветку
Турецкий микроскоп

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

Ответить
Развернуть ветку
Alina Iudina
Автор

Спасибо за дополнение, попробую дать развернутый ответ.

Конечно, присутствует некоторый уровень абстракции. Что такое VPS, для чего они нужны, как их выбирать и администрировать - все это темы не на одну статью, и они уже написаны. Не рассмотрены правила iptables, менеджер пакетов apt и система инициализации systemd. Даже понятие VPN введено очень условно, предполагается, что аудитория имеет некоторое представление о этой технологии.

Конечно, гуманитариям многое может показаться непонятным и не раскрытым, но раздел - технический, в описании указано, что это сообщество разработчиков:

В общем, классический мир разработки, системного администрирования и QA.
Ответить
Развернуть ветку
Alina Iudina
Автор

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

Ответить
Развернуть ветку
Alex

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

Ответить
Развернуть ветку
Читать все 9 комментариев
null