Split-horizon DNS: Нехай LAN-імена резолюються, не ламаючи публічний інтернет

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

Все працює… поки не перестає. Ви додаєте блискуче внутрішнє ім’я хоста, наприклад git.company.com, що вказує на приватний IP,
і раптом ноутбуки в гостевому Wi‑Fi не можуть дістатися реального публічного сайту. Або гірше: внутрішнє ім’я витікає назовні,
і тепер ваша «приватна» інфраструктура базікає з чужими.

Split-horizon DNS — також звана split-brain DNS — це доросле рішення: різні відповіді залежно від того, звідки запит. Зроблено правильно, LAN-імена резолюються чисто, публічна резолюція лишається коректною, а ваш on-call персонал спить. Зроблено неправильно — ви винаходите нові й цікаві режими відмов.

Що таке split-horizon DNS насправді (і чого це не означає)

Split-horizon DNS означає, що ваша DNS-інфраструктура повертає різні записи для одного й того самого імені залежно від мережевого контексту клієнта:
IP-адреси джерела, інтерфейс, стан VPN або явні правила «view». Класичний випадок — внутрішні клієнти резолюють app.example.com
як 10.10.20.30, тоді як зовнішні клієнти бачать 203.0.113.10 за CDN або WAF.

Split-horizon DNS — це не «використовувати внутрішній суфікс на кшталт .lan і вважати справу зробленою.» Це може працювати в домашній лабораторії,
але в підприємствах це часто породжує підводні камені: міграція пристроїв, розділення тунелів VPN, внутрішній TLS і незручна реальність, що люди будуть вводити те, що схоже на публічне ім’я.

І ще: split-horizon — це не магічний регулятор продуктивності. DNS вже швидкий, якщо ви не ламаєте кешування або не створюєте цикли. Мета — коректність і передбачувана резолюція. «Передбачувана» — ключове слово. Резолвер, який відповідає швидко, але непослідовно, — це просто генератор високошвидкісних збоїв.

Чітка ментальна модель

  • Авторитетні сервери публікують «правду» щодо зони (або кілька правд через views).
  • Рекурсивні резолвери шукають відповіді від імені клієнтів і кешують результати.
  • Stub-резолвери живуть на клієнтах і пересилають запити рекурсивному резолверу.

Split-horizon можна реалізувати на рівні авторитетних серверів (дві різні авторитетні «правди» залежно від джерела) або на рівні рекурсії (перезапис окремих імен всередині, водночас використовуючи публічний інтернет для всього іншого). Обидва підходи працюють. Тільки один з них зазвичай чисто масштабується у вашій організації, залежно від того, хто що володіє.

Жарт №1: DNS — єдина система, де «вчора працювало» вважається вагомим доказом нічого.

Цікаві факти та історія для аргументів

Ось короткі, конкретні контекстні пункти. Вони корисні, коли ви переконуєте команди безпеки, мереж і додатків припинити «креативно» звертатися з іменами.

  1. DNS передував сучасним припущенням про безпеку. Ранній DNS (середина 1980‑х) був побудований для кооперативних мереж; цілісність і автентичність зʼявилися пізніше, додані через DNSSEC.
  2. Split-horizon набув популярності з периферійними брандмауерами. Коли стали поширені NAT і шаблони DMZ, одне і те саме ім’я часто вимагало різних відповідей для внутрішньої та зовнішньої маршрутизації.
  3. RFC 1918 приватні діапазони IP (1996) нормалізували ідею, що внутрішня адресація фундаментально відрізняється від публічної маршрутизації — і DNS мав відображати цю реальність.
  4. «Split-brain DNS» старший за хмару. Патерн існував задовго до VPC; хмара просто ускладнила життя, давши багато «внутрішніх» зон з перекриттям і напіввласними зонами.
  5. Кешування DNS — причина, чому ваші зміни «не працюють». TTL і поведінка негативного кешування (NXDOMAIN) часто пояснюють, чому один ноутбук бачить новий запис, а інший — ні.
  6. DNS search domains — це зброя зворотної дії. Багато резолверів додають суфікси пошуку і генерують кілька запитів. Неправильно налаштовані списки пошуку можуть створювати несподівані запити й витоки.
  7. Суфікс .local особливий у багатьох стеках. Його використовує multicast DNS (mDNS). Використовувати його для unicast DNS — класична пастка «працює в мене».
  8. EDNS Client Subnet змінив уявлення про «де ви знаходитесь». Деякі публічні резолвери можуть передавати підказки про підмережу клієнта до CDN. Це добре для продуктивності і плутанини при відлагодженні.
  9. DNS over HTTPS і DNS over TLS ускладнюють корпоративний контроль. Якщо клієнти обходять ваш резолвер, ваша логіка split-horizon може ніколи не спрацювати.

Рішення з дизайну, що важливі в продакшні

1) Виберіть стратегію простору імен: одне й те саме ім’я чи різні імена

