Раньше VPN для команды означал лицензию, центр сертификации и неделю на подключение сотрудников. WireGuard заменил всё это одним UDP-портом и парой ключей на каждое устройство. В этом руководстве мы построим VPN по схеме «звезда» (hub-and-spoke) на VPS-1, самом дешёвом из наших тарифов: с отдельными ключами для каждого устройства, раздельным туннелированием (split tunnelling), при котором через туннель идёт только приватный трафик, и с IPv6 внутри туннеля — просто потому, что нет причин обходиться без него.
Схема сети
VPS — это хаб. Каждый ноутбук, телефон и офисный сервер — периферийный узел (spoke) со своей парой ключей и своим адресом в туннеле. Узлы общаются друг с другом через хаб и добираются до любого приватного сервиса, который вы разместите за ним. Публичный трафик по-прежнему идёт через обычное соединение каждого устройства, поэтому ничьи видеозвонки не ходят окружным путём.
- Сеть туннеля:
10.66.0.0/24иfd66::/64. - Хаб:
10.66.0.1, слушает UDP 51820. - Периферийные узлы: от
10.66.0.10и выше, по одному адресу на устройство, без общих.
Хаб за десять команд
apt install -y wireguard
umask 077 && wg genkey | tee /etc/wireguard/hub.key | wg pubkey > /etc/wireguard/hub.pub
cat > /etc/wireguard/wg0.conf <<EOF
[Interface]
Address = 10.66.0.1/24, fd66::1/64
ListenPort = 51820
PrivateKey = $(cat /etc/wireguard/hub.key)
EOF
sysctl -w net.ipv4.ip_forward=1 net.ipv6.conf.all.forwarding=1
echo -e "net.ipv4.ip_forward=1\nnet.ipv6.conf.all.forwarding=1" > /etc/sysctl.d/70-wg.conf
ufw allow 51820/udp comment wireguard
systemctl enable --now wg-quick@wg0
Именно пересылка пакетов (forwarding) позволяет узлам общаться друг с другом через хаб. Без правила NAT хаб не выводит узлы в интернет, и в этом как раз смысл раздельного туннелирования; добавьте такое правило позже, если вам понадобится вариант с полным туннелем для публичного Wi-Fi.
Добавление устройства
Пару ключей для каждого устройства по возможности генерируют на самом устройстве, чтобы закрытый ключ никуда не передавался. На ноутбуке с приложением WireGuard создайте пустой туннель и скопируйте его открытый ключ; на телефоне приложение показывает его в настройках туннеля. Затем зарегистрируйте устройство на хабе:
wg set wg0 peer <DEVICE_PUBLIC_KEY> allowed-ips 10.66.0.10/32,fd66::10/128
wg-quick save wg0
А затем вставьте вот это в конфигурацию туннеля на устройстве:
[Interface]
PrivateKey = <generated on the device>
Address = 10.66.0.10/32, fd66::10/128
DNS = 10.66.0.1
[Peer]
PublicKey = <contents of /etc/wireguard/hub.pub>
Endpoint = hub.example.com:51820
AllowedIPs = 10.66.0.0/24, fd66::/64
PersistentKeepalive = 25
AllowedIPs на устройстве — это переключатель раздельного туннелирования: в нём перечислена только сеть туннеля, поэтому через WireGuard маршрутизируется лишь этот трафик. PersistentKeepalive не даёт устареть записи NAT на телефонах и домашних роутерах. Для телефона сгенерируйте QR-код из конфигурации на хабе командой qrencode -t ansiutf8 < device.conf и отсканируйте его; приложение в один клик WireGuard из нашей формы заказа делает именно это для пяти устройств при развёртывании.
Приватный DNS (по желанию)
Строка DNS = 10.66.0.1 работает, только если хаб умеет разрешать имена. Простой путь — unbound в роли локального рекурсивного резолвера с несколькими статическими записями для ваших приватных хостов:
apt install -y unbound
cat > /etc/unbound/unbound.conf.d/hub.conf <<'EOF'
server:
interface: 10.66.0.1
interface: fd66::1
access-control: 10.66.0.0/24 allow
access-control: fd66::/64 allow
local-zone: "team.internal." static
local-data: "git.team.internal. A 10.66.0.20"
local-data: "wiki.team.internal. A 10.66.0.21"
EOF
systemctl restart unbound
Теперь git.team.internal открывается с любого узла, а публичные имена хаб разрешает рекурсивно сам, а не DNS кофейни, в которой вы сидите.
Серверы за хабом
Любой другой сервер CheapServ тоже может присоединиться как периферийный узел — со своим ключом и адресом — и быть доступным только через туннель. Обычная схема такая: привязать административные интерфейсы, базы данных и дашборды к туннельному адресу сервера, а соответствующие порты на публичном файрволе закрыть полностью. База данных, которая слушает только 10.66.0.20, из интернета недоступна, что бы ни пробовали боты-сканеры.
Что тянет VPS-1
Шифрование ChaCha20 в WireGuard на современном процессоре работает на скорости в несколько гигабит в секунду на ядро, так что один vCPU не станет узким местом. Узким местом станет порт: у VPS-1 порт 1 Gbps и 4 TB трафика в месяц, а это больше, чем команда из десяти человек пропустит через VPN для администрирования. По нашему собственному опыту, хаб с 30 пирами в простое потребляет 1% CPU и 40 MB RAM. Если позже вы пустите через него весь интернет-трафик, следить придётся за полосой, а не за процессором.
Эксплуатация
wg showвыводит пиров со временем последнего рукопожатия; если рукопожатия с пиром не было уже несколько минут, он либо не в сети, либо настроен неверно.- Удаление устройства — это
wg set wg0 peer <KEY> remove && wg-quick save wg0; никаких списков отзыва, никаких сроков действия: ключ просто перестаёт работать. - Включайте
/etc/wireguard/в резервное копирование вместе с остальной конфигурацией; закрытый ключ хаба — единственный секрет, который имеет значение. - Меняйте ключ хаба раз в год или при потере ноутбука; после этого каждому устройству понадобится новый открытый ключ — хороший повод заодно почистить список пиров.
Если вы вообще не хотите содержать хаб, дополнение Tailscale даёт ту же mesh-сеть, но с облачным сервером координации; платить за это приходится тем, что третья сторона знает, кто ваши пиры. Для команды, которая хочет держать ключи в своих руках, двадцать строк конфигурации WireGuard на VPS за $3 — вариант, который трудно превзойти.
