WireGuard на маршрутизаторі: помилки NAT, які порушують доступ до локальної мережі (та як їх виправити)

Було корисно?

Ви налаштували WireGuard на маршрутизаторі, бо хочете «VPN для всього дому» або віддалений доступ до своєї LAN. З’єднання встановлюється миттєво. Ваш телефон отримує тунельну IP‑адресу.
Ви відчуваєте себе розумним п’ять хвилин. А потім ви не можете дістатися до принтера, NAS або будь‑чого в локальній мережі — якщо тільки не вимкнути VPN. Це не проблема WireGuard.
Це ви (або ваш маршрутизатор) виконуєте NAT у невірному місці.

Найгірше: це часто «нібито працює». DNS резолвиться. Деякі сайти завантажуються. Але трафік у LAN тихо вмирає, або працює лише в один бік, або ламається лише для однієї підмережі.
Помилки NAT схожі на блискітки: як тільки вони опиняються в таблиці маршрутів і фаєрволі, вони проявляються всюди.

Ментальна модель: спочатку маршрутизація, потім NAT

WireGuard нудний у найкращому значенні. Це точково‑точковий інтерфейс, який шифрує пакети і поміщає їх на віртуальний NIC.
Всі інші рішення — хто може досягти чого, як повертаються пакети, чи бачать пристрої LAN реальні IP клієнтів — визначаються тією самою старою
таблицею маршрутів і тими самими правилами фаєрволу, з якими ви зіштовхуєтесь з 2003 року.

Три істини, що пояснюють 90% випадків «VPN ламає LAN»

  • AllowedIPs — це маршрутизація. На peer, AllowedIPs — це селектор політики маршрутів і анти‑спуфінговий фільтр. Це не «ACL». Ставтеся до нього як до карти маршрутів.
  • NAT приховує помилки, поки більше не приховує. Маскарадування тунелю може зробити повернення трафіку «працюючим» без додавання маршрутів, але воно ламає видимість в LAN, вхідні політики й іноді навіть з’єднання.
  • Шляхи повернення важливіші за прямі шляхи. Більшість відмов — це асиметрична маршрутизація: пакет входить, відповідь виходить через неправильний інтерфейс.

Коли ви запускаєте WireGuard на маршрутизаторі, ви поєднуєте дві ролі: кінцеву точку VPN і диригента трафіку.
Якщо ви виконуєте NAT на неправильній ланці (або для невірних підмереж), можете отримати тунель, що працює ідеально, тоді як мережа поводиться так, ніби там привид.

Що насправді означає «доступ до LAN»

Люди кажуть «я не можу потрапити в LAN», але мають на увазі одне з кількох різних явищ:

  • Не досягаються IP у LAN: ping до 192.168.1.10 з віддаленого клієнта через тунель не проходить.
  • IP досягається, але сервіси падають: SMB працює періодично, mDNS/Bonjour не працює, виявлення принтера мертве.
  • Пристрої LAN не можуть дістатися до VPN‑клієнта: Ви можете підключитися до NAS, але NAS не може зателефонувати назад на ваш ноутбук (поширено для бекапів, агентів моніторингу або зворотних з’єднань).
  • Весь трафік йде через VPN і LAN «вмирає»: Повний тунель ловить RFC1918 трафік і спрямовує його в тунель, відрізаючи локальні мережі.

Виправлення різні. Якщо ви відразу додаєте «masquerade», ви обираєте швидку нагороду замість правильного рішення.
Іноді NAT потрібен (особливо для road‑warrior клієнтів), але ви маєте розуміти, чим платите: спостережуваність, ідентифікація та політика.

Парафраз ідеї Джона Оллспо: Надійність приходить з розуміння того, як системи відмовляють, а не з прикидання, що цього не станеться.
Це стосується і NAT для WireGuard.

Жарт №1: NAT — як програма захисту свідків для пакетів. Чудово для приватності, жахливо, коли ви намагаєтесь допитати свідка.

Факти та контекст: чому це повторюється