Є два широкі підходи:

  • Той самий FQDN всередині і зовні (наприклад, git.company.com резолюється всередині в RFC1918 і зовні в публічний IP/CDN). Це найзручніше для людей і додатків. Воно також найпростіше випадково неправильно налаштувати.
  • Інше внутрішнє ім’я (наприклад, git.internal.company.com або git.corp). Це зменшує шанси конфліктів з публічним DNS, але підвищує операційну фрикцію: сертифікати, редиректи, CORS, OAuth‑callback-и та поведінку користувачів.

Думка: якщо ви керуєте серйозними внутрішніми додатками, якими користуються реальні люди і пристрої мігрують (ноутбуки, телефони, VPN), використовуйте той самий FQDN і реалізуйте split-horizon правильно. Якщо це невелика статична лабораторія, різні внутрішні імена допустимі — поки ви не почнете виписувати TLS і інтегруватися з SaaS, тоді ви пожалкуєте про свій вибір.

2) Вирішіть, де відбувається розділення: авторитетно чи рекурсивно

Реалізуйте split-horizon на рівні авторитетних серверів, коли ви контролюєте зону і потребуєте детермінованих відповідей для внутрішніх/зовнішніх джерел. Приклад: BIND views, NSD з різними інстансами або split views у хмарного DNS.

Реалізуйте split-horizon на рівні рекурсії, коли ви хочете тримати публічну авторитетну DNS простою і переоприділяти лише невеликий набір імен всередині. Приклад: local zones в Unbound, переоприділення в dnsmasq або умовна пересилка до внутрішніх авторитетних серверів.

Думка: для підприємств віддавайте перевагу розділенню на краю рекурсії плюс чистій внутрішній авторитетній зоні. Покладіть якнайменше «політики» в авторитетні сервери, які спільні між середовищами. Для менших мереж один екземпляр BIND з views — цілком прийнятний, якщо ви ставитесь до нього як до продакшну і тестуєте зміни.

3) Уникайте «тіньових зон», якщо не любите сюрпризів

Тіньова зона — це коли внутрішній DNS-сервер вдає, що він авторитетний для публічної зони (скажімо, company.com), але містить лише кілька записів. Все інше перетворюється на NXDOMAIN або застарілі відповіді. Це ламає випадкові речі так, що відчувається як проклята магія.

Якщо ви мусите переоприділяти в межах публічної зони, робіть це через:

  • авторитетні split views, які все ще містять повний вигляд зони, або
  • рекурсивні переоприділення для конкретних імен, дозволяючи всім іншим іменам резолюватися публічно.

4) Стратегія TTL: достатньо низько для змін, але не настільки, щоб розплавити кеші

TTL — це не «наскільки швидкий DNS». TTL — це наскільки довго тримається ваша помилка.

Для внутрішніх переоприділень, які можуть змінюватися під час інциденту (failover, DR), поширені TTL від 30 до 300 секунд. Для стабільних внутрішніх записів підходять 300–3600 секунд. Для публічних записів за CDN зазвичай діє політика провайдера.

Низькі TTL збільшують обсяг запитів і підсилюють відмови, коли резолвер коливається. Високі TTL збільшують час відновлення, коли треба перемістити endpoint. Обирайте навмисно, для класу записів, і вимірюйте QPS резолверів перед «оптимізацією».

5) Зробіть DNSSEC усвідомленим рішенням, а не випадковістю

DNSSEC валідація стає все більш розповсюдженою (корпоративні резолвери, деякі ISP). Split-horizon може погано взаємодіяти з DNSSEC, якщо ви подаєте підписані/непідписані відповіді по-різному або якщо ви переоприділяєте підписані публічні імена без контролю над ключами підпису.

Практичні рекомендації:

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

6) Враховуйте сучасних клієнтів: DoH, VPN і «допоміжні» резолвери ОС

Split-horizon припускає, що ви знаєте, куди клієнт надсилає DNS. Але браузери й ОС мають свої вподобання:

  • DNS over HTTPS може повністю обійти ваш резолвер. Ваші внутрішні імена не резолюються, і ваша політика не застосовується.
  • systemd-resolved може робити DNS за інтерфейсом і маршрутизацію запитів за доменом. Це чудово при налаштуванні. Це плутає, коли не налаштовано.
  • VPN split tunneling може маршрутизувати DNS інакше, ніж трафік, створюючи хаос «DNS каже всередині, пакети йдуть назовні».

Зразкові архітектури: три розумні патерни

Патерн A: Авторитетні views (BIND “views”) + внутрішня рекурсія

Ви запускаєте набір авторитетних серверів, які відповідають зовнішнім клієнтам публічними записами, а внутрішнім — приватними записами, на основі ACL по IP джерела. Внутрішні резолвери питають їх, зовнішні — теж, і всі «щасливі».

Плюси: одне ім’я зони, чітка політика, детермінованість. Мінуси: views складні в конфігурації; помилки можуть витікати внутрішні записи або подавати неповні зони; тестування вимагає дисципліни.

