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