#crypto
6 min readOct 6, 2022

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

Наиболее популярные решения с открытым исходным кодом для построения виртуальных частных сетей — «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 клиента. Перезапустим службу и убедимся, что все настроено корректно:

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

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

Сборки 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-туннель:

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

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

👨 Удаленный 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:

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

sudo apt install qrencode

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

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

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

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

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

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

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

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

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

apt install openresolv