Патерн B: Рекурсивні переоприділення (Unbound/dnsmasq) + публічні авторитетні залишаються публічними

Публічна зона лишається як є, розміщена будь-де. Всередині LAN ви запускаєте рекурсивні резолвери, які переоприділяють окремі імена (або перенаправляють певні зони) на внутрішні авторитетні сервери.

Плюси: мінімальна звʼязаність; легко пояснити; менше шляхів зламати публічний інтернет. Мінуси: тепер ви залежите від того, що клієнти користуються вашим резолвером; DoH може обійти вас; потрібна висока доступність резолверів.

Патерн C: Окрема внутрішня підзона + умовна пересилка

Розмістіть внутрішні імена під делегованою підзоною, наприклад corp.company.com, і пересилайте цю зону внутрішньо. Публічний DNS або не публікує її, або публікує лише те, що ви хочете.

Плюси: чисте відокремлення; менше конфліктів; DNSSEC простіше, якщо ви підписуєте внутрішню зону окремо. Мінуси: люди все одно вводитимуть публічне ім’я; додатки інтегруються з публічними callback-ами; зрештою вам все одно знадобиться split для деяких імен.

Думка: Патерн B — найкращий дефолт для більшості організацій. Патерн A потужний, коли вам реально потрібне «одне ім’я, дві правди» на рівні авторитету. Патерн C — ковдра безпеки, що працює, поки не перестане.

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

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

Завдання 1: Підтвердьте, яким резолвером хост насправді користується

cr0x@server:~$ resolvectl status
Global
         Protocols: -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
  resolv.conf mode: stub
Current DNS Server: 10.10.0.53
       DNS Servers: 10.10.0.53 10.10.0.54
        DNS Domain: corp.company.com
Link 2 (ens192)
    Current Scopes: DNS
         Protocols: +DefaultRoute -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
Current DNS Server: 10.10.0.53
       DNS Servers: 10.10.0.53 10.10.0.54

Що це означає: systemd-resolved задіяний; DNS іде на 10.10.0.53/.54. Є підказка маршрутизації домену для corp.company.com.

Рішення: Якщо користувачі повідомляють «внутрішні імена не резолюються», перевірте, що вони підключені до цих резолверів. Якщо ви бачите публічний DNS (ISP, 1.1.1.1, 8.8.8.8), у вас немає split-horizon; у вас є надія.

Завдання 2: Доведіть наявність split заціленим запитом до внутрішнього резолвера

cr0x@server:~$ dig @10.10.0.53 app.company.com +noall +answer
app.company.com.        60      IN      A       10.10.20.30

Що це означає: Внутрішній резолвер повертає приватний IP з TTL 60.

Рішення: Якщо це правильно, ваш внутрішній view/override працює. Далі: перевірте, що бачить зовнішній світ.

Завдання 3: Порівняйте з публічною резолюцією (не довіряючи своєму резолверу)

cr0x@server:~$ dig @1.1.1.1 app.company.com +noall +answer
app.company.com.        300     IN      A       203.0.113.10

Що це означає: Публічна відповідь відрізняється (очікувано для split-horizon). TTL вищий.

Рішення: Якщо публіка повертає приватний IP — ви витікаєте. Якщо публіка повертає NXDOMAIN — ймовірно, ви зробили shadow-zone і зламали інтернет для себе.

Завдання 4: Визначте, звідки прийшла відповідь (авторитетно чи з кешу)

cr0x@server:~$ dig @10.10.0.53 app.company.com +norecurse
; <<>> DiG 9.18.24-1 <<>> @10.10.0.53 app.company.com +norecurse
;; flags: qr aa; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
app.company.com.        60      IN      A       10.10.20.30

Що це означає: aa вказує, що сервер вважає себе авторитетним для цієї відповіді.

Рішення: Якщо ви очікували рекурсивного переоприділення і бачите aa, можливо, ви подаєте view/зону, якої не мали на меті (ризик тіньової зони).

Завдання 5: Перевірте негативне кешування (NXDOMAIN, який не минає)

cr0x@server:~$ dig @10.10.0.53 newhost.corp.company.com +noall +answer +authority
corp.company.com.       900     IN      SOA     ns1.corp.company.com. hostmaster.corp.company.com. 2025123101 3600 600 1209600 60

Що це означає: Немає секції відповіді; authority показує SOA. Резолвер ймовірно кешував NXDOMAIN; негативний TTL часто походить від мінімального/негативного TTL у SOA.

Рішення: Якщо ви щойно створили newhost, або дочекайтеся закінчення негативного кешу, або очистіть кеш, або зменшіть негативний TTL у SOA для зон, які часто змінюються.

Завдання 6: Безпечно очистіть кеш резолвера (systemd-resolved)

