Короткий ответ
Пока wg show пишет latest handshake: 0 seconds ago нет и never, полезного трафика не будет. Сначала докажите, что UDP 51820 доходит до vpn.example.com, что endpoint резолвится в актуальный WAN IP, что публичные ключи не перепутаны местами и что часы обеих сторон не уехали больше чем на ~180 секунд. Не переустанавливайте WireGuard и не меняйте LAN 10.0.10.0/24, пока нет пакетов handshake на сервере.
Снимите tcpdump на WAN сервера и wg show на клиенте в одну минуту. Если на сервере тишина — проблема до демона (маршрут, NAT, фильтр, DNS имени). Если пакеты есть, а handshake не завершается — ключ, ListenPort или часы.
Симптомы и как отличить
Клиент:
- интерфейс
wg0UP, адрес10.8.0.10/24есть; latest handshakeотсутствует или старше десятков минут при попытке ping;transferнулевой в обе стороны.
На сервере в тот же момент нет входящих UDP на 51820 либо они есть, но пир не появляется.
Это другое, если:
- handshake свежий, ping молчит — handshake есть, трафика нет;
- туннель жил часами и внезапно «замер» с редкими handshake — NAT timeout, разрывы;
- Windows RAS (IKEv2/L2TP) не поднимается — это не WireGuard, смотрите IPsec/L2TP статьи.
Возможные причины
- UDP
51820режется на клиентском NAT, на WAN-firewall сервера или у провайдера (редко, но бывает «вычищают» нестандартный UDP). - Endpoint в конфиге — старый IP или имя
vpn.example.comсмотрит не туда (кэш DNS, «забыли» A-запись после смены белого адреса). - Перепутаны private/public: в
[Peer] PublicKeyвставлен свой ключ или ключ другого пира. - Сервер слушает другой порт (
ListenPort = 51821), клиент стучит в51820. - Часы: WireGuard отбрасывает слишком старые handshake-сообщения (порядка трёх минут). VM без NTP после паузы гипервизора — типичный кейс.
- Клиент за CGNAT без
PersistentKeepalive, сервер не знает, куда отвечать, если инициации нет — но первая инициация с клиента всё равно должна создать handshake, если UDP проходит. - Несколько туннелей с одним и тем же ключом на двух машинах: «ворует» сессию, handshake прыгает.
Диагностика
1. Что видит клиент
wg show
resolvectl query vpn.example.com
getent hosts vpn.example.com
ip route get $(getent ahostsv4 vpn.example.com | awk '{print $1; exit}')На Windows 11:
Resolve-DnsName vpn.example.com -Type A
Get-NetUDPEndpoint -LocalPort 51820 -ErrorAction SilentlyContinue
Get-VpnConnection | Format-List Name, ServerAddress, ConnectionStatus, TunnelTypeGet-VpnConnection относится к RAS. Для WireGuard for Windows смотрите лог менеджера и wg show. Если A-запись не та — дальше не идите.
2. Доходит ли UDP
На сервере, на WAN-интерфейсе:
tcpdump -n -i eth0 udp port 51820С клиента в этот момент:
ping -c 1 10.8.0.1
# или явно
wg show wg0Любая попытка ping к адресу из AllowedIPs должна инициировать handshake. Если tcpdump пуст — пакет не покинул клиент или умер по дороге. Проверьте исходящий:
tcpdump -n -i any udp port 51820на клиенте. Нет исходящих — локальный фильтр или туннель не active. Есть исходящие, нет на сервере — транзит/NAT/WAN ACL.
3. Ключи
Сравните отпечатки, не пересылайте private в чат:
wg show wg0 public-key
wg show wg0 preshared-keysНа клиенте [Peer] PublicKey = вывод wg show сервера. На сервере [Peer] PublicKey = публичный ключ этого клиента. PresharedKey, если используется, должен совпасть байт-в-байт на обеих сторонах; пустой с одной стороны и заданный с другой — handshake не сойдётся.
4. Порт и процесс
ss -ulnp | grep 51820
systemctl status wg-quick@wg0Если слушает 51821, а в клиенте Endpoint = vpn.example.com:51820, handshake не будет. DNAT на роутере «WAN 51820 → внутренний 51820» должен указывать на хост, где реально крутится wg.
5. Время
timedatectl status
chronyc trackingWindows:
w32tm /query /status
Get-DateРасхождение больше пары минут после долгой паузы VM — сначала NTP, потом снова wg show.
Решение
Сценарий A. UDP не доходит
- Разрешите только
51820/udpна WAN до хоста WireGuard. - На домашнем роутере клиента обычно ничего открывать не нужно: клиент сам инициирует. Исключение — если роль «сервера» у ноутбука за NAT.
- Проверьте, что провайдерский NAT не переписывает порт в другой (редко); тогда в
Endpointнужен фактический порт после проброса.
Постоянное правило — в nftables/ACL, не «выключенный firewall до понедельника».
Сценарий B. Неверный endpoint
Обновите A-запись vpn.example.com или пропишите актуальный IP временно для теста. Если IP меняется — динамический DNS, не ручная правка раз в квартал. После смены:
wg-quick down wg0
wg-quick up wg0Старый endpoint в runtime wg show не всегда обновляется сам, если DNS уже закэширован.
Сценарий C. Ключи перепутаны
Сгенерируйте пару заново только для сломанного пира:
wg genkey | tee /tmp/peer.key | wg pubkeyВставьте private только в [Interface] клиента, public — в [Peer] сервера. Старый пир с сервера удалите, чтобы не было двух записей с похожими ключами.
Сценарий D. Часы
Включите NTP, дождитесь синхронизации, не переводите часы руками на часы вперёд «для теста». Повторите handshake.
Сценарий E. Клиент за NAT, сервер за NAT
Один из двух должен иметь достижимый UDP endpoint. Если оба за CGNAT без проброса — нужен посредник или другой протокол с брокером. Keepalive:
PersistentKeepalive = 25на стороне за NAT. Это не создаст handshake, если UDP до сервера закрыт, но удержит маппинг после первого успеха. См. разрывы.
Как проверить, что проблема устранена
wg showОжидание: latest handshake секунды назад, ненулевой transfer после ping -c 3 10.8.0.1. На сервере tcpdump показывает UDP в обе стороны (или хотя бы запрос и ответ). Затем — ping в LAN только если это уже следующая задача; для этой статьи достаточно handshake + ping туннельного адреса пира.
Windows:
Test-NetConnection vpn.example.com -Port 51820UdpTestSucceeded здесь ненадёжен (UDP не handshake). Ориентир — wg show и ping 10.8.0.1, не «зелёный» Test-NetConnection.
Если не помогло
- UDP доходит, ключи сверены, часы ровные — ищите второй процесс WireGuard, который перехватывает тот же ключ (телефон + ноутбук с одним конфигом).
- Сервер в контейнере: проброшен TCP вместо UDP, или
network_modeбезNET_ADMIN//dev/net/tun. - Сравниваете с OpenVPN на
1194/udp— это другой демон, клиент OpenVPN. - Корпоративный SSL-inspection «ломает UDP» — обход только согласованным каналом, не трюками с портом 443, пока это не ваша политика.
Лестница целиком: диагностика VPN. Выбор протокола, если UDP безнадёжно режут: WireGuard или IPsec.
Профилактика
- Мониторинг: алерт, если handshake старше N минут при ожидаемом онлайн-пире.
- Документируйте ListenPort, DNAT и FQDN
vpn.example.com. - По пиру — уникальная ключевая пара, без шаринга конфига в общий чат.
- NTP на VPN-шлюзе и на VM-клиентах.
- После смены белого IP — проверка A-записи до звонков «VPN умер».
FAQ
WireGuard слушает, nmap снаружи «filtered» — это смерть?
Нет. Handshake — UDP без баннера. filtered не отличает «дроп» от «нет ответа не-WG пакетам». Смотрите tcpdump во время реальной попытки клиента.
Нужен ли IPv6?
Только если endpoint резолвится в AAAA, а UDP6 по пути режется. Тогда либо A-запись и Endpoint в IPv4, либо разрешите UDP6. Смешанный «A живой, ходит по AAAA» даёт тишину.
Можно ли сменить порт на 443/udp?
Технически да, если ничего больше не слушает 443/udp. Это не маскировка под HTTPS (это TCP). Меняйте осознанно на обеих сторонах и на DNAT.
Почему после сна ноутбука handshake пропадает?
NAT забыл маппинг, или часы «прыгнули». Keepalive и NTP; не пересоздавайте ключи после каждого сна.
Get-VpnConnection пустой, а WireGuard в трее есть
Ожидаемо. RAS и WireGuard for Windows — разные стеки. Для RAS смотрите IKEv2/L2TP статьи, для WG — wg show.