WireGuard PersistentKeepalive: сохраните сопоставление NAT живым
Если обратное соединение работает только сразу после отправки трафика узлом, сопоставление истекает. Настройте keepalive за маршрутизатором и затем прочитайте реальный тайм-аут.
Домашний блок открывает туннель и без проблем достигает облачного сервера. Облачный сервер может достигать домашнего приложения минуту или две после того, как домашний блок последний раз что-то отправил, а затем перестаёт. В журнале WireGuard ничего не появляется, ошибка рукопожатия не сообщается, а перезапуск туннеля кратко это исправляет. Этот шаблон — истекающее сопоставление, а не сломанный туннель, и приведённое ниже руководство подтверждает это перед любыми изменениями.
Убедитесь, что шаблон — это истечение при простое
Отличительная деталь — время. Если обратное соединение работает сразу после того, как домашний узел отправляет трафик, и перестаёт работать после тихого интервала, путь в порядке, а состояние посередине — нет. Если оно никогда не работало, даже сразу после трафика, это неверный диагноз.
sudo wg show wg0 latest-handshakes
sudo wg show wg0 endpoints
sudo wg show wg0 transfer
Запустите первые две команды сразу после того, как домашний узел что-то отправит, подождите пять минут и запустите их снова. Метка времени рукопожатия, которая обновляется по расписанию без новой конечной точки, говорит вам, что туннель жив. Изменилась способность незапрошенных пакетов приходить снаружи, а это свойство пути, а не туннеля.
Затем сделайте обратную попытку и посмотрите на счётчики передачи. Если облачная сторона отправляет байты, а домашняя не получает ни одного, пакет покинул облако и погиб по пути в устройстве, хранящем состояние. Это та подпись, которую вы ищете. Если оба счётчика двигаются, туннель доставил пакет, и подозреваемый — приложение.
Поместите keepalive на узел за маршрутизатором
Постоянные keepalive поддерживают сопоставление NAT и любое состояние межсетевого экрана живым, отправляя по расписанию небольшой аутентифицированный пакет. Настройка относится к машине за маршрутизатором, в её записи для удалённого узла, потому что именно эта сторона своим исходящим пакетом создаёт состояние.
[Peer]
PublicKey = <cloud peer public key>
AllowedIPs = 10.71.0.1/32
PersistentKeepalive = 25
Объедините её с существующим разделом узла. Добавление второго блока с тем же открытым ключом не является правильным способом добавления параметров, и wg-quick не объединит их за вас. Задокументированные 25 секунд — это пример, выбранный, чтобы находиться ниже обычных тайм-аутов UDP, а не значение с особым смыслом.
Размещение той же директивы на облачной стороне этой проблеме не помогает. Пакеты этого узла и так приходят с публичного адреса, поэтому в важном направлении нечего сохранять. Это добавляет трафик и ничего не меняет.
Читайте таймеры вместо того, чтобы угадывать интервал
Keepalive работают, потому что приходят чаще, чем истекает состояние. Поэтому тайм-аут — это число, которое вам действительно нужно, и в Linux его можно прочитать на устройстве, выполняющем трансляцию:
sysctl net.netfilter.nf_conntrack_udp_timeout
sysctl net.netfilter.nf_conntrack_udp_timeout_stream
sudo conntrack -L -p udp --dport 51820
Первое значение — тайм-аут для UDP-потока, который наблюдался только в одном направлении, а второе применяется после того, как замечены ответы. Оба обычно короткие, и замолчавшее сопоставление будет следовать тому, что применимо к вашему потоку.
Сравните это число со своим интервалом. Keepalive в 25 секунд при тайм-ауте 30 секунд работает; тот же keepalive при тайм-ауте 15 секунд не работает. Никакое количество повторов не меняет эту арифметику. Некоторые домашние маршрутизаторы и мобильные операторы используют гораздо более короткие значения, чем значение по умолчанию в Linux, поэтому конфигурация, работающая в одной сети, сбоит в другой.
| Observation | What it means | Reasonable response |
|---|---|---|
| Works after traffic, dies when idle | Mapping or firewall state expiring | Lower the keepalive interval |
| Never works, even immediately | No return route, listener or firewall | Stop tuning keepalive |
| Works for hours, then dies once | Carrier-side translation or address change | Check the endpoint and logs together |
Проверьте слушателя и межсетевой экран отдельно
Живое сопоставление необходимо и недостаточно. Приложение на домашнем блоке должно слушать правильный адрес, а межсетевой экран хоста должен разрешить пакет после расшифровки.
sudo ss -lntup | grep 8080
sudo wg show wg0 allowed-ips
curl -sS -m 5 http://10.71.0.2:8080/health
Если сокет привязан только к адресу физического интерфейса, а не к адресу туннеля, пакеты, приходящие по туннелю, отбрасываются ещё до того, как будет опрошен межсетевой экран. Этот сбой с облачной стороны выглядит так же, как проблема сопоставления, и переживает любую настройку keepalive.
Проверка списка разрешённых не менее важна и в обратном направлении. Облачный узел должен разрешить адрес домашнего туннеля как источник, если собирается отвечать, а домашний узел должен разрешить облачный адрес как назначение. Пакеты keepalive — это аутентифицированный трафик, и они применяют те же правила, поэтому keepalive, который выглядит работающим, может сосуществовать с приложением, которое не работает.
Внедрите изменение и знайте его пределы
Примените настройку, перезапустите интерфейс, если это ваш способ обновления, а затем повторите тест простоя, а не немедленный тест. Подождите дольше тайм-аута, который вы прочитали ранее, сделайте обратный запрос и убедитесь, что счётчики сдвинулись на обоих концах.
Запишите интервал и измеренный тайм-аут рядом. Будущее изменение прошивки маршрутизатора или переход на мобильное соединение может изменить тайм-аут. Заметка — это то, что позволяет кому-то заново вывести значение, а не скопировать его. Два числа в одной строке позже экономят целое расследование.
Постоянные keepalive защищают состояние. Они не открывают порт, не добавляют запись в список разрешённых и не заставляют слушателя появиться. Когда обратное соединение не работает вообще, виновато одно из этих трёх, и быстрый старт WireGuard описывает настройку keepalive в тех же узких терминах.