cr0x@server:~$ resolvectl flush-caches
cr0x@server:~$ resolvectl statistics
DNSSEC supported by current servers: no
Transactions               Current Transactions: 0
Cache                       Current Cache Size: 12
Cache                         Cache Hits: 221
Cache                       Cache Misses: 45

Що це означає: Кеш очищено; статистика показує поточну поведінку.

Рішення: Якщо очищення «постійно фіксує» проблему, у вас проблема з TTL/негативним кешуванням або непослідовними відповідями upstream.

Завдання 7: Перевірте цілісність зони BIND перед перезавантаженням (без геройських перезавантажень)

cr0x@server:~$ named-checkzone corp.company.com /etc/bind/zones/db.corp.company.com
zone corp.company.com/IN: loaded serial 2025123101
OK

Що це означає: Файл зони розбирається, серіал присутній, BIND навряд чи відкине його.

Рішення: Якщо перевірка не проходить, не перезавантажуйте. Виправте синтаксис; інакше ви можете подати старішу зону або повністю провалити view.

Завдання 8: Перевірте конфігурацію BIND (views та ACL — там проблеми)

cr0x@server:~$ named-checkconf -z
zone corp.company.com/IN: loaded serial 2025123101
zone company.com/IN: loaded serial 2025123105

Що це означає: Конфіг синтаксично вірний і зони завантажуються.

Рішення: Якщо named-checkconf видає помилки, не перезапускайте BIND. Виправте конфіг; рестарт під навантаженням — спосіб отримати сповіщення двічі.

Завдання 9: Підтвердіть, до якої view потрапляє клієнт (BIND querylog)

cr0x@server:~$ sudo rndc querylog on
cr0x@server:~$ sudo tail -n 3 /var/log/named/query.log
31-Dec-2025 11:03:22.918 client @0x7f2c8c1a: query: app.company.com IN A +E(0)K (10.10.0.53) [view "internal"]
31-Dec-2025 11:03:23.104 client @0x7f2c8c2b: query: app.company.com IN A +E(0)K (10.10.0.53) [view "external"]
31-Dec-2025 11:03:23.201 client @0x7f2c8c2b: query: www.company.com IN A +E(0)K (10.10.0.53) [view "external"]

Що це означає: Два клієнти (або джерела за NAT) класифікуються в різні views.

Рішення: Якщо внутрішній клієнт позначено як external, виправте ACL, адреси джерела або поведінку NAT. Не «додавайте ще один запис»; так ви створюєте повільнодіючий апокаліпсис.

Завдання 10: Виявлення циклів пересилки (тихий вбивця резолвера)

cr0x@server:~$ dig @10.10.0.53 corp.company.com SOA +time=1 +tries=1
;; communications error to 10.10.0.53#53: timed out
;; no servers could be reached

Що це означає: Резолвер швидко таймаутить. Під капотом це часто відбувається, коли Резолвер A пересилає Резолверу B, який пересилає назад до A.

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

Завдання 11: Перегляньте локальні переоприділення Unbound (що він «бреше»?)

cr0x@server:~$ sudo unbound-control list_local_zones
corp.company.com. transparent
company.com. nodefault

Що це означає: corp.company.com обробляється прозоро; company.com переоприділено (nodefault), що може затіняти публічні дані.

Рішення: Якщо ви не мали наміру широко переоприділяти company.com, видаліть або звузьте це до конкретних хост-переоприділень.

Завдання 12: Запитайте Unbound про локальні дані і перевірте, чи воно «авторитетне-ish»

cr0x@server:~$ dig @10.10.0.53 app.company.com +noall +answer +comments
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 61545
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
app.company.com.        60      IN      A       10.10.20.30

Що це означає: Це рекурсивна поведінка (rd/ra), а не авторитетна (aa відсутній). Добре для патерну «переоприділити конкретні імена».

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

Завдання 13: Підтвердіть умовну пересилку (Windows/AD середовища)

cr0x@server:~$ dig @10.10.0.10 _ldap._tcp.dc._msdcs.corp.company.com SRV +noall +answer
_ldap._tcp.dc._msdcs.corp.company.com. 600 IN SRV 0 100 389 dc01.corp.company.com.

Що це означає: AD DNS повертає SRV записи; пересилка для corp.company.com ймовірно працює.

Рішення: Якщо SRV-пошуки періодично падають, спершу розглядайте це як проблему маршрутизації split-horizon (неправильний резолвер на деяких клієнтах), перш ніж звинувачувати Kerberos.

Завдання 14: Перевірте, чи клієнти обходять вас через DoH (перевірка на рівні браузера)

cr0x@server:~$ sudo tcpdump -ni any port 53 -c 5
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes
11:09:41.120421 ens192 In  IP 10.10.50.21.53821 > 10.10.0.53.53: 31614+ A? app.company.com. (33)
11:09:41.120987 ens192 Out IP 10.10.0.53.53 > 10.10.50.21.53821: 31614 1/0/0 A 10.10.20.30 (49)
11:09:44.908112 ens192 In  IP 10.10.50.21.34620 > 10.10.0.53.53: 1720+ A? www.company.com. (33)
11:09:44.908621 ens192 Out IP 10.10.0.53.53 > 10.10.50.21.34620: 1720 1/0/0 A 203.0.113.10 (49)
5 packets captured

