Ви можете збудувати бездоганний VPN-тунель і одночасно створити витік приватності, хаос у надійності та купу звернень у службу підтримки — лише неправильно налаштувавши DNS. Зазвичай це проявляється як «VPN підключено, але внутрішні застосунки не працюють», а потім «чому мій ноутбук звертається до випадкового резолвера в готелі?»
DNS — це крихітні пакети з великими наслідками. Якщо ваш split tunnel пропускає «тільки важливий» трафік через VPN, але DNS-запити все ще йдуть у локальну мережу, ви отримаєте витоки, зламане внутрішнє розв’язування і дивні стрибки затримок, які виглядають як «VPN повільний», навіть коли тунель у порядку.
Ментальна модель: що насправді означає «локальний DNS для користувачів VPN»
Фраза «локальний DNS для користувачів VPN» використовується в трьох різних значеннях. Якщо ви не уточните, яке саме впроваджуєте, то отримаєте систему, що працює в лабораторії і ламається в лобі готелю.
Значення №1: «Використовувати внутрішній резолвер доступний через VPN»
Класична корпоративна модель: клієнт VPN має надсилати DNS-запити до резолвера всередині вашої мережі (або в межах вашого cloud VPC), а не до резолвера, який видає користувацька Wi‑Fi. Це основа split-horizon DNS (внутрішні імена резолвляться в внутрішні IP), зон лише для внутрішнього використання та узгодженого логування.
Значення №2: «Запустити резолвер на клієнті та форвардити розумно»
Ви запускаєте локальний stub-резолвер на пристрої (або покладаєтесь на stub ОС) і налаштовуєте умовне форвардення: внутрішні домени йдуть до внутрішніх DNS через VPN; усе інше — до публічного резолвера (або теж через VPN, залежно від політики). Часто це найчистіший спосіб змусити split tunnel поводитись без прокидання всього інтернет-DNS через корпоративну мережу.
Значення №3: «Надати DNS-сервіс близько до користувача, щоб зменшити затримки»
Це орієнтовано на продуктивність: розгорнути регіональні резолвери, доступні через VPN, щоб віддалені працівники не «завивались» до головного офісу для кожного запиту. Це також зменшує blast radius, коли один DNS-вузол падає, бо «найближчий» змінюється.
Усі три підходи валідні. Змішування їх без наміру призводить до часткових витоків, непередбачуваного порядку резолверів і кешів, що змагаються між собою.
Операційна правда: DNS «працює», поки не перестане, а тоді ламається як мильна бульбашка — тихо, випадково і завжди під час живої демонстрації.
Цікаві факти та історія, що пояснюють сьогоднішній безлад
- DNS існував ще до сучасних VPN. Специфікація DNS (RFC 1034/1035) з 1987 року, і вона була розроблена для більш дружньої мережі, ніж сьогоднішні ворожі Wi‑Fi та captive portal.
- «Split horizon» старіший за хмару. Підприємства використовували різні погляди для внутрішнього та зовнішнього DNS задовго до того, як Kubernetes зробив усе відчутно новим.
- UDP був перевагою, а потім — проблемою. DNS по UDP ідеально підходив для малих запитів, але його легко підробити, блокувати або неправильно обробляти на ненадійних мережах.
- EDNS0 змінив розміри пакетів. Більші DNS-відповіді (DNSSEC, багато записів) підвищили проблеми фрагментації — саме те, що веде до дивних помилок через MTU у VPN.
- DNSSEC підвищив цілісність, але не приватність. Воно допомагає запобігти підміні, але не зупиняє витоки DNS і не перешкоджає спостерігачам бачити запити.
- DoH/DoT змінили, хто «володіє» резолвом імен. Застосунки можуть обходити налаштування резолвера ОС, що означає: «встановити DNS-сервер» VPN може ігноруватися браузером.
- Windows NRPT існує не просто так. Microsoft додала Name Resolution Policy Table, щоб контролювати, які простори імен використовують які резолвери — бо «просто вказати DNS-сервер» було недостатньо.
- systemd-resolved приніс split DNS у Linux масово. Воно потужне, але також додало нові режими відмов, коли адміністратори вважають, що /etc/resolv.conf показує повну картину.
- Корпоративний DNS часто останній рубіж на чергуванні. Багато команд модернізують аутентифікацію, впроваджують проксі, але все ще експлуатують DNS як у 2009 році, бо «раніше все працювало».
Цілі проєкту: оберіть, що ви оптимізуєте
Перш ніж торкатися конфігів, вирішіть, що для вашої організації означає «правильно». DNS — це політика, замаскована під інфраструктуру.
Ціль A: Запобігти витокам DNS (приватність + відповідність)
Витоки стаються, коли DNS-запити для внутрішніх доменів (або будь-яких доменів, згідно політики) надходять до резолвера поза вашим контролем. Виправлення може вимагати примусового налаштування DNS через інтерфейс VPN, блокування портів 53 поза тунелем та опрацювання DoH.
Ціль B: Зробити split tunnel надійним (надійність)
Split tunnel зазвичай означає: внутрішні застосунки через VPN, інтернет напряму. DNS має відповідати цьому. Якщо внутрішні зони резолвляться через публічні резолвери — внутрішні застосунки ламаються. Якщо публічні зони резолвляться через внутрішні резолвери по завантаженому тунелю — інтернет здається «повільним».
Ціль C: Тримати затримки та навантаження в розумних межах (продуктивність)
Централізувати DNS за одним VPN-точкою легко, але це також шлях до того, щоб користувачі сказали, що «VPN повільний». Регіональні резолвери, кешування і правильна робота з TTL роблять DNS настільки швидким, що ніхто про нього не думає — це найвища похвала.
Ціль D: Зробити операції нудними (підтримуваність)
Налагодження DNS на віддалених кінцевих точках вже болісне. Не ускладнюйте це хитрощами, які ви не можете спостерігати. Віддавайте перевагу дизайнам, де ви можете відповісти: який резолвер використав клієнт, через який інтерфейс пішов запит і що він отримав у відповідь?
Парафраз ідеї від John Allspaw: надійність будується на здатності реагувати на несподіване, а не на припущенні, що несподіваного не буде.
Референсні архітектури, які працюють у продакшені
1) Full-tunnel DNS: примусити весь DNS через VPN до внутрішніх резолверів
Коли використовувати: сувора відповідність, регульовані середовища або коли ви не можете терпіти DNS поза тунелем.
Як працює: VPN штовхає внутрішні DNS-сервери; клієнт маршрутизує DNS-запити через тунель; фаєрвол блокує вихід DNS на локальному інтерфейсі; опційно перехоплює/перенаправляє на внутрішній резолвер.
Побічні ефекти: більше навантаження на ваш VPN і DNS; вища затримка для публічних запитів, якщо внутрішній резолвер не обирає хороші upstream; потребує окремої обробки DoH.
2) Split DNS з умовним форвардингом (рекомендований за замовчуванням)
Коли використовувати: більшість організацій зі split tunnel і внутрішніми просторами імен.
Як працює: внутрішні домени (наприклад, corp.example, svc.cluster.local, приватні зони хмари) йдуть до внутрішніх резолверів через VPN; усе інше — використовує локальний резолвер мережі або обраний публічний резолвер.
Побічні ефекти: більше складності конфігурації на різних ОС; вимагає контролю порядку резолверів і правил маршрутизації доменів; все ще треба думати про шляхи витоків.
3) Локальний резолвер на клієнті + зашифровані upstream (DoT) через VPN
Коли використовувати: ви хочете узгодженої поведінки й менше проблем з особливостями ОС, і можете керувати агентом.
Як працює: запускається локальний кешуючий stub (наприклад, unbound) на клієнті; внутрішні зони форвардяться до внутрішніх DNS; публічні запити форвардяться до DoT-пунктів або через VPN, або напряму. Це може приборкати змагання резолверів і зменшити повторні запити на нестабільних каналах.
Побічні ефекти: управління життєвим циклом агента; ще одна рухома частина; налагодження переходить з інструментів ОС у логи вашого stub.
4) Доступні через VPN anycast резолвери (для масштабу)
Коли використовувати: велика віддалена робоча сила по регіонах; низькі затримки; якщо ви вже добре керуєте глобальним маршрутизуванням.
Як працює: рекламувати ті самі IP резолверів у кількох регіонах, доступні через VPN; BGP або оверлей-рутинги ведуть клієнта до найближчого інстансу. Працює найкраще в парі з health checks і швидким failover.
Побічні ефекти: потрібна операційна зрілість; anycast + stateful фаєрволи можуть ускладнити ситуацію; для налагодження «який вузол відповів» потрібна хороша спостережуваність.
Думка: якщо вас не змушують регуляції до full-tunnel DNS, почніть зі split DNS і умовного форвардингу. Це найкращий баланс користувацького досвіду і контролю — якщо ви чесно впровадите і протестуєте на реальних ОС клієнтів.
Поведінка клієнтів: Windows, macOS, Linux, мобільні (і їхні погані звички)
Windows: кілька резолверів, пошук суфіксів і таблиці політик
Windows може мати різні DNS-сервери для кожного інтерфейсу і має правила, який інтерфейс перемагає. Також є списки пошукових суфіксів, які можуть створювати несподівані запити. Для split DNS Windows NRPT може маршрутизувати певні простори імен до заданих DNS-серверів. Якщо ви масштабуєте корпоративний VPN, вивчіть NRPT. Це різниця між «працює для ІТ» і «працює для всіх».
macOS: порядок резолверів реальний, і інколи індивідуальний
macOS використовує динамічну конфігурацію резолвера. Можна мати кілька активних резолверів з маршрутизацією по доменах. UI і клієнт VPN можуть казати одне, а підлеглий резолвер робити інше. Завжди перевіряйте фактичний стан резолвера, а не лише панель мережі.
Linux: /etc/resolv.conf — брехун у сучасних системах
На багатьох дистрибутивах /etc/resolv.conf вказує на локальний stub (наприклад, 127.0.0.53), яким керує systemd-resolved, NetworkManager або інше. Діагностика вимагає запитів до менеджера резолвера, а не лише читання файлу.
Мобільні пристрої: captive portal, «корисні» фічі приватності та DNS на рівні застосунку
Телефони роумлять, перемикають мережі і агресивно намагаються зберегти підключення. Деякі застосунки використовують власні методи DNS, а сучасні платформи можуть віддавати перевагу зашифрованому DNS, якщо воно налаштовано. Ваша історія «пушити DNS через VPN» може не покривати налаштування DoH у браузері або агента безпеки, що робить власне розв’язування.
Жарт №1: DNS — як офісні плітки: якщо ви не контролюєте, куди вони йдуть, вони неодмінно опиняться в неправильному коридорі.
Звідки беруться витоки DNS та збої split routing
Шлях витоку 1: DNS-сервер задано, але маршрут відсутній
VPN штовхає внутрішній DNS IP, але клієнт не маршрутизує цей IP через тунель (поширено при split tunnel). Результат: DNS-сервер «налаштований», але недоступний. ОС переходить на інший резолвер — часто локальний — що спричиняє витоки і збої.
Шлях витоку 2: порядок резолверів і fallback
Клієнти можуть пробувати кілька резолверів. Якщо внутрішній резолвер таймаутиться (затримка, MTU, втрата пакетів), ОС використовує наступний резолвер. Вітаємо, ви щойно створили ймовірнісну політику приватності.
Шлях витоку 3: DNS на рівні застосунку (DoH/DoT)
Якщо браузери або агенти використовують DoH напряму до публічного провайдера, налаштування DNS VPN можуть бути обійдені. Іноді це треба. Часто — ні. Визначте політику, а потім застосуйте її через управління кінцевими точками і/або мережеві контролі.
Збій split routing: внутрішні імена резолвляться в публічні IP (або NXDOMAIN)
Якщо внутрішні зони не маршрутизовано до внутрішніх резолверів, користувачі отримають NXDOMAIN або, гірше, внутрішні імена резолвляться в публічні записи з тим же імʼям. Split horizon DNS існує через повторне використання імен. Ігнорування цього факту породжує тикети, які ви не заслуговуєте.
Збій split routing: внутрішні імена резолвляться, але трафік іде напряму
Навіть якщо DNS правильний, отримана A/AAAA адреса має належати діапазону, маршрутизованому через VPN. Якщо ваш split tunnel маршрутизує лише деякі префікси, а внутрішні сервіси живуть в іншому місці, розв’язування пройшло, але з’єднання все одно не встановиться. Користувачі все одно називатимуть це «DNS». Іноді вони праві, але не з тієї причини, яку думають.
Практичні завдання: команди, виводи та висновки
Це перевірки, які я виконую приблизно в такому порядку, коли хтось каже «DNS VPN не працює». Кожне завдання містить команду, типовий вивід, що це означає, і рішення, яке ви робите далі.
Завдання 1: Визначити, який DNS-сервер насправді використовує система (Linux із systemd-resolved)
cr0x@server:~$ resolvectl status
Global
Protocols: -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
resolv.conf mode: stub
Current DNS Server: 10.20.0.53
DNS Servers: 10.20.0.53 1.1.1.1
DNS Domain: corp.example
Link 3 (wg0)
Current Scopes: DNS
Protocols: +DefaultRoute
Current DNS Server: 10.20.0.53
DNS Servers: 10.20.0.53
DNS Domain: ~corp.example
Що це означає: DNS розділений: wg0 обробляє ~corp.example і використовує 10.20.0.53. Також є глобальний fallback (1.1.1.1).
Рішення: Якщо внутрішні запити все ще витікають, перевірте, що внутрішні запити йдуть через wg0 і що ~corp.example правильно налаштовано. Якщо його немає — виправте маршрутизацію по доменах.
Завдання 2: Перевірити /etc/resolv.conf, не даючись обдурити ним
cr0x@server:~$ ls -l /etc/resolv.conf
lrwxrwxrwx 1 root root 39 Jan 2 10:11 /etc/resolv.conf -> ../run/systemd/resolve/stub-resolv.conf
Що це означає: Ви використовуєте stub-резолвер. Читання файлу не покаже справжній upstream.
Рішення: Використовуйте resolvectl (або інструменти NetworkManager) для правди. Якщо застосунки обходять stub, це інша проблема.
Завдання 3: Підтвердити, що внутрішній DNS-сервер доступний через маршрут VPN
cr0x@server:~$ ip route get 10.20.0.53
10.20.0.53 dev wg0 src 10.20.0.10 uid 1000
cache
Що це означає: Маршрут до внутрішнього резолвера йде через wg0. Добре.
Рішення: Якщо маршрут іде через wlan0 або інший локальний інтерфейс — виправте split tunnel маршрути (AllowedIPs, pushed routes або policy routing).
Завдання 4: Тестувати внутрішнє розв’язування безпосередньо проти внутрішнього резолвера
cr0x@server:~$ dig @10.20.0.53 git.corp.example +time=2 +tries=1
; <<>> DiG 9.18.24 <<>> @10.20.0.53 git.corp.example +time=2 +tries=1
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 40211
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; ANSWER SECTION:
git.corp.example. 60 IN A 10.30.4.21
;; Query time: 21 msec
;; SERVER: 10.20.0.53#53(10.20.0.53)
Що це означає: DNS-сервер відповідає швидко і повертає внутрішню IP-адресу.
Рішення: Якщо це працює, але застосунки не працюють, клієнт може не використовувати цього резолвера (проблема з порядком резолверів) або маршрутизація до 10.30.4.21 неправильна.
Завдання 5: Протестувати те саме імʼя через системний шлях за замовчуванням (виявлення витоків і помилок маршрутизації)
cr0x@server:~$ dig git.corp.example +time=2 +tries=1
; <<>> DiG 9.18.24 <<>> git.corp.example +time=2 +tries=1
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 5851
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
Що це означає: Ваш системний шлях резолвера не знає внутрішньої зони (ймовірно використовує зовнішній DNS).
Рішення: Виправте split DNS-маршрутизацію, щоб corp.example йшов до внутрішнього резолвера. На Linux це маршрутизація за посиланнями; на Windows — часто NRPT; на macOS — записи резолвера по доменам.
Завдання 6: Виявити, чи DNS-пакети дійсно проходять інтерфейс VPN
cr0x@server:~$ sudo tcpdump -ni wg0 port 53 -c 5
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on wg0, link-type RAW (Raw IP), snapshot length 262144 bytes
10:22:41.111112 IP 10.20.0.10.53321 > 10.20.0.53.53: 40211+ A? git.corp.example. (33)
10:22:41.132908 IP 10.20.0.53.53 > 10.20.0.10.53321: 40211 1/0/1 A 10.30.4.21 (49)
Що це означає: DNS іде через тунель, і відповіді повертаються. Це чиста базова лінія.
Рішення: Якщо ви не бачите нічого на wg0, але бачите запити на wlan0, це витік. Виправте маршрутизацію або вибір резолвера.
Завдання 7: Вловити поведінку «fallback резолвера», спостерігаючи кілька інтерфейсів
cr0x@server:~$ sudo tcpdump -ni wlan0 port 53 -c 3
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on wlan0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
10:23:02.002201 IP 192.168.1.25.58732 > 192.168.1.1.53: 5851+ A? git.corp.example. (33)
10:23:02.004991 IP 192.168.1.1.53 > 192.168.1.25.58732: 5851 NXDomain 0/1/0 (102)
Що це означає: Ваш пристрій витікає внутрішні запити до локального резолвера мережі.
Рішення: Зупиніть fallback, правильно реалізувавши split DNS і/або блокуючи DNS поза тунелем. Якщо політика дозволяє, впровадьте на рівні ОС правило «внутрішні зони мають йти через VPN».
Завдання 8: Перевірити проблеми MTU/фрагментації, що виглядають як «DNS таймаути»
cr0x@server:~$ ping -M do -s 1472 10.20.0.53 -c 2
PING 10.20.0.53 (10.20.0.53) 1472(1500) bytes of data.
ping: local error: message too long, mtu=1420
ping: local error: message too long, mtu=1420
--- 10.20.0.53 ping statistics ---
2 packets transmitted, 0 received, +2 errors, 100% packet loss, time 1026ms
Що це означає: Шляховий MTU менший (1420). Великі UDP-відповіді можуть фрагментуватися або падати, що призводить до періодичних DNS-збоїв.
Рішення: Налаштуйте MTU VPN, увімкніть TCP-fallback для надійності або забезпечте, щоб DNS-відповіді залишалися маленькими. Якщо ви використовуєте багато DNSSEC, будьте особливо обережні.
Завдання 9: Перевірити, що клієнт не використовує DoH так, щоб обходити ваш план (мережевий погляд)
cr0x@server:~$ sudo tcpdump -ni wg0 'tcp port 443 and (host 1.1.1.1 or host 8.8.8.8)' -c 3
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on wg0, link-type RAW (Raw IP), snapshot length 262144 bytes
10:24:10.500000 IP 10.20.0.10.41220 > 1.1.1.1.443: Flags [S], seq 123456, win 64240, options [mss 1360,sackOK,TS val 1 ecr 0], length 0
Що це означає: Ви бачите HTTPS-трафік до публічного провайдера резолверів. Це може бути нормальний веб-трафік — або DoH.
Рішення: Якщо політика забороняє DoH-обхід, забезпечте її через управління кінцевими точками і/або егрегні контролі. Якщо політика дозволяє, переконайтеся, що внутрішні домени не витікають через DoH (що часто означає правила split DNS на рівні застосунків або блокування певних суфіксів з виходу).
Завдання 10: Підтвердити, який DNS-сервер відповів на запит (trace у dig)
cr0x@server:~$ dig git.corp.example +trace +time=2 +tries=1
; <<>> DiG 9.18.24 <<>> git.corp.example +trace +time=2 +tries=1
;; Received 525 bytes from 192.168.1.1#53(192.168.1.1) in 3 ms
Що це означає: Trace почався з вашого локального резолвера (192.168.1.1). Для внутрішнього імені це вже витік.
Рішення: Виправте вибір резолвера і маршрутизацію доменів. Trace корисний для доказу «хто відповів», без аргументів по скриншотах UI.
Завдання 11: Підтвердити, що IP внутрішнього сервісу маршрутизується через VPN (після DNS)
cr0x@server:~$ ip route get 10.30.4.21
10.30.4.21 dev wg0 src 10.20.0.10 uid 1000
cache
Що це означає: Трафік до внутрішнього сервісу піде через VPN. Можливо, DNS і не є справжньою проблемою.
Рішення: Якщо це йде поза тунелем, виправте префікси split tunnel. DNS — в порядку; проблема в маршрутизації.
Завдання 12: Перевірити, чи внутрішній резолвер може дістати upstream (на стороні резолвера)
cr0x@server:~$ dig @127.0.0.1 example.com +time=2 +tries=1
; <<>> DiG 9.18.24 <<>> @127.0.0.1 example.com +time=2 +tries=1
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 30001
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
;; Query time: 2000 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
Що це означає: Локальний резолвер (на DNS-сервері) не може розв’язати публічні імена. Upstream заблоковано, поламано або таймаутиться.
Рішення: Виправте egress резолвера, upstream конфіг або правила фаєрвола. Інакше користувачі VPN скаржитимуться на «DNS VPN», хоча проблема в шляху upstream вашого резолвера.
Завдання 13: Перевірити лічильники фаєрвола на предмет блокованого DNS (серверна перевірка)
cr0x@server:~$ sudo nft list ruleset | sed -n '1,120p'
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
ct state established,related accept
iifname "wg0" udp dport 53 accept
iifname "wg0" tcp dport 53 accept
counter packets 1203 bytes 90211 drop
}
}
Що це означає: DNS з інтерфейсу VPN дозволено; усе інше за замовчуванням відкидається.
Рішення: Якщо клієнти VPN досі не можуть розв’язувати, проблема не в тому, що DNS-сервер їх блокує (принаймні не на input chain). Перейдіть до перевірки сервісу, маршрутизації або MTU.
Завдання 14: Перевірити продуктивність резолвера і частоту попадань у кеш (приклад Unbound)
cr0x@server:~$ sudo unbound-control stats_noreset | egrep 'total.num.queries|total.num.cachehits|total.num.cachemiss|avg'
total.num.queries=145233
total.num.cachehits=109887
total.num.cachemiss=35346
total.requestlist.avg=8.132
Що це означає: Співвідношення попадань у кеш пристойне; середній список запитів свідчить про деяку конкурентність, але не обов’язково про перевантаження.
Рішення: Якщо попадань у кеш мало і затримки великі — додайте кешування ближче до користувачів, підлаштуйте prefetching або збільшіть потужність резолвера. Якщо rate miss раптово зростає під час інцидентів — можливо, у вас проблеми з upstream.
Жарт №2: Split DNS — як політика «роботи з дому»: всі погоджуються в принципі, а потім крайні випадки селяться безплатно.
Плейбук швидкої діагностики
Це порядок дій «припиніть гадати». Виконуйте його як чекліст, а не як дискусію.
Перший крок: підтвердити, який резолвер використовує клієнт
- На Linux:
resolvectl status(не довіряйте лише/etc/resolv.conf). - На macOS: перевірте конфігурацію резолвера (вам потрібна маршрутизація по доменах, а не просто «DNS-сервери» у UI).
- На Windows: перевірте DNS інтерфейсу плюс NRPT-правила, якщо ви їх використовуєте.
Рішення: Якщо клієнт не налаштований використовувати внутрішній DNS для внутрішніх доменів — припиніть. Виправте конфігурацію перед тим, як шукати «мережеві проблеми».
Другий крок: підтвердити маршрут до внутрішнього DNS-сервера через VPN
- Запустіть
ip route get <dns_ip>(Linux) або відповідні інструменти. - Якщо маршрут поза тунелем — це помилка політики split-tunnel.
Рішення: Виправте маршрути (AllowedIPs, pushed routes, policy routing) перед тим, як торкатися DNS-серверів.
Третій крок: протестуйте внутрішнє розв’язування безпосередньо проти внутрішнього DNS
dig @internal-dns internalhost.corp.example- Виміряйте затримку, коди відповідей і повернені IP.
Рішення: Якщо прямі запити не працюють — резолвер нездоровий або недоступний. Якщо працюють — порядок резолверів клієнта або маршрутизація за доменами неправильні.
Четвертий крок: снифінг, щоб підтвердити, куди йдуть DNS-пакети
tcpdumpна інтерфейсі VPN і локальному інтерфейсі для порту 53.- Шукайте витоки внутрішніх зон до локальних резолверів.
Рішення: Якщо бачите витоки — впроваджуйте split DNS або блокуйте DNS поза тунелем. Якщо бачите таймаути — досліджуйте MTU і втрати пакетів.
П’ятий крок: опрацюйте реальність «DoH обходу»
- Вирішіть, чи дозволяєте ви застосунковий зашифрований DNS поза вашим резолвером.
- Якщо ні — забезпечте це через політику кінцевих точок і егрегні контроли; інакше документуйте поведінку і її вплив на внутрішні зони.
Типові помилки (симптоми → корінь проблеми → виправлення)
1) «VPN підключено, внутрішні сайти не резолвляться»
Симптом: внутрішні хости повертають NXDOMAIN або резолвляться в публічні IP.
Корінь проблеми: клієнт все ще використовує локальний DNS; немає умовної маршрутизації для внутрішнього суфіксу; NRPT/записи резолвера відсутні.
Виправлення: реалізуйте split DNS: направляйте corp.example на внутрішній DNS через VPN; верифікуйте через dig і packet capture, що запити йдуть через тунель.
2) «Працює по Ethernet, не працює по Wi‑Fi/в готелі»
Симптом: періодичні таймаути, особливо для більших відповідей; інколи лише деякі записи не працюють.
Корінь проблеми: невідповідний MTU призводить до падіння фрагментів; UDP-відповідь усе ще обрізується.
Виправлення: налаштуйте MTU VPN; забезпечте TCP-fallback; розгляньте обмеження EDNS буфера, якщо потрібно.
3) «Тільки деякі користувачі витікають DNS»
Симптом: непослідовні витоки; користувачі з однаковим налаштуванням працюють по-різному.
Корінь проблеми: відмінності ОС (systemd-resolved vs legacy resolvconf), кілька активних інтерфейсів, поведінка fallback резолверів.
Виправлення: стандартизувати інструмент керування DNS на клієнтах; тестувати на кожній ОС, яку ви підтримуєте; явно налаштувати маршрутизацію по доменах і пріоритети резолверів.
4) «Внутрішнє розв’язування працює, але застосунки не підключаються»
Симптом: DNS повертає правильні внутрішні IP; TCP-з’єднання не встановлюється.
Корінь проблеми: split tunnel маршрути не включають діапазони сервісів; security groups/фаєрволи блокують; асиметрична маршрутизація.
Виправлення: виправте рекламу маршрутів і політику безпеки; перевірте за допомогою ip route get і traceroute через тунель.
5) «Публічний DNS повільний, коли VPN увімкнено»
Симптом: затримки в перегляді; багато «очікування DNS» у devtools.
Корінь проблеми: ви примусили весь DNS через внутрішні резолвери в одному регіоні; затримка і завантаження зростають; промахи кеша підсилюють біль.
Виправлення: використайте split DNS для публічних запитів або розгорніть регіональні резолвери доступні через VPN; забезпечте кешування і здоровий вибір upstream.
6) «Ми заблокували порт 53, але витоки все одно відбуваються»
Симптом: запити внутрішніх доменів все ще видимі зовні.
Корінь проблеми: DoH/DoT обхід; DNS вбудований у застосунки; резолвер використовує нестандартні порти.
Виправлення: опрацюйте політику зашифрованого DNS: конфіги кінцевих точок, DNS-проксі або контрольовані DoH-ендпоїнти. Не імітуйте, що порт 53 — це вся історія.
7) «Все ламається після ввімкнення валідації DNSSEC»
Симптом: SERVFAIL на багатьох доменах; періодичні успіхи.
Корінь проблеми: MTU/фрагментація на шляху upstream, поламні middlebox, або зсув часу, що впливає на ланцюги валідації.
Виправлення: перевірте MTU, дозвольте TCP/53, забезпечте правильний синхрон часу і розгортайте поступово. DNSSEC — це не вимикач; це зобов’язання.
Три міні-історії з корпоративного життя (анонімізовано)
Міні-історія 1: Інцидент через хибне припущення
Середня SaaS-компанія впровадила split-tunnel VPN, щоб зменшити витрати на трафік. VPN штовхав внутрішні DNS, і команда припустила, що «DNS вирішено». Базове тестування пройшло: підключитися з домашнього Wi‑Fi, розв’язати внутрішній Git, відправити зміни.
Потім настала понеділкова реальність. Користувачі в коворкінгах повідомили про збій внутрішніх застосунків, але лише інколи. Helpdesk підняв «VPN нестабільний». Мережна команда перевірила стан тунелів: все «зелене». Аутентифікація: зелена. CPU на шлюзах VPN: у нормі. Тим часом хтось помітив, що внутрішні запити відображалися в логах публічного DNS-провайдера — бо підмножина клієнтів падала у fallback, коли внутрішній резолвер таймаутився.
Хибне припущення було тонким: «якщо DNS-сервер налаштований, запити підуть туди». Насправді, якщо маршрут до цього резолвера не гарантовано через VPN, клієнти все одно намагаються, падають і тихо використовують наступний резолвер. Split tunnel мав маршрути для підмереж застосунків, але не для підмережі DNS-серверів. Тож DNS IP був налаштований, але недоступний з багатьох мереж.
Виправлення було нудним: гарантувати, що IP резолверів завжди маршрутизуються через тунель, і впровадити умовну маршрутизацію для внутрішніх доменів. Також додали packet capture у runbook, щоб доказати, чи запити покидали тунель. Інцидент закінчився не героїчним патчем, а зміною таблиці маршрутів і політичним рішенням припинити покладатись на «fallback».
Міні-історія 2: Оптимізація, що обернулася проти
Великий ентерпрайз хотів «швидкий DNS скрізь», тож розгорнув регіональні внутрішні резолвери і придумав складні правила форвардингу. Публічні запити форвардили до локальних ISP-резолверів (низька затримка!), а внутрішні — через VPN до авторитетних серверів. На папері — чистий split.
У практиці це створило проблему когерентності кеша і кошмар для налагодження. Деякі пристрої мали власні кеші; деякі — корпоративний агент; інші — stub ОС. TTL відрізнялися по ланцюгах. Зміна A-запису для внутрішнього сервісу розповсюдилася нерівномірно, і частина користувачів продовжувала звертатись до старих IP навіть після переміщення сервісу.
Потім справжній прокол: в деяких регіонах ISP-резолвери агресивно фільтрували і інколи дивно відповідали на рідкісні типи записів. Для «звичайного браузингу» це мало значення, але зламало кілька продуктів безпеки і робочих процесів розробників, що залежали від специфічної DNS-поведінки. Раптом «оптимізація DNS» перетворилася на «розробники не можуть збирати», і мережна команда опинилася в центрі розслідування чужих фічів у резолверах.
Зрештою вирішили не віддавати публічну частину DNS випадковим ISP. Залишили регіональні внутрішні резолвери, але форвардили публічні запити до контрольованого, узгодженого набору upstream (також регіонального) з передбачуваною поведінкою і спостережуваністю. Продуктивність лишилась гарною. Кількість пейджів впала. Оптимізація залишилася, але контрольований змінний фактор був усунений.
Міні-історія 3: Нудна, але правильна практика, що врятувала ситуацію
Мале фінтех-підприємство тримало два внутрішні рекурсивні резолвери на регіон, доступні через VPN, і ставилося до DNS як до будь-якого іншого шару: моніторинг, алерти, контроль змін і планування потужності. Нічого екзотичного. Просто дисципліна.
Одного дня у хмарного провайдера сталася часткова мережна подія, що спричинила періодичну втрату пакетів між ingress VPN і одним вузлом резолвера. Кінцеві користувачі бачили «деякі внутрішні імена не працюють». Запахло проблемою застосунків, потім VPN, потім «може DNS». Класичне «хто винен».
Причина, через яку вони не зірвалися: мали метрики латентності на кожен резолвер і лічильники помилок запитів, а також логували, який резолвер відповів на кожен запит (принаймні для корпоративних stub-форвардерів). On-call побачив, що таймаути одного резолвера різко зросли, а інший був у нормі. Вони вивели проблемний вузол з обслуговування і спостерігали, як помилки зменшуються.
Без магії. Просто перевірені резолвери, резервування і спостережуваність. Репорт по інциденту був коротким — і це справжній знак зрілості.
Контрольні списки / покроковий план
Крок 1: Визначте вашу DNS-політику (запишіть її)
- Чи дозволяється, щоб запити внутрішніх доменів покидали пристрій поза тунелем? (Зазвичай: ні.)
- Чи дозволяється, щоб публічні домени використовували локальний мережний DNS? (Залежить: продуктивність проти відповідності.)
- Чи дозволяєте DoH/DoT напряму з клієнтів? Якщо так — для яких застосунків і до яких ендпоїнтів?
- Чи потрібне логування DNS-запитів? Якщо так — куди і на який термін?
Крок 2: Визначте простори імен і межі маршрутизації
- Перерахуйте внутрішні DNS-зони:
corp.example,internal.example, приватні зони хмари, Kubernetes-кластери. - Перерахуйте IP резолверів і забезпечте їх доступність через маршрути VPN.
- Перерахуйте внутрішні CIDR сервісів, які обов’язково мають маршрутизуватись через VPN (не лише підмережа DNS).
Крок 3: Явно реалізуйте split DNS
- Linux: налаштуйте per-link домени (наприклад,
~corp.example) і DNS-сервери на VPN-лінку. - Windows: використовуйте NRPT для внутрішніх просторів імен, якщо маєте керовані пристрої.
- macOS: забезпечте наявність per-domain записів резолвера для внутрішніх зон.
Крок 4: Закрийте реальні шляхи витоку
- Блокуйте UDP/TCP 53 поза тунелем, якщо політика вимагає відсутності зовнішнього DNS.
- Опрацюйте DoH/DoT політику та її виконання; не розраховуйте на бажання.
- Запобігайте тому, щоб fallback резолвери захоплювали внутрішні простори імен.
Крок 5: Зробіть DNS стійким і спостережуваним
- Щонайменше два резолвери на регіон або POP VPN.
- Health checks, які відображають реальне розв’язування, а не лише «порт 53 відкритий».
- Логи або метрики: швидкість запитів, SERVFAIL, NXDOMAIN, розподіл латентності, частота попадань у кеш.
Крок 6: Тестуйте з ворожих мереж
- Wi‑Fi в готелі, кавʼярні, мобільні хотспоти, captive portal.
- Сценарії з IPv6 увімкнено/вимкнено (деякі витоки відбуваються через IPv6-шляхи, які ви могли забути).
- Клієнти з кількома активними інтерфейсами (Wi‑Fi + Ethernet + віртуальні адаптери).
Крок 7: Випустіть runbook, що відповідає реальності
- Включіть команди з розділу «Практичні завдання».
- Визначення «DNS-витоку» для вашої організації (лише внутрішні або всі домени).
- Границі ескалації: команда кінцевих точок vs мережна команда vs DNS-команда.
FAQ
1) Що саме вважається DNS-витоком?
DNS-витік — це будь-який DNS-запит, що надсилається до резолвера поза вашою визначеною межею довіри. Для багатьох організацій виток — це коли внутрішні простори імен (наприклад, corp.example) йдуть до публічних або локальних резолверів. У суворіших середовищах будь-який DNS поза тунелем — це витік.
2) Чому split tunneling ускладнює DNS?
Тому що DNS має відповідати намірам трафіку. Якщо VPN маршрутизує лише деякі підмережі, але DNS налаштовано на використання внутрішнього резолвера, цей резолвер має бути доступним через тунель. Інакше клієнти перейдуть у fallback до інших резолверів, часто зовнішніх.
3) Якщо я штовхаю DNS-сервери через VPN, чи цього достатньо?
Ні. Ви маєте гарантувати маршрут до цих DNS-серверів через VPN і контролювати правила вибору резолвера, щоб внутрішні простори імен не обробляли fallback-резолвери. Конфігурація — це не те саме, що примусове виконання.
4) Нам запускати свої рекурсивні резолвери чи просто форвардити на публічний DNS?
Якщо вам потрібна узгоджена поведінка, спостережуваність і внутрішні зони — запускайте свої рекурсивні резолвери (або керований резолвер під вашим контролем) і форвардьте upstream передбачувано. Форвардити публічну частину до випадкових локальних резолверів — це надійність, замаскована під економію.
5) А як щодо зашифрованого DNS (DoH/DoT)?
DoH/DoT захищає приватність по каналу, але може обійти маршрутизацію DNS вашого VPN. Визначте політику: дозволяти з охороною чи блокувати/перенаправляти через політику кінцевих точок і мережеві контроли. Прикидання, що цього не існує, породжує витоки навіть при «блокуванні» DNS.
6) Як обробляти внутрішній DNS, коли користувачі в IPv6 мережах?
Переконайтесь, що ваш VPN і DNS-план охоплюють IPv6 явно: доступність резолверів, маршрути і відповіді на AAAA. Якщо ви працюєте лише з IPv4, деякі клієнти можуть резолвити й підключатися по IPv6 поза тунелем, і ви будете ловити привидів.
7) Чому деякі внутрішні запити працюють, а інші таймаутяться?
Типові причини: MTU-проблеми, що ріжуть великі відповіді; втрата пакетів на шляху VPN; перевантажені резолвери; або fallback резолверів. Перевіряйте за допомогою tcpdump, MTU-тестів і прямого dig проти внутрішнього резолвера.
8) Чи можна «просто заблокувати порт 53», щоб зупинити витоки?
Блокування 53 допомагає, але недостатньо. Застосунки можуть використовувати DoH по 443, і деякі середовища використовують DNS на нестандартних портах. Також блокування 53 без наявності робочого резолвера у тунелі перетворює «запобігання витоків» на «вихід в інтернет відсутній».
9) Який найпростіший безпечний підхід для змішаного флоту ОС?
Використовуйте split DNS з умовним форвардингом і гарантуйте маршрутизацію до внутрішніх резолверів. Стандартизуйте конфіг клієнтів через MDM/GPO де можливо. Додайте моніторинг резолверів. Потім тестуйте з ворожих мереж.
10) Як довести, що ми виправили витік?
Захопіть пакети на клієнті: переконайтеся, що запити внутрішніх зон з’являються на інтерфейсі VPN і не з’являються на локальному інтерфейсі. Також логувати запити на внутрішніх резолверах і корелювати. Доказ важливіший за скриншоти.
Практичні наступні кроки
- Визначте політику. Вирішіть, що для вас означає «витік» і чи має публічний DNS йти через VPN.
- Зробіть досяжність резолверів обовʼязковою. Забезпечте маршрути до IP резолверів через VPN навіть у режимі split tunnel.
- Реалізуйте split DNS навмисно. Умовна маршрутизація для внутрішніх просторів імен, а не просто «встановити DNS-сервер».
- Спостерігайте за цим. Додайте health checks резолверів, метрики затримки і достатнє логування, щоб відповідати на питання «який резолвер відповів».
- Тестуйте в реальному світі. Готелі, captive portal, IPv6 мережі і пристрої з кількома інтерфейсами — бо саме там живуть ваші користувачі.
Якщо ви зробите ці п’ять речей, DNS перестане бути щотижневою таємницею і стане тим, чим має бути: нудною інфраструктурою, що тихо робить свою роботу.