WireGuard handshake did not complete: разбор причин и способы решения
Ошибка WireGuard handshake did not complete возникает из-за сетевых экранов, неправильных ключей, проблем с NAT или рассинхронизации времени. В статье — системный разбор причин и пошаговые проверки для быстрого восстановления соединения.
Содержание
Ошибка WireGuard handshake did not complete — одна из самых частых при настройке VPN. Она появляется в логах клиента или сервера, когда пиры не могут установить сеанс связи. При этом пользователь часто видит, что интерфейс поднят, но трафик не ходит. В этой статье разберём, что означает этот сбой, какие причины встречаются чаще всего и как правильно диагностировать проблему — от наиболее вероятной к редкой.
Что означает ошибка WireGuard handshake did not complete?
WireGuard использует криптографический протокол на основе постквантовой схемы? На самом деле — на основе Curve25519 и ChaCha20. Чтобы начать передачу данных, пиры должны выполнить рукопожатие: обменяться публичными ключами, подтвердить подлинность и согласовать параметры шифрования. Рукопожатие выполняется поверх UDP на определённом порту — обычно 51820 по умолчанию.
Если клиент в течение некоторого времени не получает ответа от второго пира, в лог пишется сообщение Handshake did not complete (или Handshake for peer did not complete). Это не ошибка в смысле сбоя программы, а индикатор того, что сетевой пакет не дошёл до адресата или был отвергнут. Поэтому диагностика сводится к проверке сетевой связности, конфигурации и окружения.
Типичные причины и их систематизация
Чтобы не перебирать наугад, разделим причины на группы:
- Сетевые фильтры — файрвол, список контроля доступа (ACL) провайдера, блокировка UDP на маршрутизаторе или у хоста.
- Криптографическая несостыковка — неправильные публичные или приватные ключи, неверно указан
PublicKeyпира. - NAT и маршрутизация — отсутствие keepalive, неверный endpoint, проблема с перезаписью порта.
- Системное время — разница более чем на несколько минут нарушает проверку временных меток.
- MTU и IP-адресация — слишком большой MTU фрагментирует пакеты, или AllowedIPs заданы с ошибками.
Важно понимать, что клиент и сервер — это понятия относительные. В WireGuard все пиры равны, но обычно инициатор — это клиент, а отвечающий — сервер. Ошибка может возникать на любой стороне.
Пошаговая проверка: от вероятного к редкому
Не пропускайте шаги — это сэкономит время. Порядок составлен по статистике обращений.
1. Проверьте файрвол и доступность UDP-порта
Первым делом убедитесь, что порт, на котором слушает сервер WireGuard, открыт. С клиента выполните:
nc -u -vz <IP_сервера> 51820
или используйте nmap -sU -p 51820 <IP_сервера> (проверьте для своей ОС). Если порт недоступен, откройте его на файрволе. Типичная ошибка — правило разрешает TCP, но не UDP. Также проверьте, не блокирует ли порт провайдер или внешний брандмауэр хостинга.
2. Убедитесь в правильности ключей и конфигурации
На клиенте в файле конфигурации секции [Peer] должен быть указан публичный ключ сервера, а на сервере — публичный ключ клиента. Приватные ключи не должны совпадать. Проверьте, нет ли лишних пробелов или переносов строк. Проще всего скопировать ключи вручную или использовать wg show для сравнения.
Также проверьте, что в [Interface] указан приватный ключ, а не публичный. Это распространённая ошибка новичков.
3. Проверьте системное время
WireGuard требует синхронизации времени между пирами. Выполните на обоих устройствах date и убедитесь, что разница не превышает пару минут. Используйте NTP (chrony, systemd-timesyncd, ntpd) для автоматической синхронизации.
4. Проверьте настройки NAT и keepalive
Если устройство находится за NAT, инициатор соединения должен отправлять keepalive каждые 25 секунд, чтобы сохранить привязку. Убедитесь, что в конфигурации клиента задан PersistentKeepalive = 25 (или другое значение). Если сервер тоже за NAT, он также может нуждаться в этой опции. В случае, когда endpoint указывает на внешний IP, а порт переадресуется на внутренний, проверьте правила DNAT.
5. Проверьте MTU и фрагментацию
Пакеты WireGuard имеют накладные расходы (~60-80 байт). Если MTU на интерфейсе слишком велик, пакеты фрагментируются, что иногда приводит к потере. Уменьшите MTU до 1420 или 1400 на интерфейсе WireGuard (например, MTU = 1420 в [Interface]). Также проверьте, что AllowedIPs указаны корректно — если клиенту не разрешены нужные подсети, он будет считать всё недоступным.
Частые ошибки при диагностике
Даже опытные администраторы тратят время впустую. Вот что делают неправильно:
- Проверяют только TCP-порт, хотя WireGuard использует UDP.
- Смотрят логи только на клиенте, игнорируя сервер (где может быть видно входящие пакеты).
- Не учитывают, что в некоторых регионах определенные UDP-порты блокируются на уровне провайдера — пробуйте другой порт.
- Сбрасывают конфигурацию и удаляют ключи без предварительной проверки времени и сетевой связности.
Решения, если ничего не помогло
Если шаги не дали результата, попробуйте:
- Включите подробное логирование на сервере:
wg show wg0 listen-portиtcpdump -i any udp port 51820на обоих сторонах, чтобы увидеть, доходят ли пакеты. - Временно отключите файрвол (на тестовой среде) — это изолирует проблему.
- Смените порт WireGuard (например, 53 для обхода блокировок DNS в некоторых сетях).
- Проверьте, не конфликтует ли с другими VPN-клиентами.
- Переустановите WireGuard, обновите модуль ядра и инструменты wg-tools.
Заключение
Ошибка handshake did not complete решается системным подходом. Начните с сетевой связности (UDP), затем проверьте ключи и время, потом NAT/MTU. В большинстве случаев причина — банальный файрвол или опечатка в ключе. Если вы используете облако, проверьте также security group инстанса. Не забывайте, что инструкции для разных версий WireGuard могут отличаться — всегда сверяйтесь с официальной документацией для вашей ОС.
Мини-чеклист
- Проверьте, что UDP-порт для WireGuard открыт на файрволе и маршрутизаторе.
- Сравните публичные ключи: на клиенте — ключ сервера, на сервере — ключ клиента.
- Синхронизируйте время на всех пирах через NTP.
- Добавьте PersistentKeepalive = 25 на клиенте, если он за NAT.
Частые ошибки
- Проверка только TCP-портов вместо UDP.
- Игнорирование состояния времени на устройстве.
- Использование неверного ключа в секции [Interface] (приватного вместо публичного).
- Слишком большой MTU на интерфейсе WireGuard.
Источники и документация
FAQ
Почему ошибка handshake появляется сразу после подключения?
Скорее всего, файрвол блокирует UDP-пакеты, или сервер настроен не на тот порт. Проверьте доступность порта командой nc или nmap.
Может ли проблема быть вызвана неправильно указанным AllowedIPs?
Да, если в AllowedIPs клиента не указан адрес сервера или подсеть, клиент может не отправлять рукопожатие. Убедитесь, что AllowedIPs содержит нужные префиксы, например 0.0.0.0/0 или конкретные подсети.
Что делать, если keepalive включён, а рукопожатие всё равно не завершается?
Проверьте, что на маршрутизаторе настроена переадресация порта на внутренний IP сервера, и что у сервера нет внутреннего файрвола, блокирующего входящие UDP. Также проверьте таблицу маршрутизации на сервере.
Нужен быстрый рабочий доступ?
Если сейчас важнее вернуть подключение, чем продолжать ручную диагностику, переходите к прямому сценарию оформления доступа.
Получить доступ