Що це означає: Принаймні для цих запитів клієнт використовує класичний DNS до вашого резолвера.

Рішення: Якщо користувачі скаржаться, але ви не бачите трафіку на порт 53, підозрівайте DoH/DoT або дивну поведінку captive portal. Ваш split-horizon нічого не зробить, якщо він ніколи не бачить запиту.

Завдання 15: Підтвердіть, що зворотний DNS відповідає прямому split (інакше зламаєте аудити та деяку автентифікацію)

cr0x@server:~$ dig @10.10.0.53 -x 10.10.20.30 +noall +answer
30.20.10.10.in-addr.arpa. 300 IN PTR app.company.com.

Що це означає: PTR існує і вказує назад на очікуване ім’я.

Рішення: Якщо зворотний DNS відсутній або вказує на публічне ім’я, виправте це. Деякі системи (пошта, логування, засоби безпеки) використовують rDNS для кореляції і перевірок.

Завдання 16: Виміряйте затримку DNS і виявляйте таймаути (реальний тест «DNS повільний»)

cr0x@server:~$ dig @10.10.0.53 app.company.com +stats +noall +answer
app.company.com.        60      IN      A       10.10.20.30
;; Query time: 2 msec
;; SERVER: 10.10.0.53#53(10.10.0.53) (UDP)
;; WHEN: Wed Dec 31 11:12:12 UTC 2025
;; MSG SIZE  rcvd: 49

Що це означає: 2 мс — здорово для LAN.

Рішення: Якщо ви бачите 200–2000 мс, підозрівайте проблеми з форвардингом, втрату пакетів, MTU-проблеми з EDNS або перевантажений резолвер. Виправте затримку до того, як чіпатимете ретраї додатків.

Жарт №2: Якщо хочете сховати деталі інфраструктури, не кладіть їх у DNS — DNS по суті офісний гучномовець.

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

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

Перш за все: підтвердьте шлях резолюції клієнта

  • Перевірте, якими DNS-серверами користується хост (resolvectl status на Linux, налаштування мережі на інших). Якщо це не ваш внутрішній резолвер, split-horizon не діє.
  • Запустіть tcpdump на резолвері: чи бачите ви запити від клієнта?
    Якщо ні — підозрівайте DoH/DoT, VPN або інший резолвер.

По-друге: порівняйте внутрішні й публічні відповіді на те саме ім’я

  • Опитайте внутрішній резолвер напряму через dig @internal.
  • Опитайте відомий публічний резолвер через dig @1.1.1.1 (або ваш базовий вибір).
  • Якщо публічний резолвер «неправильний», ваша публічна авторитетна DNS неправильна або витікає.
    Якщо внутрішній «неправильний», ваша внутрішня логіка переоприділення/view/форвардингу неправильна.

По-третє: визначте, чи відповідь авторитетна, з кеша або з upstream, що падає

  • +norecurse плюс огляд прапорів: aa означає авторитетну відповідь.
  • Шукайте таймаути: повторні communications error зазвичай означають мережу або цикли форвардингу.
  • Перевірте негативне кешування: SOA в authority без answer часто вказує на кешований NXDOMAIN.

По-четверте: ізолюйте транспортні та EDNS-проблеми

  • Якщо UDP не працює, але TCP проходить — підозрюйте MTU/фрагментацію або правила фаєрволу.
  • Якщо DNS працює для малих відповідей, але падає при багатьох записах — підозрюйте проблеми з EDNS буфером.

По-п’яте: підтвердьте класифікацію view/ACL (якщо використовуєте views)

  • Коротко увімкніть логування запитів і визначте, в яку view клієнти потрапляють.
  • Виправте ACL або поведінку NAT; не заклеюйте дублюванням записів.

Одна цитата для тих, хто вимагає «швидке виправлення», що насправді — лотерея:
paraphrased idea — John Allspaw: робота — це розуміння системи; звинувачення людей не покращує надійність.

Поширені помилки: симптом → корінь → виправлення

1) «Внутрішній додаток працює по VPN, але не в офісному Wi‑Fi»

Симптом: Той самий ноутбук, різні мережі, різна відповідь.

Корінь: Різні резолвери за інтерфейсами; офісний Wi‑Fi роздає публічний DNS, VPN штовхає внутрішній DNS (або навпаки).

Виправлення: Уніфікуйте DHCP DNS-опції; використовуйте маршрутизацію за доменом (split DNS) на VPN, щоб лише внутрішні домени йшли до внутрішніх резолверів; перевіряйте через resolvectl status.

2) «Деякі користувачі отримують стару IP годинами»

