WireGuard: handshake есть, а трафика нет
Вы запустили команду wg show, увидели строку latest handshake с недавним временем — вроде бы всё подключилось, — но пинг не проходит, сайты не открываются, а в браузере крутится «загрузка». Это самая частая жалоба на WireGuard, и она сбивает с толку именно потому, что «рукопожатие» звучит как «соединение работает». На деле это не так: handshake подтверждает только один узкий этап, а до реального трафика дело может и не дойти по четырём разным причинам. Разберём каждую по шагам — с командами для проверки и точным исправлением, без пропуска этапов.
Содержание
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Что на самом деле означает handshake — и почему этого мало
Прежде чем чинить, важно понять, что именно проверяет команда wg show. Наберите в терминале сервера (или клиента, если это компьютер с установленным WireGuard):
sudo wg show
Если вы никогда всерьёз не пользовались терминалом — это окно для текстовых команд вместо кликов мышкой, а sudo в начале значит «выполнить с правами администратора» (система спросит пароль). Вывод будет примерно такой:
interface: wg0
public key: AbCdEf...
private key: (hidden)
listening port: 51820
peer: XyZ123...
endpoint: 203.0.113.10:51234
allowed ips: 10.0.0.2/32
latest handshake: 14 seconds ago
transfer: 1.48 KiB received, 148 B sent
Строка latest handshake: 14 seconds ago — это «пинг-понг» шифрования: клиент и сервер обменялись ключами, подтвердили подлинность и договорились о сеансовых ключах. Это происходит на уровне криптографии, ещё до отправки хотя бы одного пакета с вашими данными. WireGuard обновляет handshake автоматически каждые примерно 2 минуты (keepalive), даже если вы ничего не делаете.
Обратите внимание на строку transfer: 1.48 KiB received, 148 B sent — это крохи, ровно объём служебных пакетов handshake. Если бы трафик реально шёл, цифры росли бы килобайтами и мегабайтами при каждой проверке. Маленькие статичные значения — диагностический признак: канал зашифрован, но данные по нему не ходят. Дальше разбираем, на каком этапе они теряются.
Причина 1: неверный AllowedIPs — самая частая ошибка
AllowedIPs — это строка в конфиге WireGuard, которая встречается дважды с разным смыслом, и путаница между ними — источник девяти из десяти случаев «handshake есть, трафика нет».
На клиенте AllowedIPs в секции [Peer] говорит операционной системе, какой трафик вообще направлять в туннель. Откройте конфиг клиента:
cat /etc/wireguard/wg0.conf
Если там стоит только внутренняя подсеть VPN, например:
[Peer]
PublicKey = ...
Endpoint = 203.0.113.10:51820
AllowedIPs = 10.0.0.0/24
— то в туннель уйдёт только трафик к адресам из 10.0.0.0/24, а запрос к 8.8.8.8 или любому сайту уйдёт напрямую, минуя VPN. Внешне это выглядит как «VPN не работает», хотя туннель работает штатно — просто пропускает лишь часть трафика. Чтобы весь интернет-трафик клиента шёл через сервер (полный туннель), нужно:
AllowedIPs = 0.0.0.0/0
Это значит «все IP-адреса — направлять в туннель». Если же вам нужен частичный (split) туннель — например, только доступ к внутренним серверам компании — узкий AllowedIPs правильный, и отсутствие «трафика» для остального интернета — ожидаемое поведение, а не поломка.
На сервере та же строка в секции [Peer] работает иначе и куда коварнее: это не маршрутизация, а фильтр входящих пакетов. Сервер расшифровывает пакет от пира, смотрит на его внутренний исходный IP и сверяет с AllowedIPs, заданным для этого пира. Если адрес не совпадает — пакет молча уничтожается, без ошибки и записи в лог. Handshake при этом проходит успешно, потому что проверяется на уровне ключей, а не IP внутри пакетов. Именно этот механизм — источник ровно того симптома, что вынесен в заголовок статьи.
Проверьте, что сервер реально ожидает от каждого клиента:
sudo wg show wg0 allowed-ips
Вывод покажет пары «публичный ключ пира — разрешённые ему IP». Сверьте со строкой Address в конфиге клиента — адрес, который он сам себе присваивает на интерфейсе wg0. Если клиент считает себя 10.0.0.5, а на сервере для его ключа прописано AllowedIPs = 10.0.0.2/32 (например, скопировали блок другого пира и забыли поправить) — сервер отбросит весь его трафик. Исправление — привести значения в соответствие и перезапустить интерфейс:
sudo systemctl restart wg-quick@wg0
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать VPSПричина 2: не включён IP forwarding на сервере
Даже при идеально настроенном AllowedIPs сервер не перешлёт трафик клиента дальше в интернет, если ядро Linux вообще не умеет пересылать пакеты между сетевыми интерфейсами. Эта настройка называется IP forwarding и по умолчанию выключена — защитный дефолт, ведь обычному серверу (не роутеру) пересылка не нужна.
sysctl — утилита для чтения и изменения параметров работающего ядра «на лету». Проверьте текущее состояние:
sysctl net.ipv4.ip_forward
Вывод net.ipv4.ip_forward = 0 значит «выключено» — вот ваша проблема, значение 1 — «включено». Включите немедленно (действует сразу, но слетит после перезагрузки):
sudo sysctl -w net.ipv4.ip_forward=1
Чтобы настройка сохранилась и после перезагрузки, добавьте её в файл конфигурации, который применяется при каждом старте системы:
echo "net.ipv4.ip_forward = 1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
Если сервер обслуживает и IPv6-клиентов, включите такой же параметр для IPv6:
sudo sysctl -w net.ipv6.conf.all.forwarding=1
echo "net.ipv6.conf.all.forwarding = 1" | sudo tee -a /etc/sysctl.conf
Без форвардинга симптом такой: внутренний адрес сервера (10.0.0.1) пингуется, а любой внешний — нет. Пакет клиента доходит до сервера и «упирается в стену»: ядро не пропускает его дальше на внешний интерфейс.
Причина 3: не настроен NAT/MASQUERADE
Форвардинг разрешает пакетам двигаться дальше, но не решает другую задачу: у клиентского пакета в качестве исходного адреса стоит внутренний IP туннеля (10.0.0.2) — он ничего не значит для внешнего интернета, и ответ от 8.8.8.8 не будет знать, куда возвращаться. NAT с маскарадингом (MASQUERADE) подменяет исходный адрес на внешний IP сервера перед отправкой наружу и обратно при возврате ответа — это и делает выход в интернет возможным.
Сначала выясните имя внешнего сетевого интерфейса — того, через который сервер сам смотрит в интернет:
ip route | grep default
В выводе будет строка вида default via 192.0.2.1 dev eth0 — eth0 (может быть ens3, enp1s0) и есть нужное имя. Дальше действуйте в зависимости от того, что установлено на сервере — iptables или более новый nftables.
Если используется iptables (классика для Ubuntu/Debian, AlmaLinux), проверьте, есть ли уже правило маскарадинга:
sudo iptables -t nat -L POSTROUTING -n -v
Если в списке нет строки с MASQUERADE, добавьте правило (замените eth0 на реальное имя интерфейса и 10.0.0.0/24 на реальную подсеть VPN из конфига сервера):
sudo iptables -t nat -A POSTROUTING -o eth0 -s 10.0.0.0/24 -j MASQUERADE
Это правило теряется после перезагрузки, если его не сохранить. Правильнее прописать его прямо в конфиг WireGuard — тогда оно ставится при поднятии туннеля и снимается при остановке:
[Interface]
Address = 10.0.0.1/24
PostUp = iptables -t nat -A POSTROUTING -o eth0 -s 10.0.0.0/24 -j MASQUERADE
PostDown = iptables -t nat -D POSTROUTING -o eth0 -s 10.0.0.0/24 -j MASQUERADE
Если используется nftables (по умолчанию во многих свежих дистрибутивах), проверьте текущие правила:
sudo nft list ruleset
Если таблицы для NAT нет, создайте её и добавьте правило маскарадинга:
sudo nft add table ip nat
sudo nft add chain ip nat postrouting { type nat hook postrouting priority 100 \; }
sudo nft add rule ip nat postrouting ip saddr 10.0.0.0/24 oifname "eth0" masquerade
Чтобы правило сохранилось после перезагрузки, сохраните набор правил в файл, который nftables подхватывает при старте (обычно /etc/nftables.conf):
sudo nft list ruleset | sudo tee /etc/nftables.conf
sudo systemctl enable nftables
Симптом отсутствующего NAT почти неотличим от отсутствующего форвардинга — оба дают «до сервера трафик доходит, дальше нет». Если после ip_forward=1 пинг наружу всё ещё не идёт — почти наверняка дело в NAT.
Причина 4: конфликт AllowedIPs между несколькими пирами
Эта причина реже встречается новичкам с одним клиентом, но становится головной болью, как только на сервере появляется второй, третий, десятый пир. WireGuard использует значения AllowedIPs всех пиров вместе как единую внутреннюю таблицу маршрутизации: получив расшифрованный пакет, ядро решает, какому пиру он «принадлежит», ориентируясь именно на эти подсети. Если у двух пиров указана одна и та же или пересекающаяся подсеть — например, по невнимательности скопировали блок [Peer] для нового клиента и забыли поменять адрес — WireGuard либо тихо перезапишет маршрут в пользу последнего правила, либо начнёт направлять ответный трафик не тому пиру.
Проверьте все текущие назначения одной командой:
sudo wg show wg0 allowed-ips
Вывод — список пар «ключ пира — подсети», например:
AbCdEf...= 10.0.0.2/32
XyZ123...= 10.0.0.3/32
QwErTy...= 10.0.0.2/32
Здесь сразу видна ошибка: у первого и третьего пира одинаковый адрес 10.0.0.2/32 — классический результат копипасты конфига при добавлении нового клиента. Правило простое: у каждого пира должен быть свой уникальный AllowedIPs, обычно единственный адрес этого клиента с маской /32 (IPv4) или /128 (IPv6):
[Peer]
PublicKey = QwErTy...
AllowedIPs = 10.0.0.4/32
Если пиров много и глазами конфликт не найти, проверьте конфиг сервера текстом:
grep -A2 "\[Peer\]" /etc/wireguard/wg0.conf | grep AllowedIPs | sort | uniq -d
Команда выведет только повторяющиеся строки AllowedIPs — если результат не пустой, вот ваш конфликт. После исправления перечитайте конфиг без разрыва уже установленных соединений других клиентов:
sudo wg syncconf wg0 <(sudo wg-quick strip wg0)
Пошаговая диагностика: проверьте всё по порядку
Если хочется не гадать, а быстро пройтись по всем причинам подряд, выполните на сервере эту последовательность:
# 1. Форвардинг включён?
sysctl net.ipv4.ip_forward
# 2. NAT настроен? (для iptables)
sudo iptables -t nat -L POSTROUTING -n -v
# NAT настроен? (для nftables)
sudo nft list ruleset | grep masquerade
# 3. Какие AllowedIPs назначены каждому пиру
sudo wg show wg0 allowed-ips
# 4. Есть ли повторяющиеся подсети между пирами
grep -A2 "\[Peer\]" /etc/wireguard/wg0.conf | grep AllowedIPs | sort | uniq -d
# 5. Реально ходит ли трафик (счётчик растёт при новом ping с клиента)
sudo wg show wg0 transfer
Пункт 5 — практический тест: запустите с клиента ping -c5 8.8.8.8 и сразу повторите sudo wg show wg0 transfer на сервере. Если цифры received/sent заметно выросли — трафик идёт через туннель, и оставшаяся проблема уже не в WireGuard, а дальше по цепочке (правила фаервола на выход, сам провайдер). Если цифры не сдвинулись — возвращайтесь к причинам 1–4 по порядку: они перечислены от самой частой к самой редкой не случайно.
Если разбираться в унаследованном или запутанном конфиге сложно, иногда быстрее поднять WireGuard заново на чистом VPS — так проще увидеть, где накопились расхождения, чем распутывать старые правки.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать VPSОбсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Частые вопросы
Handshake обновляется каждые пару минут — это нормально?
Да, это штатное поведение: WireGuard периодически обновляет сеансовые ключи (keepalive), даже без реальных данных в туннеле. Само обновление latest handshake не говорит о том, ходит ли трафик — смотрите на счётчик transfer.
Почему в логах нет ошибок, хотя пакеты явно теряются?
Отбрасывание пакетов по несовпадению AllowedIPs — штатная тихая функция WireGuard, а не сбой, в журнал она не пишется. Проверяйте вручную командой wg show wg0 allowed-ips, сравнивая с реальным адресом клиента.
Если добавить нового клиента, старые отвалятся?
Нет, если у каждого пира уникальный AllowedIPs. Отваливаются как раз те клиенты, чьи подсети случайно пересеклись с новым.
С чего начать, если сервер только что настроен и не работает вообще?
С формулы «форвардинг → NAT → AllowedIPs клиента → AllowedIPs сервера» — в этом порядке чаще всего находится причина у новой установки, конфликты между пирами пока не актуальны.
Как оплатить VPS под WireGuard из России?
В MAATRIX — картой российского банка, через СБП или криптовалютой, без иностранной карты и посредников.
Нужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.