Кілька коротких, конкретних фактів допоможуть пояснити, чому WireGuard на маршрутизаторі + NAT перетворюється на повторювану інцидентну схему:

  1. NAT не був частиною початкового дизайну Інтернету. Він поширився через дефіцит IPv4 і через те, що дозволяв «одна публічна IP» розгортання бути дешевими.
  2. У Linux IP‑пересилання за замовчуванням вимкнено. Поведінка маршрутизатора — opt‑in; туториали по VPN, що пропускають це, створюють плутанину «з’єднання є, але трафік не йде».
  3. Конфіг WireGuard навмисно мінімалістичний. Ні «режиму сервера», ні підштовхування маршрутів, ні чарівних перемикачів NAT; ви зшиваєте це разом через системну маршрутизацію й фаєрвол.
  4. AllowedIPs одночасно маршрут і фільтр. Такий дизайн запобігає спуфінгу, але дивує людей, які звикли до push‑маршрутів OpenVPN‑типу.
  5. Споживчі маршрутизатори часто постачаються з агресивним helper NAT. Деяка прошивка додає широкі правила маскараду; це може випадково NAT’ити LAN‑to‑LAN або тунель‑to‑LAN трафік.
  6. Split‑tunnel — за замовчуванням, full‑tunnel — це ріжучий інструмент. Як тільки ви маршрутизуєте 0.0.0.0/0 у тунель, ви опиняєтесь у справі винятків і політик маршрутизації.
  7. Проблеми MTU стали помітнішими з VPN поверх ISP CGNAT. Path MTU discovery може бути ненадійним; заблокований ICMP дає класичний симптом «працює для маленьких пінгів».
  8. Подвійний NAT тепер нормальний. Домашні користувачі часто стоять за NAT провайдера плюс своїм NAT; VPN додає ще один шар трансляції, якщо ви недбалий.
  9. NAT ламає енд‑ту‑енд ідентичність. Це ускладнює логування, ACL і іноді застосунки, які вбудовують IP‑адреси в протокол.

Швидкий план діагностики

Коли доступ до LAN ламається, не «пробуйте випадкові правила фаєрволу». Робіть це по черзі. Мета — ідентифікувати рівень‑вузьке місце:
крипто/handshake WireGuard, маршрутизація, NAT або фільтрація.

Перше: доведіть, що тунель живий (контрольний план)

  • Перевірте час handshake і лічильники передачі на маршрутизаторі.
  • Підтвердьте, що клієнт має маршрут до LAN (split tunnel) або принаймні дефолтний маршрут (full tunnel).

Друге: доведіть, що базове пересилання працює (план даних)

  • З клієнта пінгуйте LAN IP маршрутизатора і тунельну IP.
  • З маршрутизатора пінгуйте хост LAN, використовуючи тунельний IP як джерело (або використайте tcpdump, щоб бачити пакети, що входять і виходять).

Третє: перевірте шляхи повернення (саме тут зазвичай ламається)

  • На LAN‑хості (або шлюзі LAN) перевірте, чи є маршрут назад до підмережі WireGuard.
  • Якщо нема, вирішіть: додати маршрути (правильно) або зробити селективний NAT (прийнятний компроміс).

Четверте: перевірте політику фаєрволу і область застосування NAT

  • Підтвердьте правила форвардингу, які дозволяють wg0 → br-lan і br-lan → wg0.
  • Підтвердьте, що NAT застосовується лише там, де потрібно (зазвичай wg0 → wan для full tunnel, а не wg0 → lan, якщо ви не ховаєте клієнтів навмисно).

П’яте: MTU і DNS (відро «все хитке»)

  • Якщо маленькі пакети працюють, а великі підключення зависають — протестуйте MTU.
  • Якщо «доступ до LAN» насправді «імена не резолвяться», перевірте DNS і split DNS.

Практичні завдання: команди, виводи, рішення

Це завдання, які я реально запускаю під час інцидентів. Кожне включає: команду, реалістичний вивід, що це означає і яке рішення ви приймаєте далі.
Приклади припускають Linux‑маршрутизатор (Debian/OpenWrt‑подібне оточення). Перенесіть логіку на вашу платформу за потреби, але збережіть підхід.

Завдання 1: Перевірити handshake і лічильники WireGuard

cr0x@server:~$ sudo wg show
interface: wg0
  public key: oR7...routerpub...
  listening port: 51820

peer: k9T...clientpub...
  endpoint: 198.51.100.23:53312
  allowed ips: 10.6.0.2/32
  latest handshake: 42 seconds ago
  transfer: 18.34 MiB received, 22.91 MiB sent
  persistent keepalive: every 25 seconds

Що це значить: Handshake свіжий, лічильники рухаються. Крипто і UDP‑шлях у порядку.

Рішення: Перестаньте звинувачувати «WireGuard не працює». Перейдіть до маршрутизації/форвардингу/NAT.

Завдання 2: Підтвердити, що маршрутизатор має очікувану тунельну адресу

cr0x@server:~$ ip -brief address show dev wg0
wg0             UP             10.6.0.1/24

Що це значить: Інтерфейс піднятий і має адресу. Якщо він DOWN або відсутній IP — виправте конфіг інтерфейсу перш ніж робити інше.

Рішення: Якщо адреса невірна (наприклад /32 замість /24 коли ви очікуєте підмережу), виправте і перезапустіть інтерфейс.

Завдання 3: Перевірити, чи ввімкнено IP‑форуардінг

cr0x@server:~$ sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 0

Що це значить: Маршрутизатор поводиться як хост. Пакети не будуть форвардитись між wg0 і LAN/WAN.

Рішення: Увімкніть форвардінг і збережіть його постійно.