Симптом: Застарілі відповіді довго після зміни.

Корінь: TTL занадто високі або проміжні кешуючі резолвери (включно з домашніми роутерами) ігнорують бажану поведінку; негативне кешування для NXDOMAIN також кусає.

Виправлення: Зменшуйте TTL напередодні міграцій; очищуйте кеші на контрольованих резолверах; повідомте, що некеровані резолвери будуть відставати. Для NXDOMAIN налаштуйте негативний TTL у SOA, якщо доречно.

3) «Публічні користувачі можуть резолювати приватні IP наших сервісів»

Симптом: Зовнішні запити повертають RFC1918 або внутрішні імена хостів.

Корінь: Неправильна класифікація view ACL, NAT робить зовнішні запити схожими на внутрішні, або рекурсивний резолвер випадково відкритий в інтернет.

Виправлення: Заблокуйте рекурсію лише для внутрішніх мереж; перевірте views через логування запитів; переконайтеся, що публічні відповіді приходять тільки з зовнішнього view/зони.

4) «Внутрі всі www.company.com NXDOMAIN, крім кількох записів»

Симптом: Випадкові публічні сайти під вашим доменом ламаються всередині.

Корінь: Тіньова зона: внутрішній DNS авторитетний для company.com, але не має повного вмісту зони.

Виправлення: Перестаньте подавати часткові авторитетні зони. Або хостіть повну зону внутрішньо з коректною синхронізацією, або робіть перезапис по записах на рівні рекурсії.

5) «DNS випадково таймаутить під навантаженням»

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

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

Виправлення: Прослідкуйте шляхи форвардингу; розірвіть цикли; додайте потужності резолверам; налаштуйте TTL; перевірте, що фаєрвол дозволяє UDP/TCP 53 на внутрішніх сегментах.

6) «Працює через dig, але браузери ламаються»

Симптом: Розвʼязка в командному рядку OK; браузер не може дістатися внутрішніх імен.

Корінь: Браузер використовує DoH до публічного резолвера, обходячи внутрішні переоприділення DNS.

Виправлення: Керуйте політиками DoH через корпоративні налаштування; надайте внутрішню DoH-точку, якщо потрібно; перевірте через захоплення трафіку і налаштування браузера.

7) «Сертифікати не збігаються після зміни split-horizon»

Симптом: TLS помилки всередині після вказування імені на приватний IP.

Корінь: Внутрішній сервіс не предʼявляє сертифікат для публічного імені, або TLS-термінація відрізняється внутрішньо і зовні.

Виправлення: Уніфікуйте TLS-термінацію; використовуйте сертифікати з правильними SAN; не розраховуйте, що «внутрішні користувачі натиснуть продовжити». Вони не натиснуть, і не повинні.

Три корпоративні міні-історії (і уроки, за які заплатили)

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

Середня SaaS-компанія хотіла, щоб внутрішні користувачі потрапляли «швидкою дорогою» до staging‑середовища. Хтось запропонував split-horizon для
staging.company.com: всередині — приватний лоадбалансер; зовні — загартований публічний endpoint.

Зміна зайшла в п’ятницю після обіду, бо так завжди буває. За годину почали надходити тікети: інженери в домашніх мережах не могли дістатися staging, а деякі офісні користувачі бачили попередження сертифікатів. Негайно всі подумали, що «лоадбалансер впав». Ні.

Неправильне припущення: вони вірили, що «внутрішній» означає «запити, що походять з нашого публічного IP‑діапазону». ACL їхнього view трактувала всі NAT‑адреси виходу з офісу як внутрішні — начебто нормально. Але їхній VPN концентратор також NAT‑ив віддалених користувачів за тим самим блоком вихідних IP. Залежно від стану маршрутів, користувач міг класифікуватися як внутрішній DNS‑wise, тоді як його трафік усе ще виходив через публічний інтернет без доступу до приватного лоадбалансера.

Результат — огидний розрив: DNS казав «йди приватно», маршрутизація казала «ти не можеш», а браузер казав «сертифікат не той». Рішення було смішно просте: класифікувати views по підмережах джерела, які реально репрезентують внутрішню досяжність, а не просто «те, що ми володіємо». Вони також перейшли на per-domain маршрутизацію DNS на VPN‑клієнті, щоб внутрішні імена йшли до внутрішніх резолверів лише коли VPN активний і маршрути наявні.

Урок: split-horizon — не про ідентичність або власність. Воно про досяжність. Якщо ваш «внутрішній» view включає клієнтів, які не можуть дістатися внутрішніх сервісів, ви побудували машину плутанини.

Міні-історія 2: Оптимізація, що обернулась проти

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

Графіки стали гарними. QPS резолверів впала. Кеші тішили око. Потім рутинна операція потребувала перемістити VIP внутрішнього сервісу в іншу підмережу через реорганізацію мережі. DNS‑запис змінився, і половина середовища продовжувала звертатися до старого IP, поки кеші не протухли. Деякі додатки мали свої власні DNS-кешеї поверх TTL, бо навіщо мати один кеш, якщо можна мати три.

