Непостійні збої DNS — найгірший тип інциденту: графіки виглядають «гарно», резолвер здається здоровим, але кілька доменів продовжують тайм-аутити, ніби це 1998 рік.
Якщо ви коли-небудь бачили, як dig вдається для одного імені і зависає для іншого, або помічали, що DNS працює через мобільний хостспот, але не через VPN — ви зустріли тихого лиходія: MTU, фрагментацію та ланцюжок припущень «має працювати» між клієнтом і резолвером.
Що насправді відбувається: чому MTU ламає DNS
DNS маленький, поки раптом ним не стає. A-запити для помірних зон зазвичай вміщуються в один UDP-пакет. Але в момент, коли відповіді зростають — підписи DNSSEC, багато записів, довгі TXT-рядки (вітання, SPF/DMARC), записи SVCB/HTTPS або просто балакучий резолвер — відповідь може перевищити Path MTU між клієнтом і сервером.
Коли це відбувається, для роботи UDP DNS має бути виконано одне з двох:
- Відповідь має бути фрагментована, і всі фрагменти мають дістатися клієнту.
- Або клієнт і сервер повинні погодити менший розмір корисної вантажу (зазвичай через EDNS(0)), щоб фрагментації взагалі не було.
У реальних мережах фрагментація крихка. Фаєрволи скидають фрагменти. NAT-пристрої «допомагають», часом просто втрачаючи їх у таймауті. Деякі балансувальники хешують тільки за першим фрагментом (який не містить UDP-портів для наступних фрагментів), і тоді ваші фрагменти йдуть різними шляхами, як поганий груповий проєкт.
Отже запит DNS відправлено, резолвер повертає надто велику UDP-відповідь, ця відповідь фрагментується, один фрагмент зникає, і клієнт чекає. Зрештою він повторює спробу, можливо по TCP, можливо до іншого резолвера, можливо ні. Ззовні ви бачите: «непостійний DNS». Зсередини ви бачите: «мережевий рівень 2–3, що маскується під рівень 7».
Path MTU Discovery (PMTUD) має запобігати цьому, змушуючи маршрутизатори відправляти ICMP «Fragmentation Needed» (IPv4) або «Packet Too Big» (IPv6), щоб кінцеві вузли дізналися максимальний розмір. Але PMTUD вимагає, щоб ICMP проходив. Багато середовищ ставляться до ICMP як до небажаного гостя і потім дивуються, чому комунікація тече.
Одна операційна реальність: DNS часто першим покаже біль від MTU, бо він всюдисущий, за замовчуванням використовує UDP і бере участь майже в кожній іншій каскаді відмов. Коли DNS ламається, усе виглядає зламаним. Ваше завдання — довести, що справа в MTU, а потім виправити шлях, щоб ви не провели тиждень, звинувачуючи резолвер.
Жарт №1: Якщо ви блокуєте ICMP, бо це «небезпечно», ви винайшли мережевий еквівалент видалення індикатора масла, бо він дратує.
Ключовий механізм: EDNS(0) і «який розмір занадто великий?»
Класичний DNS обмежував UDP-відповіді 512 байтами. EDNS(0) (RFC 2671, пізніше RFC 6891) розширив DNS, дозволивши клієнтам рекламувати більший UDP-буфер (часто 1232 байти — безпечний сучасний вибір). Це добре: зменшує перехід на TCP і покращує продуктивність. Але це також погано: збільшує ймовірність, що ви перевищите MTU на якійсь поламаній ділянці шляху і отримаєте мовчазні відкидання.
Отже шаблон «MTU ламає DNS» часто виглядає так:
- Клієнт надсилає DNS-запит з EDNS(0), рекламує 4096 байт.
- Резолвер повертає UDP-відповідь 1600–3000 байт.
- Деякий проміжний вузол не може її перенести (наприклад VPN тунель, PPPoE лінк, оверлейна мережа, неправильно встановлений MTU на vNIC).
- Виникає фрагментація або має відбутися PMTUD, але фрагменти/ICMP блокуються.
- Клієнт тайм-аутиться, повторює спробу або переходить на TCP — якщо це дозволено.
Чому це часто «тільки деякі домени»
MTU проблеми не стільки ламають DNS, скільки ламають великі DNS-відповіді. Ось чому ви можете резолвити example.com весь день, тоді як some-dnssec-heavy-domain.tld нестабільно. Будь-який домен з DNSSEC, великими TXT-записами, багатьма записами в RRset або ланцюжками CNAME — кандидат на проблему.
Найстрашніше в тому, що ви можете «виправити» це випадково, перемкнувши резолвер, кешування або просто дочекавшись. Жодне з цього не виправляє шлях. Воно просто переміщує симптом, поки це не вдарить важливіше ім’я опівночі.
Факти й історія, що важливі в продакшені
- Факт 1: Початкове обмеження UDP-відповіді в DNS було 512 байт; EDNS(0) дозволив клієнтам рекламувати більший буфер.
- Факт 2: Впровадження DNSSEC зробило великі відповіді звичними, бо підписи та ключі додають обсяг — особливо для негативних відповідей (NSEC/NSEC3).
- Факт 3: Широко використовуваний «безпечний» EDNS UDP-розмір сьогодні — близько 1232 байт, щоб уникнути проблем з фрагментацією в IPv6 на типовому шляху.
- Факт 4: PPPoE зменшує Ethernet MTU з 1500 до 1492, а тунелі можуть опустити його ще нижче. Ви швидко втрачаєте додаткові ~60–80 байт.
- Факт 5: IPv4 маршрутизатори можуть фрагментувати пакети, а IPv6 маршрутизатори не фрагментують у транзиті; фрагментація робиться тільки кінцевими вузлами, що робить PMTUD та доставку ICMPv6 значно важливішими.
- Факт 6: Багато middlebox-ів трактують IP-фрагменти як підозрілі і відкидають їх — іноді навмисно, іноді як побічний ефект «загартування безпеки».
- Факт 7: Деякі NAT-пристрої і фаєрволи погано відстежують UDP-потоки для фрагментів, бо пізніші фрагменти не містять інформації про UDP-порти.
- Факт 8: Падіння DNS до TCP — частина дизайну протоколу, але в корпоративних мережах TCP/53 часто блокується «бо DNS — це UDP». Так невелика проблема MTU перетворюється на відмову.
- Факт 9: Хмарні оверлейні мережі та інкапсуляція (VXLAN, Geneve, IPsec, GRE) рутинно зменшують ефективний MTU. Коли накопичуєте тунелі, ви накопичуєте накладні витрати, а не радість.
Цитата, яку варто запам’ятати в опс-культурі, бо вона боляче підходить для MTU-загадок:
“paraphrased idea” — Richard Feynman: reality must take precedence over public relations; nature can’t be fooled.
Швидкий план діагностики (робіть це спочатку)
Якщо DNS нестабільний і ви підозрюєте MTU, не починайте з перевстановлення systemd-resolved або суперечок про те, який публічний резолвер кращий. Зробіть таке:
1) Підтвердіть, що це «DNS з великою відповіддю»
- Візьміть домен, що падає, і той, що працює.
- Протестуйте з EDNS увімкненим і вимкненим.
- Протестуйте UDP проти TCP явно.
2) Виміряйте PMTU у напрямку, що падає
- Від клієнта до IP резолвера (не «до інтернету»).
- Використовуйте ping з DF-бітом (IPv4) або ping для IPv6 з вказаним розміром.
- Очікуйте знайти число менше за 1500 на VPN, PPPoE, оверлеях та деяких хмарних шляхах.
3) Шукайтe ICMP-«чорні діри» та скидання фрагментів
- Захоплення пакетів на клієнті або близько до резолвера.
- Перевірте правила фаєрволу на предмет ICMP «Fragmentation Needed» / «Packet Too Big».
- Перевірте, чи працює TCP/53; якщо так — ви дивитесь на проблему UDP-фрагментації.
4) Застосуйте мінімально ризиковану міру першою
- Зменшіть EDNS UDP-розмір на клієнтах/резолверах (наприклад до 1232).
- Дозвольте TCP/53 там, де це доречно.
- Виправте MTU тунелю/інтерфейсу та MSS clamping коректно (не вгадуйте; вимірюйте).
Доведіть це командами: 12+ реальних завдань і рішень
Нижче завдання написані, ніби ви на виклику: ви виконуєте команду, інтерпретуєте вихід, а потім приймаєте рішення. Запускайте їх з клієнта, який відчуває проблеми, і, якщо можливо, з хоста поруч із резолвером також.
Завдання 1: Відтворіть збій за допомогою dig і зафіксуйте час
cr0x@server:~$ dig @10.20.30.40 large-dnssec-domain.example A +tries=1 +time=2
; <<>> DiG 9.18.24 <<>> @10.20.30.40 large-dnssec-domain.example A +tries=1 +time=2
; (1 server found)
;; global options: +cmd
;; connection timed out; no servers could be reached
Що це означає: Маються проблеми доступності клієнт→резолвер на рівні DNS. Це ще не достатньо, щоб назвати MTU винуватцем.
Рішення: Порівняйте з «малим» доменом і змусьте TCP, щоб побачити, чи проблема в UDP.
Завдання 2: Порівняйте з відомою малою відповіддю
cr0x@server:~$ dig @10.20.30.40 example.com A +tries=1 +time=2
; <<>> DiG 9.18.24 <<>> @10.20.30.40 example.com A +tries=1 +time=2
;; ANSWER SECTION:
example.com. 3600 IN A 93.184.216.34
;; Query time: 18 msec
Що це означає: Базовий DNS до резолвера працює. Отже, ймовірно, проблема залежить від даних: розмір відповіді, фрагментація, DNSSEC або фільтрація пакетів.
Рішення: Примусьте TCP для імені, що падає. Якщо TCP вдасться, підозрюйте UDP-фрагментацію/PMTUD.
Завдання 3: Примусьте DNS по TCP (обминає проблеми UDP-фрагментації)
cr0x@server:~$ dig @10.20.30.40 large-dnssec-domain.example A +tcp +tries=1 +time=2
; <<>> DiG 9.18.24 <<>> @10.20.30.40 large-dnssec-domain.example A +tcp +tries=1 +time=2
;; ANSWER SECTION:
large-dnssec-domain.example. 300 IN A 203.0.113.77
;; Query time: 42 msec
Що це означає: TCP/53 працює і повертає відповідь. Шлях UDP — ймовірний підозрюваний, а не дані резолвера.
Рішення: Підтвердьте, що відповідь велика і викликає EDNS/фрагментацію.
Завдання 4: Подивіться на EDNS і узгодження UDP-розміру
cr0x@server:~$ dig @10.20.30.40 large-dnssec-domain.example A +dnssec +bufsize=4096
; <<>> DiG 9.18.24 <<>> @10.20.30.40 large-dnssec-domain.example A +dnssec +bufsize=4096
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 4096
;; connection timed out; no servers could be reached
Що це означає: Реклама великого UDP-буфера спричиняє збій. Це узгоджується з проблемою MTU/фрагментації.
Рішення: Спробуйте менший буфер (1232) і подивіться, чи стане надійно.
Завдання 5: Зменшіть EDNS-буфер, щоб уникнути фрагментації
cr0x@server:~$ dig @10.20.30.40 large-dnssec-domain.example A +dnssec +bufsize=1232 +tries=1 +time=2
; <<>> DiG 9.18.24 <<>> @10.20.30.40 large-dnssec-domain.example A +dnssec +bufsize=1232 +tries=1 +time=2
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 1232
;; ANSWER SECTION:
large-dnssec-domain.example. 300 IN A 203.0.113.77
;; Query time: 29 msec
Що це означає: Менший UDP-буфер вдається. Ваш шлях, ймовірно, не може надійно переносити більші UDP-відповіді.
Рішення: Тепер потрібно довести обмеження MTU/шляху, а не тільки «EDNS дивний». Наступний крок — виміряти PMTU.
Завдання 6: Виміряйте IPv4 PMTU за допомогою ping з DF
cr0x@server:~$ ping -M do -s 1472 -c 3 10.20.30.40
PING 10.20.30.40 (10.20.30.40) 1472(1500) bytes of data.
ping: local error: message too long, mtu=1472
--- 10.20.30.40 ping statistics ---
3 packets transmitted, 0 received, +3 errors, 100% packet loss
Що це означає: MTU інтерфейсу (або ранній хоп) нижчий, ніж очікувалося, або ви на лінку зі зменшеним MTU. Локальна помилка вказує, що локальний стек не може відправити такий розмір по цьому інтерфейсу.
Рішення: Знайдіть фактичний MTU інтерфейсу, а потім бінарно пошукайте PMTU з меншими розмірами. Також перевірте, чи резолвер доступний через тунельний інтерфейс.
Завдання 7: Знайдіть MTU інтерфейсу і вихідний інтерфейс
cr0x@server:~$ ip route get 10.20.30.40
10.20.30.40 via 10.8.0.1 dev tun0 src 10.8.0.10 uid 1000
cache
cr0x@server:~$ ip link show dev tun0
6: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1400 qdisc fq_codel state UNKNOWN mode DEFAULT group default qlen 500
link/none
Що це означає: DNS до резолвера йде через tun0 з MTU 1400. Це вже менше за Ethernet 1500; додайте заголовки й великі UDP-пакети легко можуть заштовхатися.
Рішення: Протестуйте PMTU до резолвера з розмірами менше 1400 і з’ясуйте, де відбувається збій.
Завдання 8: Підтвердіть найбільший незфрагментований корисний розмір до резолвера (бінарний пошук)
cr0x@server:~$ ping -M do -s 1372 -c 2 10.20.30.40
PING 10.20.30.40 (10.20.30.40) 1372(1400) bytes of data.
1380 bytes from 10.20.30.40: icmp_seq=1 ttl=63 time=31.2 ms
1380 bytes from 10.20.30.40: icmp_seq=2 ttl=63 time=30.7 ms
--- 10.20.30.40 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss
cr0x@server:~$ ping -M do -s 1392 -c 2 10.20.30.40
PING 10.20.30.40 (10.20.30.40) 1392(1420) bytes of data.
From 10.8.0.1 icmp_seq=1 Frag needed and DF set (mtu = 1400)
From 10.8.0.1 icmp_seq=2 Frag needed and DF set (mtu = 1400)
--- 10.20.30.40 ping statistics ---
2 packets transmitted, 0 received, +2 errors, 100% packet loss
Що це означає: Ваш PMTU на цьому шляху — 1400, і ICMP «Frag needed» дійсно доходить (добре). Якби ICMP блокувався, ви могли б бачити лише тайм-аути.
Рішення: Оскільки PMTU — 1400, запитайте: чому EDNS 4096 провалився? Тому що шлях з MTU 1400 фрагментуватиме UDP-відповіді більші за це. Якщо фрагменти відкидаються, отримуєте тайм-аути. Далі: підтвердіть втрату фрагментів за допомогою tcpdump.
Завдання 9: Захопіть DNS-пакети й подивіться на фрагментацію
cr0x@server:~$ sudo tcpdump -ni tun0 -vvv 'host 10.20.30.40 and (udp port 53 or tcp port 53)' -c 20
tcpdump: listening on tun0, link-type RAW (Raw IP), snapshot length 262144 bytes
IP 10.8.0.10.50821 > 10.20.30.40.53: 12345+ [1au] A? large-dnssec-domain.example. (56)
IP 10.20.30.40.53 > 10.8.0.10.50821: 12345* 1/0/1 A 203.0.113.77 (1492)
IP 10.8.0.10.42233 > 10.20.30.40.53: 54321+ [1au] A? large-dnssec-domain.example. (56)
IP 10.8.0.10.42233 > 10.20.30.40.53: Flags [S], seq 101, win 64240, options [mss 1360,sackOK,TS val 1 ecr 0,nop,wscale 7], length 0
IP 10.20.30.40.53 > 10.8.0.10.42233: Flags [S.], seq 202, ack 102, win 65160, options [mss 1360,sackOK,TS val 2 ecr 1,nop,wscale 7], length 0
Що це означає: Ви бачите велику UDP-відповідь (1492 байти «на дроті»), що перевищує MTU 1400 на тунелі; залежно від точки захоплення, ви можете або не можете бачити фрагментацію явно. Присутність TCP SYN після цього натякає, що клієнт повторює спробу і переходить на TCP.
Рішення: Якщо ви не бачите повної UDP-відповіді на клієнті (або бачите її вихід з сервера, але не надходження на клієнт), у вас — втрата фрагментів. Міграція: знизьте EDNS-розмір і/або виправте MTU тунелю й дозволи ICMP.
Завдання 10: Перевірте, чи TCP/53 дозволений наскрізь
cr0x@server:~$ nc -vz 10.20.30.40 53
Connection to 10.20.30.40 53 port [tcp/domain] succeeded!
Що це означає: TCP/53 відкрито на цьому шляху. Це страховка; у багатьох мереж її немає.
Рішення: Якщо TCP працює, ви можете швидко пом’якшити проблему, переконавшись, що клієнти/резолвери коректно падають на TCP, і зменшивши UDP-розміри. Якщо TCP заблоковано, виправте це негайно — потім продовжуйте розбиратися з MTU.
Завдання 11: Перевірте налаштування резолвера щодо EDNS-розміру (приклад BIND)
cr0x@server:~$ sudo named-checkconf -p | grep -E 'edns-udp-size|max-udp-size' || true
max-udp-size 4096;
Що це означає: Резолвер готовий надсилати дуже великі UDP-відповіді. Це оптимістично для корпоративних мереж з тунелями й фаєрволами.
Рішення: Зменшіть до безпечнішого значення (зазвичай 1232), якщо ви не контролюєте всі проміжні вузли і не можете довести, що більші працюють стабільно.
Завдання 12: Застосуйте безпечніший максимальний UDP-розмір на резолвері (BIND) і перевірте конфіг
cr0x@server:~$ sudo sed -i 's/max-udp-size 4096;/max-udp-size 1232;/' /etc/bind/named.conf.options
cr0x@server:~$ sudo named-checkconf
cr0x@server:~$ sudo systemctl reload bind9
cr0x@server:~$ sudo systemctl status bind9 --no-pager -l
● bind9.service - BIND Domain Name Server
Loaded: loaded (/lib/systemd/system/bind9.service; enabled)
Active: active (running)
Що це означає: Резолвер тепер обмежений меншими UDP-відповідями, зменшуючи ризик фрагментації.
Рішення: Перепроґрайте падіння доменів за допомогою dig без примусового +bufsize. Якщо проблема зникла, ви довели чутливість шляху до MTU/фрагментації. Але все одно виправте мережу остаточно.
Завдання 13: Перевірте, чи хостовий фаєрвол не відкидає ICMP «frag needed» (Linux)
cr0x@server:~$ sudo iptables -S | grep -E 'icmp|fragmentation|RELATED' || true
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
Що це означає: ICMP дозволено на хості. Якщо раніше ви бачили лише тайм-аути, блокування може бути на мережевому фаєрволі, а не на хості.
Рішення: Якщо ICMP блокується десь на шляху, виправте політику, щоб дозволити необхідні типи ICMP (не «усі ICMP назавжди», але достатньо для PMTUD).
Завдання 14: Перевірте MSS clamping на VPN-шлюзі (поширене пом’якшення для TCP, не для UDP)
cr0x@server:~$ sudo iptables -t mangle -S | grep -i clamp || true
-A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
Що це означає: MSS clamping увімкнено, що допомагає TCP уникнути проблем з MTU. Для UDP DNS це нічого не робить.
Рішення: Не зупиняйтеся на цьому. Люди бачать «clamp-mss-to-pmtu» і оголошують перемогу, потім дивуються, чому DNS по UDP все ще падає. Потрібно налаштувати EDNS і/або MTU правильно.
Завдання 15: Швидка перевірка Kubernetes: чи бачить CoreDNS усікання або повтори?
cr0x@server:~$ kubectl -n kube-system logs deploy/coredns --tail=50 | grep -E 'timeout|truncated|SERVFAIL' || true
[ERROR] plugin/errors: 2 large-dnssec-domain.example. A: read udp 10.244.2.15:46122->10.20.30.40:53: i/o timeout
Що це означає: CoreDNS тайм-аутиться на UDP-зчитуваннях до upstream резолвера. Якщо TCP з того самого пода/мережі працює, підозрюйте MTU/фрагментацію між кластером і резолвером (часто невідповідність MTU оверлея).
Рішення: Перевірте MTU мережі подів і вузлів, встановіть безпечний EDNS-розмір для CoreDNS/вихідного резолвера. Потім виправте MTU оверлея/тунелю коректно.
Три короткі корпоративні історії (як це відбувається на практиці)
1) Інцидент, спричинений неправильним припущенням
Розгорнули новий site-to-site VPN між двома офісами. Було багато звичних обіцянок: «прозоре підключення», «без змін у застосунках», «це просто маршрутизація». Мережна команда встановила MTU тунелю за замовчуванням, який використовували роками, і пішла далі. Ніхто нічого не вимірював, бо навіщо вимірювати те, що «стандартне»?
В понеділок вранці кількість інцидентів різко зросла. Користувачі могли дістатися внутрішніх додатків по IP, але імена були нестабільні. Деякі веб-сторінки завантажувалися, деякі крутилися вічно, а портал логіну падав так, ніби проблема з аутентифікацією. Графіки резолвера виглядали чистими. CPU в нормі. QPS нормальний. On-call почав переслідувати «продуктивність DNS-сервера».
Потрібна була одна людина, щоб запустити dig +tcp. Раптом проблемні домени розв’язувалися миттєво, і «автентифікаційний інцидент» став схожим на «розмір відповіді DNSSEC». Пакетні захоплення показали UDP-відповіді, що виходять із резолвера і ніколи не доходять до клієнта цілими. У тунелі ефективний MTU був меншим, ніж вважалося, а фаєрвол посеред відкидав фрагменти.
Неправильне припущення стосувалося не MTU-математики; воно стосувалося відповідальності. Усі вважали «VPN це вирішує» і «DNS же маленький». Виправлення було ганебно простим: виправити MTU тунелю, дозволити необхідний ICMP і обмежити EDNS UDP-розмір на резолвері як ремінь і підтяжки. Пункт постмортему: будь-який новий тунель має мати тест виміру PMTU у чеклісті розгортання.
2) Оптимізація, що повернулася бумерангом
Інша організація мала ініціативу з оптимізації: зменшити затримки, уникаючи TCP для DNS. Хтось помітив, що TCP-запити складають значну частку трафіку резолвера в пікові години. Тож вони «оптимізували», піднявши EDNS-буфери по всьому парку і підкрутивши фаєрволи, щоб «переважати UDP». Зміни виглядали добре в вузькому бенчмарку: менше TCP-хендшейків, трохи менший середній час запиту.
Через два тижні частина віддалених співробітників почала повідомляти, що «деякі сайти не існують» і «VPN нестабільний». Це було періодично й дратівливо. Команда резолвера бачила більше повторів і тайм-аутів, але не могла відтворити з дата-центру. VPN команда звинувачувала Wi‑Fi. Десктоп-команда звинувачувала ОС. У кожного була правдоподібна історія; ніхто не був правий.
Корінь проблеми — оптимізація: збільшення UDP-відповідей підвищило частоту фрагментації на VPN-лінках з меншим ефективним MTU. На шляху був пристрій безпеки, що відкидав нефайлові фрагменти як частину «базового загартування». Стара конфігурація змушувала більше усікати і переходити на TCP, що хоч і повільніше, але було надійніше. Вони оптимізували запас надійності.
Откат зменшив EDNS UDP-розмір до консервативного значення, і вони явно дозволили TCP/53. Потім виправили конфігурацію пристрою безпеки, щоб не відкидати фрагменти бездумно, і дозволили ICMP необхідних типів для PMTUD. Урок: не «ніколи не оптимізувати», а «оптимізуйте лише те, що можете спостерігати енд‑ту‑енд», особливо коли протокол — UDP, а мережа повна middlebox-ів зі своїми думками.
3) Скучна, але правильна практика, що врятувала день
Одна команда мала правило, яке звучало нудно: будь-яка зміна резолвера вимагала канарковий тест мінімум з трьох мережевих точок — дата-центр, VPN і хмарний VPC. Набір тестів не був химерним. Це було кілька dig запитів, кілька відомих великих DNSSEC імен і змушений випадок з +bufsize, щоб симулювати найгіршу поведінку.
Під час рутинного оновлення їх канарка з VPN почала падати тільки для «великих відповідей». Усе інше пройшло. Різниця була в тому, що пул VPN-концентраторів оновили того ж тижня, і одна нова модель пристрою мала менший ефективний MTU через додатковий шар інкапсуляції.
Оскільки вони тестували з краю, вони виявили це до того, як користувачі помітили. Вони знизили EDNS UDP-розмір на резолвері як миттєву міру, потім виправили MTU VPN і переконались, що ICMP «Packet Too Big» дозволено. Ніяких інцидентних дзвінків, ніяких ескалацій, ніяких квитків. Просто нудні тести, що запобігли драмі.
Жарт №2: Скучна робота з надійності — як чистити зуби: ніхто не хвалиться, але всі помічають, коли цього не роблять.
Рішення, які дійсно працюють (і чого уникати)
Категорія A: Зробіть DNS менш схильним до фрагментації
Встановіть консервативний EDNS UDP-розмір
Якщо робити лише одну міру, зробіть цю. Багато резолверів і клієнтів дозволяють налаштовувати рекламований/прийнятий розмір UDP-корисного навантаження. Операційна ціль — часто 1232 байти, підібрані для сумісності з IPv6 і типовими накладними витратами тунелів.
На стороні резолвера (приклади):
- BIND:
max-udp-size 1232; - Unbound: налаштуйте
edns-buffer-size/msg-buffer-sizeвідповідно - PowerDNS Recursor: налаштуйте обмеження EDNS UDP
Точна опція різниться, але операційний сенс однаковий: припинити відправляти «героїчні» UDP‑відповіді, що покладаються на фрагментацію через невідомі мережі.
Дозвольте TCP/53 і переконайтеся, що fallback працює
Переход на TCP — не «приємна опція». Це аварійний вихід протоколу, коли UDP не працює або у випадку усікання. Блокування TCP/53 — класичний корпоративний самособій.
Не «надавайте перевагу UDP», блокуючи TCP. Це не перевага — це саботаж. Дозвольте TCP/53 принаймні між клієнтами і рекурсивними резолверами, а також між резолверами і upstream, якщо ви їх оперуєте.
Категорія B: Виправіть шлях (реальна коренева причина)
Виправте MTU на тунелях та оверлеях
Якщо DNS йде через тунель, MTU тунелю має враховувати накладні витрати інкапсуляції. IPsec, WireGuard, OpenVPN, GRE, VXLAN — обирайте, що у вас. Накладні витрати різні і можуть сумуватися. Правильний підхід:
- Виміряйте PMTU між кінцевими точками.
- Встановіть MTU інтерфейсів відповідно.
- Перевірте DF ping-ами і реальними DNS-тестами.
Припиніть відкидати критичний ICMP
PMTUD потребує ICMP-повідомлень. Не потрібно дозволяти всі типи ICMP з усіх джерел, але потрібно дозволити ті, що забезпечують функціонування мережі. Для IPv4 — «Fragmentation Needed». Для IPv6 — «Packet Too Big» — обов’язково.
Якщо ваша політика безпеки каже «нічого ICMP», перепишіть її. Якщо не можете, принаймні чесно визнайте, що ви міняєте операційну коректність на відчуття безпеки.
Обробляйте фрагменти свідомо
Деякі середовища навмисно відкидають фрагменти як частину політики безпеки. Якщо ви так робите, треба компенсувати: обмежити EDNS-розмір, забезпечити TCP fallback і перевіряти застосунки, що залежать від UDP, чи не перевищують MTU. DNS — яскравий приклад, але не єдиний.
Категорія C: Виправте поведінку клієнтів (корисно, але не ховайте баг шляху)
Клієнтські стеки відрізняються. Деякі stub-резолвери рекламують великі EDNS-буфери та агресивно повторюють UDP. Деякі швидко падають на TCP. Деякі… креативні.
В керованих парках можна встановити безпечні значення:
- Використовуйте локальний кешуючий резолвер (systemd-resolved, Unbound, dnsmasq) з консервативним EDNS-розміром.
- Переконайтеся, що VPN-клієнти встановлюють адекватний MTU і не покладаються тільки на PMTUD, особливо якщо ICMP фільтрується.
- Використовуйте DoT/DoH лише якщо розумієте MTU/PMTUD наслідки (вони TCP‑базовані, що може допомогти, але додає свої складнощі).
Чого уникати (бо це «виправляє» не те)
- Уникайте гасіння симптомів перемиканням резолверів як основного рішення. Це може змінити розміри відповідей і кешування, маскуючи проблему.
- Уникайте підняття EDNS UDP-розміру як хаку продуктивності, якщо ви не контролюєте і не перевірили весь шлях.
- Уникайте «просто блокувати фрагменти» без компенсуючої DNS-стратегії (обмежити EDNS + TCP fallback).
- Уникайте вгадування MTU. Виміряйте PMTU. Потім встановіть MTU.
Типові помилки: симптом → корінь проблеми → виправлення
1) «Лише деякі домени не резолвляться»
Симптом: Кілька доменів тайм-аутять; більшість працює. DNS-сервер здається здоровим.
Корінь проблеми: Великі UDP-відповіді (DNSSEC/TXT/багато записів) фрагментуються; фрагменти відкидаються або ICMP блокується.
Виправлення: Зменшити EDNS UDP-розмір (почніть з 1232), дозволити TCP/53, виправити MTU/ICMP на тунелях та фаєрволах.
2) «DNS працює через мій хостспот, але падає через корпоративний VPN»
Симптом: Той самий клієнт, той самий резолвер, різні мережеві шляхи змінюють поведінку.
Корінь проблеми: VPN зменшує ефективний MTU і/або блокує ICMP; фрагментація не проходить.
Виправлення: Встановити правильний MTU для VPN, дозволити ICMP «frag needed/packet too big», обмежити EDNS-розмір.
3) «TCP DNS працює, UDP DNS тайм-аути»
Симптом: dig +tcp надійно працює; звичайний dig іноді падає.
Корінь проблеми: UDP-фрагментація або PMTUD чорна діра.
Виправлення: Діагностуйте PMTU; дозволіть фрагменти або зменшіть UDP-розмір; переконайтеся, що TCP/53 не блокується.
4) «Ми встановили MSS clamping, але DNS все одно падає»
Симптом: Хтось вказує на --clamp-mss-to-pmtu і чекає дива.
Корінь проблеми: MSS clamping впливає лише на TCP. DNS в основному використовує UDP.
Виправлення: Обмежте EDNS UDP-розмір і виправте MTU/ICMP; не плутайте TCP-пом’якшення з поведінкою UDP.
5) «Ми заблокували ICMP і тепер рандомні речі зависають»
Симптом: Великі передачі зависають; DNS час від часу тайм-аутить; IPv6 поводиться гірше.
Корінь проблеми: PMTUD не працює; формуються чорні діри; кінцеві вузли продовжують відправляти надто великі пакети.
Виправлення: Дозвольте необхідні типи ICMP; перевірте DF ping і захоплення пакетів.
6) «DNS у кластері Kubernetes нестабільний після увімкнення шифрування оверлею»
Симптом: Поди отримують періодичні тайм-аути DNS; вузли можуть бути в порядку.
Корінь проблеми: MTU оверлея зменшено інкапсуляцією; поди все ще вважають MTU 1500; втрата або відкидання фрагментів на вузлах.
Виправлення: Встановіть правильний CNI MTU, перевірте узгодження MTU вузол/под, обмежте EDNS-розмір у CoreDNS/upstream резолвері.
Чеклісти / поетапний план
Крок за кроком: від симптома до кореня (перевірено в полі)
- Візьміть два імені: одне, що падає, і одне, що працює. Для проблемного краще DNSSEC‑важке ім’я.
- Виконайте три запити: звичайний UDP, примусово TCP, UDP з
+bufsize=1232. - Якщо TCP вдається і малий bufsize вдається: вважайте, що це MTU/фрагментація, поки не доведено інше.
- Визначте маршрут:
ip route get <resolver_ip>і зафіксуйте вихідний інтерфейс. - Перевірте MTU інтерфейсу:
ip link show dev <if>. - Виміряйте PMTU до резолвера: DF ping-ами (IPv4) або пінгами з розміром (IPv6). Зафіксуйте найбільший робочий розмір.
- Захопіть пакети: на вихідному інтерфейсі під час відтворення. Дивіться на повтори, усікання, відсутні відповіді.
- Перевірте політику фаєрволу: впевніться, що важливі ICMP проходять; перевірте політику обробки фрагментів.
- Швидке пом’якшення: встановіть резолвер
max-udp-size(або еквівалент) на 1232; забезпечте TCP/53. - Виправлення назавжди: виправте MTU тунелів/оверлеїв; не складуйте тунелі без перерахунку накладних витрат.
- Регресійне тестування: канарка з VPN + дата-центр + хмара з великими DNSSEC-запитами.
- Документування: запишіть PMTU для основних шляхів і додайте тести в процес change management.
Операційний чекліст: «ми збираємося міняти MTU/тунелі/фаєрволи»
- Виміряйте PMTU до і після зміни з принаймні двох точок.
- Тестуйте DNS UDP з EDNS на 1232 і з більшим значенням (щоб рано виявити проблеми з фрагментацією).
- Переконайтеся, що TCP/53 дозволений для клієнтів до рекурсивних резолверів.
- Переконайтеся, що типи ICMP, необхідні для PMTUD, дозволені (особливо ICMPv6 Packet Too Big).
- Свідомо визначте політику щодо фрагментів; не наслідуйте дефолти бездумно.
- Оновіть максимальний EDNS UDP-розмір резолвера, якщо середовище містить тунелі/оверлеї, які ви не повністю контролюєте.
FAQ
1) Чому DNS взагалі використовує UDP, якщо він такий крихкий?
Через затримку та простоту. UDP уникає встановлення з’єднання і добре масштабується для малих запитів. У протоколі є TCP-fallback для більших відповідей і повтори при втраті. Крихкість виникає через middlebox-и і поламані PMTUD, а не через сам DNS.
2) Якщо я дозволю TCP/53, чи все одно потрібно виправляти MTU?
Так. TCP-fallback — страховка, а не лікування. Якщо у вас в шляху PMTU чорна діра, інші UDP‑протоколи (і навіть інколи TCP) також постраждають. Виправте мережу, щоб вона поводилася передбачувано.
3) Який EDNS UDP-розмір обрати?
Якщо ви працюєте через VPN/оверлеї/корпоративні фаєрволи, почніть з 1232 байт. Якщо ви контролюєте кожен хоп і можете довести, що більше працює — можна піднімати. Але не піднімайте його тільки тому, що бенчмарк так показав.
4) Як відрізнити фрагментацію від «поганого DNS-сервера»?
Класичний доказ: dig +tcp працює, коли UDP тайм-аутить, і dig +bufsize=1232 працює, а +bufsize=4096 — ні. Захоплення пакетів покаже відсутність UDP-відповідей або повтори.
5) Чому IPv6 часто гірший у цьому?
IPv6 маршрутизатори не фрагментують у транзиті. Кінцеві вузли мають це робити, а PMTUD покладається на ICMPv6 «Packet Too Big», щоб надіслати відправникові інформацію. Якщо мережа блокує ці повідомлення, ви навмисно будуєте IPv6‑чорну діру.
6) Чи може DNSSEC бути тригером, навіть якщо я «не використовую DNSSEC»?
Так. Рекурсивні резолвери можуть валідовувати DNSSEC і отримувати додаткові записи, а клієнти можуть запитувати DNSSEC (DO bit). Навіть без запитів клієнта, upstream‑поведінка може збільшити відповіді для певних імен.
7) Що з DoH або DoT?
Вони працюють поверх TCP (і зазвичай TLS), тому менш чутливі до UDP-фрагментації. Але вони вводять інші режими відмов (перехоплення проксі, TLS‑інспекція, обмеження з’єднань, затримка). Не використовуйте DoH/DoT як пластир для поламаного MTU, якщо ви не приймаєте такі компроміси.
8) Я бачу «truncated» відповіді (TC bit). Це MTU?
Не обов’язково. Усікання означає, що сервер навмисно скоротив UDP-відповідь і просить клієнта повторити по TCP. Це може бути наслідком обмежень розміру, політики або поведінки upstream. Проблеми MTU часто виглядають як тайм-аути, а не як чисте усікання, бо відповідь втрачається в польоті.
9) Чи може один фаєрвол-правило реально ламати лише великі DNS‑відповіді?
Абсолютно. Правило, що відкидає IP-фрагменти або блокує ICMP «frag needed», вибірково шкодить пакетам, які перевищують PMTU. Малі DNS-відповіді продовжують працювати, тому проблема довго залишається непоміченою в продакшені.
Наступні кроки, які ви можете зробити сьогодні
Помилки MTU не оголошують себе. Вони маскуються під нестабільний DNS, «рандомні» тайм-аути й суб’єктивні скарги користувачів, доки ви не зрозумієте, що розміри пакетів — об’єктивні.
- Доведіть це: запустіть
digзвичайно проти+tcpта+bufsize=1232для проблемного імені. - Виміряйте: знайдіть вихідний інтерфейс і PMTU до IP резолвера за допомогою DF ping-ів.
- Швидко пом’якшіть: обмежте EDNS UDP-розмір резолвера до 1232 і забезпечте дозвіл TCP/53.
- Виправте по-справжньому: скоректуйте MTU тунелів/оверлеїв і дозволіть необхідні ICMP для PMTUD; свідомо визначте політику щодо фрагментів.
- Тримайте це виправленим: додайте канарковий тест з VPN + дата-центр + хмара, що включає хоча б одну велику DNSSEC-відповідь.
Зробіть ці п’ять речей і ви перестанете вважати DNS містичним сервісом, а почнете розглядати його як те, чим він і є: пакети, розміри й шляхи. Мережа все одно знайде нові способи вас підвести, але принаймні ви будете знати, куди дивитися в першу чергу.