Завдання 4: Увімкнути форвардінг (тимчасово + постійно)

cr0x@server:~$ sudo sysctl -w net.ipv4.ip_forward=1
net.ipv4.ip_forward = 1

Що це значить: Форвардінг увімкнено зараз; тестуйте трафік негайно.

Рішення: Якщо це вирішує проблему, зафіксуйте в /etc/sysctl.conf або еквіваленті дистрибутива і перевірте, чому він був вимкнений.

Завдання 5: Перевірити маршрути на маршрутизаторі (main table)

cr0x@server:~$ ip route show
default via 203.0.113.1 dev wan0
10.6.0.0/24 dev wg0 proto kernel scope link src 10.6.0.1
192.168.50.0/24 dev br-lan proto kernel scope link src 192.168.50.1

Що це значить: Маршрутизатор знає обидві мережі. Добре. Якщо підмережа LAN відсутня — ваш LAN‑брідж не налаштований. Якщо маршрут wg0 відсутній — WireGuard не застосував адресу.

Рішення: Якщо маршрути виглядають коректно, зосередьтеся на фаєрволі і області NAT.

Завдання 6: Перевірити правила політики маршрутизації (часто додаються при full tunnel)

cr0x@server:~$ ip rule show
0:      from all lookup local
1000:   from 10.6.0.0/24 lookup 100
32766:  from all lookup main
32767:  from all lookup default

Що це значить: Трафік з підмережі WireGuard використовує table 100. Це поширено, коли змушують VPN‑клієнтів виходити через WAN або інший uplink.

Рішення: Якщо доступ до LAN ламається лише для VPN‑клієнтів, table 100 може не мати маршруту до 192.168.50.0/24 (або відправляє його у WAN). Перевірте таблицю 100 далі.

Завдання 7: Інспектувати альтернативну таблицю маршрутів

cr0x@server:~$ ip route show table 100
default via 203.0.113.1 dev wan0

Що це значить: Для трафіку, що походить від WireGuard, все — включно з LAN‑підмережею — йде за дефолтним маршрутом через wan0. Це чорна діра або херпінг доступу до LAN.

Рішення: Додайте явний маршрут до LAN в table 100, або виправте політику, щоб LAN‑призначення використовували main.

Завдання 8: Додати LAN‑маршрут у політичну таблицю (приклад виправлення)

cr0x@server:~$ sudo ip route add 192.168.50.0/24 dev br-lan table 100

Що це значить: Тепер трафік від VPN‑клієнта до LAN залишається локальним.

Рішення: Повторно протестуйте. Якщо це вирішує проблему, збережіть маршрут у системі конфігурації вашого роутера.

Завдання 9: Підтвердити, що клієнт дійсно маршрутизує LAN через тунель

cr0x@server:~$ ip route get 192.168.50.10
192.168.50.10 via 10.6.0.1 dev wg0 src 10.6.0.2 uid 1000
    cache

Що це значить: Клієнт відправлятиме трафік до LAN через wg0. Якщо вивід каже dev wlan0 або ваш звичайний інтерфейс, AllowedIPs/split‑tunnel клієнта неправильні.

Рішення: Виправте конфіг клієнта (AllowedIPs має включати підмережі LAN, які ви хочете робити доступними) перед зміною NAT на маршрутизаторі.

Завдання 10: Дивитися пакети, що входять в wg0 і йдуть до LAN

cr0x@server:~$ sudo tcpdump -ni wg0 icmp
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on wg0, link-type RAW (Raw IP), snapshot length 262144 bytes
12:01:10.112233 IP 10.6.0.2 > 192.168.50.10: ICMP echo request, id 4421, seq 1, length 64

Що це значить: Маршрутизатор отримує ping з тунелю.

Рішення: Якщо ви бачите його на wg0, але не на LAN — фаєрвол/форвардинг блокує. Якщо бачите на LAN, але немає відповіді — проблема зі шляхом повернення.

Завдання 11: Підтвердити, що пакет виходить через LAN‑інтерфейс

cr0x@server:~$ sudo tcpdump -ni br-lan icmp
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on br-lan, link-type EN10MB (Ethernet), snapshot length 262144 bytes
12:01:10.112987 IP 10.6.0.2 > 192.168.50.10: ICMP echo request, id 4421, seq 1, length 64

Що це значить: Форвардінг працює принаймні в одному напрямку: wg0 → LAN.

Рішення: Якщо немає echo reply, хост LAN не знає, як повернутися до 10.6.0.0/24 (або фаєрвол блокує). Вирішіть: додати маршрути або зробити NAT.

Завдання 12: Перевірити правила NAT (приклад iptables legacy)