Інцидент не був драматичним. Він був гірший: повільним. Періодичні збої, часткові відновлення і хвиля звернень до служби підтримки, де кожна команда бачила різні симптоми. Декілька резолверів чистили кеш; декілька — ні. Деяким користувачам допомагав перезавантаження ноутбука. Це не фікс; це ритуал.

Висновок після інциденту — більш збалансована TTL‑стратегія: низькі TTL для endpoint‑ів, що беруть участь в failover/міграціях, помірні для стабільних записів, і чіткі рукописи для інвалідизації кешу. Також ввели практику тимчасового зниження TTL перед плановими cutover — оперативна прозорливість дешевша за героячні порятунки.

Урок: «оптимізація» DNS, що ігнорує швидкість змін, — це просто відстрочений біль з кращими графіками.

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

Фінансова компанія тримала split-horizon для кількох критичних імен: портали автентифікації, внутрішні API і кілька партнерських endpoint‑ів, доступних лише через приватне підключення. У них було по два рівні рекурсивних резолверів на кожен датацентр, плюс внутрішній авторитетний кластер для corp.company.com. Нічого особливого — просто резервні, моніторені та документовані рішення.

Одного ранку зміна в мережі нагорі спричинила періодичну втрату пакетів до одного з авторитетних вузлів. Рекурсивні резолвери почали таймаутити для частини запитів. Тут часто все перетворюється на «DNS впав», після чого починаються безладні перезавантаження і заморожування змін.

Але їхня нудна практика спрацювала: у них були безперервні DNS‑чекі з кожного сайту, що опитували канарковий запис і вимірювали затримку. Алерт був не «DNS впав». Він був «затримка DNS зросла, авторитетний вузол A періодично недоступний з сайту X». Вони також мали логування запитів, готове до короткого увімкнення, і відомий робочий шлях відкату.

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

Урок: резервність — базова вимога. Спостережуваність і контрольований фейловер — те, що не дає вам гадати о 3 ранку.

Чек-листи / покроковий план

Покроковий план: впровадження split-horizon без самошкоди

1) Визначте імена та аудиторії

  • Перелічіть FQDN, що потребують різних внутрішніх і зовнішніх відповідей.
  • Визначайте «внутрішній» через досяжність (підмережі/маршрути VPN), а не через «людей, яких ми любимо».
  • Вирішіть, чи мають мобільні пристрої працювати безшовно (зазвичай так).

2) Оберіть точку застосування

  • Віддавайте перевагу рекурсивним переоприділенням/умовній пересилці, коли публічна авторитетна DNS належить іншій команді/постачальнику.
  • Використовуйте авторитетні views, коли потрібно публікувати ту саму зону з двома наборами відповідей і ви контролюєте авторитетні сервери.

3) Побудуйте резервні резолвери першими

  • Принаймні два внутрішні рекурсивні резолвери на сайт або домен відмови.
  • Обмежте рекурсію лише для внутрішніх мереж.
  • Моніторьте затримку запитів, частоту SERVFAIL і здоровʼя upstream.

4) Впроваджуйте переоприділення вузько

  • Переоприділяйте конкретні хост-імена (A/AAAA/CNAME) перед тим, як переоприділяти цілі зони.
  • Якщо мусите переоприділити зону, переконайтеся, що можете обслуговувати повний вигляд зони, а не частковий тінь.

5) Налаштуйте TTL та план міграцій

  • Використовуйте низькі TTL для імен, які можуть змінюватися під час інцидентів або розгортань.
  • Знижуйте TTL перед плановими cutover-ами; піднімайте назад після, якщо потрібно.
  • Пам’ятайте про негативне кешування; налаштуйте SOA для динамічних зон.

6) Валідовуйте з кількох точок

  • В середині LAN, по VPN і ззовні інтернету.
  • З принаймні одного керованого клієнта і одного «дивного» клієнта (BYOD/телефон).
  • Перевіряйте як прямі, так і зворотні записи там, де це має значення.

7) Керуйте DoH/DoT поведінкою

  • Вирішіть, чи клієнти можуть використовувати зовнішні DoH-резолвери.
  • Якщо ні — впровадьте політики і мережеві контролі, де можливі.
  • Якщо так — прийміть, що внутрішні імена не резолюватимуться, якщо ви не надасте внутрішню DoH-точку.

8) Документуйте «що ламається, якщо DNS ламається»

  • Auth (Kerberos/OIDC), репозиторії пакетів, залежності синхронізації часу, внутрішні PKI-ендпоїнти.
  • Пріоритезуйте моніторинг для цих імен і зон.

