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 у тих самих вузьких термінах.