cr0x@server:~$ sudo iptables -t nat -S
-P PREROUTING ACCEPT
-P INPUT ACCEPT
-P OUTPUT ACCEPT
-P POSTROUTING ACCEPT
-A POSTROUTING -o wan0 -j MASQUERADE
-A POSTROUTING -o br-lan -j MASQUERADE

Що це значить: Третє правило підозріле: маскарадування на br-lan означає, що пакети, які йдуть у LAN, будуть source‑NAT’итись в LAN IP маршрутизатора. Ваші LAN‑хости ніколи не побачать реальний IP VPN‑клієнта.

Рішення: Якщо ваша мета — «VPN‑клієнти як повноцінні члени LAN», видаліть це правило. Якщо ваша мета — «доступ до LAN без зміни LAN‑маршрутів», тоді залиште, але обмежте область застосування і документуйте витрати.

Завдання 13: Видалити надто широке маскарадування (небезпечно, якщо ви на ньому покладалися)

cr0x@server:~$ sudo iptables -t nat -D POSTROUTING -o br-lan -j MASQUERADE

Що це значить: Трафік VPN→LAN тепер збережить початкові IP (10.6.0.x). Потрібна коректна маршрутизація для повернення.

Рішення: Якщо після цього щось ламається, ви довели, що покладалися на NAT, щоб заклеїти відсутні маршрути. Виправте маршрути правильно.

Завдання 14: Додати правильний маршрут на шлюзі LAN (приклад)

cr0x@server:~$ sudo ip route add 10.6.0.0/24 via 192.168.50.1

Що це значить: LAN‑пристрої, що використовують цей шлюз, тепер можуть повернути трафік до підмережі WireGuard через маршрутизатор.

Рішення: Якщо не можете додати маршрути на кожному пристрої LAN, додайте його на дефолтний шлюз (або використайте DHCP option 121/classless static routes), щоб клієнти вчили маршрут автоматично.

Завдання 15: Переглянути nftables ruleset (сучасні маршрутизатори часто використовують nft)

cr0x@server:~$ sudo nft list ruleset
table inet filter {
  chain forward {
    type filter hook forward priority filter; policy drop;
    iifname "wg0" oifname "br-lan" accept
    iifname "br-lan" oifname "wg0" ct state established,related accept
  }
}
table ip nat {
  chain postrouting {
    type nat hook postrouting priority srcnat; policy accept;
    oifname "wan0" masquerade
  }
}

Що це значить: Forward chain дозволяє wg0 → LAN, але LAN → wg0 дозволено лише для established/related. Це блокує ініціацію з LAN до VPN‑клієнтів (і ламає протоколи, які не виглядають як «established» так, як ви очікуєте).

Рішення: Вирішіть, чи потрібна вам ініціація з LAN → VPN. Якщо так — додайте явний accept для iif br-lan oif wg0 з відповідними обмеженнями.

Завдання 16: Тестувати MTU, якщо бачите «пінг працює, додатки падають»

cr0x@server:~$ ping -M do -s 1420 192.168.50.10 -c 2
PING 192.168.50.10 (192.168.50.10) 1420(1448) bytes of data.
ping: local error: message too long, mtu=1420
ping: local error: message too long, mtu=1420

--- 192.168.50.10 ping statistics ---
2 packets transmitted, 0 received, +2 errors, 100% packet loss, time 1026ms

Що це значить: Ваш шлях не витримує такого розміру з DF встановленим. Потрібен нижчий MTU тунелю або MSS clamping.

Рішення: Зменшіть MTU WireGuard (наприклад 1280–1380 залежно від WAN) і повторно тестуйте з поступовим зростанням розміру.

Жарт №2: Пакет був занадто великим для тунелю, як інженер сховища, що намагається впхати «ще один датасет» на повний пул.

Типові помилки: симптом → причина → виправлення

Цей розділ суб’єктивний, бо має бути. Це помилки, які постійно з’являються в чергах заявок і домашніх лабораторних записах.
Кожна включає симптом, справжню причину і виправлення, що не породить наступний інцидент.

1) «Handshake є, але я не можу пінгувати хости LAN»

Симптом: wg show показує свіжий handshake; лічильники трафіку зростають; IP LAN не відповідають.

Причина: Відсутній маршрут повернення з LAN до підмережі WireGuard (10.6.0.0/24, 10.0.0.0/24 тощо).

Виправлення: Додайте маршрут на шлюзі LAN, що вказує підмережу WireGuard через LAN‑IP маршрутизатора. Якщо це неможливо, зробіть селективний NAT для wg0 → LAN.

2) «Доступ до LAN працює, але пристрої бачать усе від маршрутизатора»

Симптом: Логи NAS показують source IP = 192.168.50.1 для всіх VPN‑клієнтів; per‑client ACL не працюють.

Причина: Маскарадування застосовано для wg0 → LAN (POSTROUTING на br-lan). Ви перетворили віддалених клієнтів на «маршрутизатор».