Операційний чек-лист: перед зміною split-horizon

  • Запустіть named-checkconf/named-checkzone (або еквівалент) перед reload/restart.
  • Підтвердіть, які клієнти в якій view / який шлях пересилки вони використовують.
  • Знизьте TTL напередодні, якщо потрібен швидкий rollback.
  • Майте план відкату, що не вимагає «відновлення з памʼяті».
  • Заплануйте коротке вікно для ввімкнення логування запитів під час rollout, потім вимкніть його (логи корисні; диск, що заповнився — ні).

Питання й відповіді (FAQ)

1) Чи те саме split-horizon DNS і split DNS на VPN-клієнтах?

Повʼязані, але не ідентичні. Split-horizon — це «різні відповіді залежно від того, де питають». Split DNS на VPN — це «надсилайте тільки певні доменні запити до VPN DNS‑серверів». Часто потрібно обидва: VPN маршрутизує внутрішні домени до внутрішніх резолверів, а внутрішні резолвери повертають внутрішні відповіді.

2) Чи варто використовувати .local для внутрішніх імен?

Ні. Багато систем трактують .local як територію mDNS. Ви можете змусити це працювати в деяких середовищах, але за це доведеться платити дивною поведінкою резолюції і часом на відлагодження.

3) Чи можу я просто запускати два окремі DNS-сервери й переключати DHCP залежно від мережі?

Можна, і іноді цього достатньо. Режим відмови — міграція й змішані мережі: пристрої з кешованими резолверами, VPN‑оверлеї і кілька інтерфейсів. Split-horizon — це те, що ви робите, коли «просто DHCP» перестає бути детермінованим.

4) Який найбезпечніший спосіб переоприділити кілька публічних імен всередині?

Робіть це на рівні рекурсії: local-data переоприділення (Unbound), host overrides (dnsmasq) або умовна пересилка для виділеної внутрішньої підзони. Уникайте ставати авторитетним для цілісної публічної зони, якщо ви не можете надати її повністю.

5) Як запобігти витоку внутрішніх DNS-записів назовні?

Не відкривайте рекурсивні резолвери для інтернету. Закрийте рекурсію через ACL. Якщо використовуєте views — перевірте класифікацію ACL і тестуйте з зовнішніх точок. Також будьте обережні з логами й експортом моніторингу — імена витікають і через телеметрію.

6) Чи руйнує split-horizon DNS DNSSEC?

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

7) Чому я отримую різні відповіді з різних машин в тій самій LAN?

Зазвичай одна з причин: різні резолвери в налаштуваннях, кешовані дані з різним часом життя TTL, або вибір DNS за інтерфейсом (особливо на ноутбуках з VPN, Wi‑Fi і дротовим Ethernet). Почніть з підтвердження налаштувань резолверів і опитування одного й того самого DNS-сервера явно через dig @server.

8) Чи потрібен мені зворотний DNS (PTR) для внутрішніх сервісів?

Не завжди, але коли потрібен — то дуже потрібен: кореляція логів, деякі інструменти безпеки, певні автентифікаційні потоки і розуміння людиною. Якщо ви будуєте split-horizon для критичних речей, розглядайте зворотні зони як частину системи, а не прикрасу.

9) Яким має бути TTL для записів failover?

Достатньо низько, щоб відновлення відбувалося за лічені хвилини, а не години — зазвичай 30–300 секунд. Потім протестуйте навантаження запитів і переконайтеся, що ваші резолвери справляються. Також пам’ятайте, що клієнти й бібліотеки можуть кешувати DNS незалежно від TTL.

10) Чи нормально CNAME‑ити внутрішні імена в публічні або навпаки?

Іноді так, але будьте обережні: CNAME‑ланцюжки перетинають кордони і ускладнюють поведінку split, кешування і TLS‑очікування. Надавайте перевагу прямим A/AAAA, коли потрібно детерміновані відповіді, особливо для критичних сервісів.

Висновок: практичні наступні кроки

Split-horizon DNS — це інфраструктурний патерн, що здається «простим», поки ви не підставите його під реальні умови: пристрої в русі, VPN, кеші, DoH і іноді добре намірені зміни, які перетворюють ваше простір імен на мистецтво перформансу.

Наступні кроки, які швидко окупаються:

  • Оберіть патерн (авторитетні views або рекурсивні переоприділення) і запишіть, чому.
  • Інвентаризуйте точні імена, що потребують split‑відповідей; тримайте список маленьким і навмисним.
  • Розгорніть резервні внутрішні рекурсивні резолвери і закрийте рекурсію.
  • Тестуйте з трьох точок: всередині LAN, по VPN і ззовні організації.
  • Вбудуйте ваш «швидкий діагноз» в on-call рутину: наведені вище команди плюс відомий хорошій канарковий запис.

Мета не в хитрому DNS. Мета — нудна резолюція імен, що залишається коректною, поки навколо все горить.

← Попередня
Ера майнінгу: як криптовалюти зламали ціни на GPU (знову й знову)
Наступна →
DNS‑записи з підстановкою: зручність, що тихо ламає речі (і як це виправити)

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