WireGuard: проверка конфигурации и AllowedIPs в изолированных netns

Ошибка в конфигурации VPN проявляется потерей доступа или, хуже, туннелем, который «работает», но пропускает лишнее. Проверить конфигурацию WireGuard можно заранее на одной машине: сервер и клиент запускаются в изолированных сетевых пространствах имён (netns), соединённых виртуальным кабелем. Вы получаете настоящее рукопожатие, трафик и проверку правил AllowedIPs без затрагивания рабочих интерфейсов. Ниже конфигурации, скрипт и ожидаемые результаты.
Статья опирается на логику направления «Сетевая безопасность» из методики зрелости Группы Сбер (источник); это методика для крупных компаний, мы используем её как ориентир и пересказываем своими словами. Проверка выполнена на Debian 12 (ядро 6.1, wireguard-tools 1.0.20210914) от root: после скрипта пространств имён и интерфейсов не осталось, рабочие настройки сети не менялись. Установка и развёртывание сервера: WireGuard: настройка VPN-сервера; изоляция тестов по тому же принципу: проверка правил в netns.
Что должно получиться
| Уровень | Что это значит на практике |
|---|---|
| 2. Гигиенический | Сеть сегментирована, удалённый доступ идёт через VPN с контролем, правила и конфигурации проверяются |
Критерии сформулированы нами по мотивам методики, это ориентир, а не оценка соответствия.
Конфигурации
Скрипт ниже создаёт два файла в формате wg-quick. Сервер (wgs0.conf) и клиент (wgc0.conf):
| Параметр | Сервер | Клиент |
|---|---|---|
Address |
10.77.0.1/24 |
10.77.0.2/24 |
ListenPort |
51820 |
не задаётся (случайный) |
PrivateKey |
ключ сервера | ключ клиента |
[Peer] PublicKey |
открытый ключ клиента | открытый ключ сервера |
PresharedKey |
общий предварительный ключ | тот же |
AllowedIPs |
10.77.0.2/32 (только адрес этого клиента) |
10.77.0.1/32 (только адрес сервера) |
Endpoint, PersistentKeepalive |
не нужны | 192.0.2.1:51820, 25 |
Принципы: на сервере в AllowedIPs каждого клиента стоит только его адрес с маской /32, на клиенте — только то, что должно идти через туннель (здесь адрес сервера; для выхода всего трафика через VPN — 0.0.0.0/0, но осознанно). Предварительный ключ добавляет защиту на случай появления квантового взлома открытых ключей и усиливает аутентификацию.
Скрипт проверки
Запускайте от root на машине, где установлены wireguard-tools и поддержка WireGuard в ядре (современные ядра Linux её содержат). Скрипт создаёт пространства zwgsrv, zwgcli и виртуальный кабель, генерирует временные ключи, запускает туннель, проверяет связь и полностью убирает за собой.
#!/bin/bash
set -u
S=zwgsrv; C=zwgcli
cleanup() { ip netns del $S 2>/dev/null; ip netns del $C 2>/dev/null; rm -rf /tmp/zwg; }
trap cleanup EXIT; cleanup
umask 077; mkdir -p /tmp/zwg; cd /tmp/zwg
SK=$(wg genkey); SP=$(echo $SK | wg pubkey); CK=$(wg genkey); CP=$(echo $CK | wg pubkey); PSK=$(wg genpsk)
cat > wgs0.conf <<EOF
[Interface]
Address = 10.77.0.1/24
ListenPort = 51820
PrivateKey = $SK
[Peer]
# клиент laptop-anna
PublicKey = $CP
PresharedKey = $PSK
AllowedIPs = 10.77.0.2/32
EOF
cat > wgc0.conf <<EOF
[Interface]
Address = 10.77.0.2/24
PrivateKey = $CK
[Peer]
PublicKey = $SP
PresharedKey = $PSK
Endpoint = 192.0.2.1:51820
AllowedIPs = 10.77.0.1/32
PersistentKeepalive = 25
EOF
ip netns add $S; ip netns add $C
ip link add zwgv0 type veth peer name zwgv1
ip link set zwgv0 netns $S; ip link set zwgv1 netns $C
ip -n $S addr add 192.0.2.1/24 dev zwgv0; ip -n $S link set zwgv0 up; ip -n $S link set lo up
ip -n $C addr add 192.0.2.2/24 dev zwgv1; ip -n $C link set zwgv1 up; ip -n $C link set lo up
command -v wg-quick || { echo "wg-quick не установлен"; exit 3; }
echo "права файлов:"; stat -c '%a %n' wgs0.conf wgc0.conf
ip netns exec $S wg-quick up ./wgs0.conf 2>&1 | grep -vE "^\[#\] (ip link add|wg setconf|ip -4 address|ip link set mtu|ip link set up)" | head -3
ip netns exec $C wg-quick up ./wgc0.conf 2>&1 | grep -vE "^\[#\] (ip link add|wg setconf|ip -4 address|ip link set mtu|ip link set up)" | head -3
echo "=== пинг"; ip netns exec $C ping -c 2 -W 2 -q 10.77.0.1 | tail -2
echo "=== handshake"; ip netns exec $S wg show wgs0 | grep -E "latest handshake|allowed ips|endpoint"
echo "=== wg-quick предупреждение о правах"; chmod 644 wgc0.conf; ip netns exec $C wg-quick down ./wgc0.conf >/dev/null 2>&1; ip netns exec $C wg-quick up ./wgc0.conf 2>&1 | grep -i "world accessible" | head -1
Что проверяется и ожидаемый результат
| Проверка | Результат на проверке |
|---|---|
| Права файлов с ключами | 600 у обоих файлов (скрипт создаёт их с umask 077) |
| Пинг клиента до сервера через туннель (10.77.0.1) | 2 из 2, потерь 0% |
| Рукопожатие | У сервера в wg show видны endpoint клиента, allowed ips: 10.77.0.2/32 и latest handshake: 1 second ago |
Дополнительные проверки, выполненные отдельным запуском на том же стенде (команды wg set вместо wg-quick, с теми же параметрами):
| Проверка | Результат |
|---|---|
wg show на клиенте |
latest handshake: 1 second ago, transfer: 348 B received, 436 B sent, persistent keepalive: every 25 seconds; приватный и предварительный ключи показываются как (hidden) (в выводе их нужно скрывать при копировании в отчёты) |
Защита AllowedIPs: клиент отправляет пакеты с другим адресом источника (10.77.0.50), которого нет в AllowedIPs сервера |
100% потерь: сервер отбрасывает пакет, потому что адрес источника не соответствует ключу клиента |
| Порт сервера | UDP 51820 слушается на 0.0.0.0 и [::] в пространстве сервера: на рабочем сервере ограничьте его правилом firewall |
| Клиент подменили ключом без регистрации на сервере | Рукопожатия нет, пинг даёт 100% потерь; на сервере остаётся только старое время последнего рукопожатия |
Последние две строки показывают главное свойство WireGuard: сервер отвечает только на пакеты от зарегистрированных ключей, а AllowedIPs работает как фильтр источника и как таблица маршрутов.
Типовые ошибки в конфигурации
| Ошибка | Последствия и как исправить |
|---|---|
На сервере у клиента AllowedIPs = 10.77.0.0/24 или 0.0.0.0/0 |
Клиент может представляться любым адресом из подсети (подмена другого клиента). Используйте только его адрес /32 |
Два клиента с одинаковым адресом в AllowedIPs |
Работает только последний; связь нестабильна. Назначайте уникальные адреса |
| Файл конфигурации доступен всем | Закрытый ключ читают другие пользователи. Права 600, владелец root; проверяйте командой stat -c '%a %n' файл |
Нет PersistentKeepalive у клиента за NAT |
Туннель «засыпает», и сервер не может отправить пакеты первым. Задайте 25 секунд |
| Порт UDP закрыт на firewall | Нет рукопожатия, пинга нет. Откройте порт: firewall в Linux |
| Клиент должен выходить в интернет через сервер, но маршрутизация не включена | Нужны net.ipv4.ip_forward=1 и правила трансляции адресов на сервере; проверка этой части выходит за рамки статьи |
Эксплуатация ключей
- Закрытые ключи создаются на устройстве клиента и не передаются; на сервер передаётся только открытый ключ.
- Для каждого устройства свой ключ: потеря устройства закрывается удалением одного клиента (
wg set wg0 peer ОТКРЫТЫЙ_КЛЮЧ removeи удаление из файла). - Список клиентов ведите в реестре с владельцем и датой выдачи; при увольнении отзывайте доступ: отзыв прав при увольнении.
- Для критичного доступа добавьте второй фактор на уровне приложений или шлюза: MFA для SSH и WireGuard.
- Журналы подключений: WireGuard не пишет события входа сам; используйте время последнего рукопожатия из
wg showи собирайте его в мониторинг.
Диагностика
| Симптом | Причина и что делать |
|---|---|
Скрипт сообщает, что wg-quick не установлен |
Установите пакет wireguard-tools (wireguard) |
| Ошибка создания интерфейса типа wireguard | В ядре нет модуля или нет прав. Проверьте версию ядра и modprobe wireguard |
| Нет рукопожатия | Неверные ключи, неверный Endpoint или порт закрыт. Проверьте ключи (открытый ключ одной стороны в конфигурации другой), доступность UDP-порта |
| Рукопожатие есть, пинга нет | Не те адреса в AllowedIPs или на интерфейсе. Сверьте с таблицей: у каждой стороны в AllowedIPs адрес противоположной стороны |
| После скрипта остались интерфейсы | Прерывание на середине. Удалите пространства ip netns del zwgsrv, ip netns del zwgcli |
Где это в модели зрелости
Материал относится к направлению «Сетевая безопасность» (материалы направления, карта зрелости). Уровень 2 требует удалённого доступа через VPN с контролем: воспроизводимая проверка конфигурации и учёт ключей делают этот доступ управляемым.
Как проверить
- Скрипт проверки выполняется без ошибок: рукопожатие есть, пинг проходит, подмена адреса и неверный ключ блокируются.
- На сервере у каждого клиента в
AllowedIPsтолько его адрес /32, файлы с ключами имеют права 600. - Порт UDP открыт только нужным адресам или защищён ограничениями; клиенты за NAT имеют keepalive.
- Список клиентов и их ключей ведётся, отзыв проверен на тестовом клиенте.
Источники
- Методика оценки уровня зрелости кибербезопасности компании, Группа Сбер: sberbank.ru.
- Документация и описание протокола WireGuard: wireguard.com; руководства
man wg,man wg-quick. - NIST SP 800-77 Rev. 1, Guide to IPsec VPNs (общие принципы защищённого удалённого доступа): csrc.nist.gov. Международная практика, не российский норматив.






