Виправлення: Приберіть NAT для трафіку в LAN; додайте правильну маршрутизацію. Якщо треба NAT, обмежте його маленьким набором застарілих пристроїв і задокументуйте.

3) «Я ввімкнув повний тунель, і тепер локальний доступ на клієнті зламався»

Симптом: Клієнт не може дістатися 192.168.0.1 на місцевому Wi‑Fi після вмикання AllowedIPs = 0.0.0.0/0.

Причина: Повний тунель перехоплює всі IPv4 маршрути, включно з RFC1918. Клієнт намагається дістатися місцевого шлюзу через тунель.

Виправлення: Використовуйте split tunnel (маршрутуйте лише потрібне) або додайте явні «бюпаси» локальної мережі на клієнті. У деяких клієнтів це «виключити приватні IP», в інших — додати ручні маршрути.

4) «Деякі сервіси працюють, але SMB/RDP нестабільні або зависають»

Симптом: Ping працює, маленький HTTP працює, але великі передачі зупиняються або віддалений робочий стіл зависає.

Причина: Проблема MTU/PMTUD. Наклад тунелю штовхає пакети вище path MTU; ICMP fragmentation‑needed блокується фаєрволом.

Виправлення: Зменште MTU WireGuard (почніть з ~1380, знижуйте до 1280 при потребі) або застосуйте MSS clamping для TCP на маршрутизаторі для потоків wg0.

5) «Працює лише одна VLAN через VPN; інші VLAN мертві»

Симптом: Доступний 192.168.50.0/24, але недоступний 192.168.60.0/24.

Причина: AllowedIPs на клієнті або серверному peer не включає всі префікси LAN, або правила фаєрволу дозволяють лише один інтерфейс/зону.

Виправлення: Додайте відсутні VLAN‑підмережі до AllowedIPs на клієнті і переконайтесь, що маршрутизатор форвардить wg0 до інтерфейсів VLAN.

6) «VPN‑клієнти можуть дістатися LAN, але LAN не може дістатися VPN‑клієнтів»

Симптом: Віддалений клієнт може SSH до NAS, але NAS не може підключитися назад до клієнта для зворотного виклику.

Причина: Політика форвардингу фаєрволу дозволяє лише established потоки з LAN до wg0, або NAT ховає клієнта і ламає ініціацію з LAN.

Виправлення: Дозвольте LAN → wg0 там, де потрібно, або залиште це заблокованим навмисно і прийміть, що VPN лише ініціюється клієнтом. Не блокуйте випадково і не дивуйтесь, чому бекапи не заходять.

7) «DNS працює для Інтернету, але внутрішні імена не резолвяться»

Симптом: nas.lan не резолвиться, але 1.1.1.1 працює нормально.

Причина: Клієнт використовує публічний DNS через тунель; немає split DNS; відсутні search domains. Люди називають це «доступ до LAN», але це проблема імен.

Виправлення: Підштовхуйте/використовуйте внутрішній DNS для домену LAN при підключенні по VPN. Якщо у вас full tunnel — використайте резольвер маршрутизатора; якщо split — налаштуйте per‑domain DNS, якщо клієнт це підтримує.

8) «Вчора працювало, тепер не працює, і нічого не змінювалося (нібито)»

Симптом: Раптова відмова після зміни провайдера або перезавантаження маршрутизатора; handshake все ще є.

Причина: Динамічна WAN IP змінилась і endpoint peer не оновлено, або стан NAT/conntrack скинувся і виявив асиметричну маршрутизацію, яку NAT раніше маскував.

Виправлення: Забезпечте keepalive для road‑warrior клієнтів, розгляньте стратегії оновлення endpoint динамічно, і виправте маршрути, щоб ви не залежали від застарілого стану conntrack.

Три корпоративні міні‑історії з окопів NAT

Міні‑історія 1: Інцидент через неправильне припущення

Середня компанія розгорнула WireGuard на бранч‑роутері, щоб on‑call інженери могли доступатися до внутрішніх інструментів під час переїзду офісу.
Людина, що це робила, припустила, що «VPN‑клієнти мають виглядати так, ніби вони в LAN». Розумна мета, але реалізація була неправильною.

Вони ввімкнули широкий маскараду для всього трафіку з wg0 до LAN‑бріджу. Це «вирішило» досяжність миттєво.
Інженери могли дістатися Jira, Grafana і файлового сервера. Усі святкували та пішли далі.

Через два тижні безпека запитала, чому логи файлового сервера показують маршрутизатор як джерело для всіх VPN‑сесій.
Потім операції помітили, що ліміти запитів спрацьовують проти LAN IP маршрутизатора, а не реальних IP клієнтів.
Декілька внутрішніх ACL, що мали бути «лише для адмінів», стали «будь‑який VPN‑користувач», бо ACL орієнтувався на IP, а маршрутизатор був у allowlist.

Інцидент — не «невірність WireGuard». Це колапс ідентичності через NAT.
Виправлення було нудним: прибрати NAT wg0→LAN, додати маршрут для підмережі VPN на шлюзі LAN і оновити політику фаєрволу, щоб явно дозволити потрібні потоки.
Після цього логи й ACL стали зрозумілими — і це дивний вид радості.

Міні‑історія 2: Оптимізація, що відбилася боком

Інша організація хотіла швидший віддалений доступ для розробників. Хтось прочитав, що «NAT дорогий» і вирішив оптимізувати, усунувши conntrack.
Вони реалізували політичну маршрутизацію, щоб трафік VPN‑клієнтів використовував спеціальну таблицю і обходив деякі ланцюги фаєрволу, сподіваючись на меншу затримку.

Відокремлено зміна виглядала чисто. Тунель лишився, пропускна здатність в Інтернеті трохи покращилася.
Але потім з’явилася зовсім інша проблема: доступ до внутрішнього Git через VLAN LAN став нестабільним, але лише для певних розробників.

Причиною була відсутність конкретного маршруту для однієї з внутрішніх підмереж у політичній таблиці.
Трафік з 10.6.0.0/24 до 192.168.70.0/24 йшов за дефолтним маршрутом політики у WAN.
Відповіді ніколи не поверталися, бо ці пакети зовсім не мали виходити назовні.

«Оптимізація» створила паралельний світ маршрутів, який відійшов від реальності. Виправлення теж було нудним: реплікувати потрібні LAN‑маршрути в політичну таблицю,
додати регресійний тест, що перевіряє досяжність до кожного внутрішнього префіксу, і перестати ставитися до policy routing як до трюку для покращення продуктивності на п’ятницю.

Міні‑історія 3: Нудна, але правильна практика, що врятувала день

Третя команда керувала флотом маленьких маршрутизаторів для віддалених сайтів, всі керувалися однаково. Їхній шаблон конфігурації WireGuard ніколи не включав wg0→LAN masquerade.
Натомість на кожному шлюзі сайту був статичний маршрут для підмережі VPN назад до маршрутизатора, а DHCP роздавав classless routes де потрібно.

Це було неефектно. Потрібно було тримати інвентар підмереж і слідкувати, щоб шаблони не розходилися.
Але це означало, що пакети зберігали джерельну ідентичність end‑to‑end. Логи були точні. Політика фаєрволу мала сенс.

Під час гучного збою провайдера на одному сайті їм довелося тимчасово переключити egress VPN на резервний uplink.
Оскільки дизайн не залежав від NAT‑трюків для доступу в LAN, зміна була переважно про дефолтні маршрути і failover.
Внутрішній доступ продовжував працювати, поки uplink флапав. On‑call зміг заснути.

Урок: коректність масштабується. «Швидкі виправлення» теж масштабуются, тільки в протилежному напрямку.

Шаблони, які реально працюють (і чому)

Шаблон A: Правильно маршрутизувати (переважно)

Якщо ваша мета — реальне членство в LAN — клієнти мають стабільні тунельні IP і ви хочете per‑client логування й ACL — робіть маршрутизацію, а не NAT.
Це означає:

  • WireGuard‑клієнти живуть у виділеній підмережі (наприклад 10.6.0.0/24).
  • Маршрутизатор знає як LAN, так і VPN‑підмережі (він знає за замовчуванням, якщо налаштований).
  • Шлюз LAN має маршрут назад до підмережі WireGuard через маршрутизатор.
  • Фаєрвол дозволяє потрібні потоки; блокує решту.

Це єдиний підхід, що робить ідентичність, моніторинг і відлагодження зрозумілими. Якщо ви оперуєте мережами професійно — вибирайте це, якщо немає вагомої причини інакше.

Шаблон B: Селективний NAT для застарілих LAN (прийнятний компроміс)

Іноді ви не можете додати маршрути на шлюзі LAN. Можливо, це пристрій від провайдера, можливо мережа під керуванням іншої організації,
можливо LAN — це зоопарк статичних пристроїв, яких не можна чіпати.

У такому випадку NAT може бути прагматичним інструментом — але звузьте його область:

  • NAT лише з підмережі WireGuard до конкретних LAN‑префіксів.
  • Не маскарадьте весь трафік wg0 у всі напрямки.
  • Тримайте список пристроїв/підмереж, що залежать від цього, щоб пізніше можна було відмовитись.

Мета — уникнути синдрому «всі VPN‑клієнти стають маршрутизатором», і уникнути ненавмисного NAT LAN‑to‑LAN.

Шаблон C: Повний тунель на маршрутизаторі (потужно, але ви підписуєтесь на роботу)

Повний тунель — коли клієнти маршрутизують 0.0.0.0/0 (іноді ::/0) у wg0. На маршрутизаторі це зазвичай означає, що ви хочете, щоб віддалені клієнти використовували ваш офісний/домашній egress
(через довіру, гео‑причини, фільтрацію контенту або тому, що готельний Wi‑Fi проклятий).

Повний тунель майже завжди потребує NAT на WAN‑егресі, бо ви відправляєте приватні тунельні адреси в Інтернет. Але цей NAT має бути на wg0→WAN, а не на wg0→LAN.
Також повний тунель вводить ці регулярні вимоги:

  • Виключення для LAN: забезпечте, щоб внутрішні префікси все ще маршрутизувалися локально (особливо якщо використовуєте політичні таблиці).
  • Стратегія DNS: внутрішній DNS для внутрішніх імен; вирішіть, чи резолвити через маршрутизатор або використовувати split DNS.
  • Налаштування MTU: більше хопів, більше інкапсуляції, більше шансів на PMTUD‑проблеми.

Де люди помиляються: плутати «зробити доступним» з «зробити правильно»

NAT спокушає, бо може змусити пакети повертатися без дотикання LAN. Але коли ви NAT‑ите тунель в LAN, ви переписуєте історію пакетів.
Все вниз по танку — логи, ACL, ліміти — тепер бачать «маршрутизатор зробив це».

Якщо ви робите це вдома і вам байдуже — гаразд. Якщо ви робите це на роботі і вам важлива атрибуція — не робіть цього.

Контрольні списки / покроковий план

Покроково: відновити доступ до LAN без культового NAT

  1. Підтвердьте handshake і лічильники: wg show має показувати свіжий handshake і ненульову передачу. Якщо ні — виправте endpoints/ключі/UDP‑доступ.
  2. Перевірте форвардінг маршрутизатора: увімкніть net.ipv4.ip_forward=1. Якщо залучений IPv6 — також увімкніть IPv6‑форвардінг свідомо.
  3. Підтвердьте намір маршрутизації клієнта: AllowedIPs клієнта має включати підмережі LAN, які ви хочете доступити (split tunnel) або 0.0.0.0/0 (full tunnel).
  4. Підтвердьте маршрути маршрутизатора: маршрутизатор має підключені маршрути для LAN і wg0. Якщо використовуєте policy routing, переконайтесь, що ці таблиці теж містять LAN‑маршрути.
  5. Доведіть потік пакетів за допомогою tcpdump: бачите ICMP/TCP на wg0 і br-lan. Якщо він не проходить — це фаєрвол/форвардинг.
  6. Виправте шлях повернення правильно: додайте маршрут для підмережі WireGuard на шлюзі LAN, що вказує на маршрутизатор. Краще зробити це один раз на шлюзі, а не на кожному хості.
  7. Тільки потім думайте про NAT: якщо реально не можете виправити маршрути, додайте сфокусоване NAT‑правило з підмережі wg0 до LAN‑підмережі, а не широкий маскарадувальний.
  8. Заблокуйте політику фаєрволу: дозволяйте лише потрібні протоколи з wg0 до LAN; розгляньте блокування латерального руху за замовчуванням.
  9. Перевірте MTU: тестуйте великі пакети і налаштуйте MTU/MSS при потребі.
  10. Документуйте: вкажіть, які підмережі існують, де є NAT (якщо є) і що означає «працює» (тести, які треба проганяти).

Чеклист рішень: чи варто NATити VPN→LAN?

  • Чи контролюєте ви шлюз LAN? Якщо так — маршрутизуйте. Якщо ні — NAT може бути єдиним варіантом.
  • Потрібна атрибуція по клієнтах на LAN‑системах? Якщо так — не робіть NAT wg0→LAN.
  • Очікуєте, що LAN ініціюватиме з’єднання до VPN‑клієнтів? Якщо так — маршрутизація набагато простіша, ніж NAT + port‑forward + сум.
  • Це тимчасово? Якщо мусите NATити, ставте це як технічний борг і план виходу.

Регресійні тести (запускайте після кожної зміни)

Зробіть ці тести м’язовою пам’яттю. Вони ловлять більшість поломок:

  • З VPN‑клієнта: ping до LAN‑IP маршрутизатора, ping до одного LAN‑хоста, підключення до одного TCP‑сервісу (SSH/HTTPS/SMB).
  • З маршрутизатора: ping до LAN‑хоста, ping до тунельного IP VPN‑клієнта.
  • З LAN‑хоста: ping до тунельного IP VPN‑клієнта (якщо ви дозволяєте LAN→VPN), або підтвердьте, що це заблоковано (якщо ні).
  • Перевірте логи: підтвердьте, що LAN‑сервіс бачить source IP VPN‑клієнта (якщо дизайн з маршрутизацією) або бачить маршрутизатор (якщо NAT, навмисно).

Питання та відповіді

1) Чому WireGuard «під’єднується», але трафік в LAN не ходить?

Handshake доводить лише криптографічне встановлення сесії. Дані все ще потребують IP‑форвардингу, коректних маршрутів і дозволу фаєрволу.
Найчастіше прямий шлях працює, але відсутній маршрут повернення з LAN до підмережі VPN.

2) Чи є AllowedIPs правилом фаєрволу?

Насправді ні. Воно поводиться як селектор маршрутизації (які призначення йдуть до того peer) і як фільтр джерел (які source адреси приймаються від того peer).
Ставтеся до нього як до політики маршрутизації, а для контролю доступу використовуйте справжній фаєрвол.

3) Чи треба маскарадувати трафік WireGuard?

Маскарадування зазвичай доречне для wg0→WAN при повному тунелі виходу. Маскарадування wg0→LAN зазвичай є тимчасовим обхідним шляхом для відсутніх маршрутів.
Використовуйте маршрутизацію, якщо можете; використовуйте обмежений NAT лише коли потрібно.

4) Моя LAN — 192.168.1.0/24, і віддалена мережа теж 192.168.1.0/24. Що робити?

Перекриваючі підмережі — це маршрутизаторний глухий кут. Потрібно перенумерувати одну сторону, або NATити одну сторону в неперекриваючийся діапазон, або використовувати проксі на рівні застосунку.
Якщо це site‑to‑site VPN — плануйте проект перенумерації і припиніть вірити, що цього не станеться.

5) Чому я можу дістатися IP, але не імен?

Це DNS, а не маршрутизація. Ваш клієнт може використовувати публічний DNS або йому бракує search domain.
Налаштуйте VPN‑клієнт на використання внутрішнього DNS (або запустіть резольвер на маршрутизаторі) і переконайтесь, що внутрішні зони доступні.

6) Як дозволити VPN‑клієнтам доступ лише до одного хоста LAN (наприклад NAS) і ні до чого іншого?

Маршрутуйте правильно (без NAT), а потім застосуйте правила фаєрволу: дозвольте wg0 до IP/портів NAS, забороніть wg0 до решти LAN.
Робити це через NAT ускладнює аудит і може створити випадковий доступ через привілеї роутера.

7) Чому трафік падає лише при великих завантаженнях або копіюванні файлів?

Це проблеми MTU/PMTUD. Шлях не може переносити великі інкапсульовані пакети, а ICMP «fragmentation needed» може бути заблокований.
Зменшіть MTU WireGuard або застосуйте MSS clamping на маршрутизаторі для трафіку через wg0.

8) Який найчистіший спосіб уникнути додавання маршрутів на кожен пристрій LAN?

Додайте маршрут на дефолтний шлюз LAN до підмережі WireGuard через маршрутизатор. Якщо у вас кілька шлюзів/VLAN, покладіть маршрут у L3‑core.
Для кінцевих пристроїв DHCP classless static routes може допомогти, але маршрут на шлюзі — найпростіший варіант.

9) Чи потрібно дозволяти br-lan → wg0 форвардинг?

Лише якщо ви хочете, щоб LAN ініціював з’єднання до VPN‑клієнтів. Багато налаштувань свідомо це блокують з міркувань безпеки.
Але будьте явними: якщо блокуєте — задокументуйте, що VPN лише ініціюється клієнтом, щоб ніхто не втратив вихідні вихідні вихідні виходи на вихідні дебаги.

Наступні кроки, які варто зробити сьогодні

Якщо ваша поточна конфігурація «працює» лише тому, що ви маскарадуєте wg0 в LAN, ви на одну зміну від дивного простою або загадки в логах.
Виправте це серйозно.

  1. Аудит області NAT: переконайтесь, що маскарадування існує для wg0→WAN якщо потрібно, і видаліть wg0→LAN маскарадування, якщо це не явний і задокументований компроміс.
  2. Зробіть шлях повернення коректним: додайте маршрут підмережі WireGuard на шлюзі LAN і перевірте через ping з боку LAN на IP VPN‑клієнта.
  3. Підтвердьте захоплення пакетів: tcpdump на wg0 і LAN, щоб довести, де саме пакет зупиняється.
  4. Визначте свою безпекову позицію: чи може LAN ініціювати з’єднання до VPN‑клієнтів? Якщо так — дозвольте це обережно; якщо ні — блокуйтe це явно і задокументуйте.
  5. Напишіть односторінковий runbook: вкажіть ваші підмережі, де є NAT і три регресійні тести. Майбутній ви буде менш сердитим.

Зробіть ці кроки, і WireGuard стане тим, чим має бути: простим зашифрованим інтерфейсом, а не повторюваною вправою в інтерпретації NAT.

← Попередня
Електронна пошта: «554 spam detected» — очистіть репутацію без тижнів марнування
Наступна →
Windows Phone: Як хороша ОС програла через екосистеми

Залишити коментар