Debian/Ubuntu: випадкові таймаути — трасуйте шлях мережі mtr/tcpdump і усуньте причину (Випадок №64)

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

Випадкові таймаути — найгірший тип відмови: нічого явно «не впало», все на вигляд «майже нормально», але користувачі дивляться на обертові індикатори. Ваші дашборди виглядають задоволеними. Логи — байдужими. А CEO завжди може відтворити проблему в готельному Wi‑Fi.

Це польовий посібник для операторів Debian/Ubuntu, яким потрібно довести, де саме відбувається таймаут, прив’язати його до конкретного хопу або підсистеми й усунути реальну причину. Ми будемо використовувати mtr і tcpdump як інструменти: не як ритуал, а як прилади. По дорозі розберемо «втрати пакетів» і «ICMP, що занижають пріоритет», виявимо PMTU‑blackhole, помітимо обман DNS і ідентифікуємо особливий біль асиметричної маршрутизації.

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

Якщо ви на виклику, вам не потрібна філософська лекція. Потрібна послідовність, яка швидко знаходить вузьке місце та уникає хибних спрацьовувань.

По-перше: визначте, що саме таймаутить (DNS, TCP connect, TLS чи додаток)

  • Перевірте затримки та помилки DNS (це класичний «випадковий» підозрюваний, бо кешування робить проблему спорадичною).
  • Перевірте час встановлення TCP з’єднання (SYN/SYN-ACK handshake). Якщо connect повільний — фокусуйтеся на шляху/файрволах/conntrack.
  • Перевірте TLS‑handshake (якщо TLS зависає після connect — підозрюйте PMTU, middlebox або дивності MTU‑offload).
  • Перевірте час запиту/відповіді додатка (якщо connect і TLS в порядку — це, ймовірно, додаток або навантаження сервера).

По-друге: вирішіть, чи це «шлях», чи «кінцева точка»

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

По-третє: класифікуйте таймаут

  • Повторні передачі без ACK → втрата, фільтрація, асиметрична маршрутизація або скидання conntrack.
  • Зникнення великих пакетів → PMTU blackhole (DF встановлено, ICMP заблоковано).
  • Тільки UDP «випадково» падає → таймаути NAT, stateful firewall або особливості DNS/QUIC.
  • Тільки один маршрут/ASN → проблема апстриму/пірування; зберіть докази й ескалюйте.

Операційне правило: не довіряйте одній перспективі. Якщо ви вимірюєте лише з сервера — не помітите last‑mile проблем. Якщо лише з клієнта — можете звинуватити інтернет замість повного conntrack‑таблиці на своїй стороні.

Практична модель мислення: чим зазвичай є «випадкові таймаути»

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

У продакшені періодичні таймаути зазвичай потрапляють у одну з цих категорій:

  • Проблеми DNS: повільні резолвери, поламаний split‑horizon, проблеми EDNS0/UDP фрагментації або rate limiting резолверів.
  • Втрати пакетів на хопі: реальні втрати (завантаження, Wi‑Fi, погана оптика) проти «ICMP занижує пріоритет» (mtr показує втрати, але TCP працює нормально).
  • PMTU blackhole: Path MTU Discovery не працює через блокування ICMP «fragmentation needed»; малі пакети працюють, великі зависають.
  • Виснаження стану: переповнена conntrack‑таблиця, переповнена NAT‑таблиця, завантаження CPU файрвола, DDoS‑механізми скидають стани.
  • Асиметрична маршрутизація: SYN іде одним шляхом, SYN‑ACK повертається іншим і відкидається stateful файрволом або source validation.
  • Проблеми оффлоудів і драйверів: GRO/TSO/LRO взаємодії, проблеми контрольних сум або баги прошивки NIC — рідко, але трапляється.
  • Черги та bufferbloat: сплески латентності під навантаженням викликають «таймаути» навіть без втрат.

Нечарівна правда: mtr показує, куди дивитися; tcpdump показує, що сталося. Використовуйте обидва.

Цікаві факти та історичний контекст

  • Ідея traceroute з’явилася в 1987 році, використовуючи збільшувані TTL для отримання ICMP «time exceeded» від кожного хопу.
  • mtr (My Traceroute) існує з кінця 1990‑х, поєднуючи traceroute і ping у часі для виявлення періодичних проблем.
  • ICMP не «опціональний» на практиці: занадто багато блокувань його ламають PMTU Discovery і викликають класичні помилки «працює для маленьких payload’ів».
  • Path MTU Discovery (PMTUD) став важливим у ранніх 1990‑х з різноманіттям мереж; досі це одна з головних причин дивних зависань.
  • Повторні передачі TCP навмисно консервативні; експоненційне відновлення робить невелику втрату схожою на велику паузу для користувача.
  • Linux conntrack існує через stateful файрволи і NAT; коли він повний — мережа «не деградує», а просто відкидає нові потоки.
  • EDNS0 збільшив розміри DNS‑повідомлень; це добре, поки файрволи й NAT неправильно обробляють фрагментований UDP і DNS починає «випадково» таймаутити.
  • Сучасні CDN і multi‑homed сервіси роблять маршрути більш динамічними; ваш «той самий» пункт призначення може йти різними шляхами за хвилину.
  • ICMP rate limiting поширений на маршрутизаторах; це може змусити mtr показувати втрати на проміжному хопі навіть при ідеальній пересилці.

Інструменти, які вам реально потрібні на Debian/Ubuntu

Встановіть базові утиліти. Не будьте тим, хто дебагує мережу лише з curl і інтуїцією.

cr0x@server:~$ sudo apt-get update
Hit:1 http://archive.ubuntu.com/ubuntu jammy InRelease
Reading package lists... Done
cr0x@server:~$ sudo apt-get install -y mtr-tiny tcpdump iproute2 dnsutils iputils-ping traceroute ethtool conntrack netcat-openbsd
Reading package lists... Done
Building dependency tree... Done
The following NEW packages will be installed:
  conntrack dnsutils ethtool mtr-tiny netcat-openbsd tcpdump traceroute
0 upgraded, 7 newly installed, 0 to remove and 0 not upgraded.

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

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

Нижче практичні завдання для Debian/Ubuntu. Кожне містить: команду, на що дивитися і яке рішення має спричинити.

Завдання 1: Підтвердити, що таймаут реальний, і виміряти, де він відбувається (DNS vs connect vs TLS)

cr0x@server:~$ time curl -sS -o /dev/null -w "namelookup:%{time_namelookup} connect:%{time_connect} appconnect:%{time_appconnect} starttransfer:%{time_starttransfer} total:%{time_total}\n" https://api.example.net/health
namelookup:0.002 connect:0.012 appconnect:0.054 starttransfer:0.061 total:0.061

real	0m0.070s
user	0m0.010s
sys	0m0.004s

Інтерпретація: Якщо namelookup стрибає під час збоїв — ганяйте DNS. Якщо connect стрибає — ганяйте шлях/файрвол/conntrack. Якщо appconnect стрибає — ганяйте TLS/MTU/middlebox. Якщо тільки starttransfer стрибає — ймовірно латентність додатка чи сервера.

Рішення: Виберіть підсистему для наступного інструментування. Не запускайте mtr до hostname, якщо DNS відпадає; спочатку отримайте IP.

Завдання 2: Розв’язати hostname і зафіксувати IP

cr0x@server:~$ dig +time=1 +tries=1 api.example.net A
; <<>> DiG 9.18.24-1ubuntu1.4-Ubuntu <<>> +time=1 +tries=1 api.example.net A
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 1203
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; ANSWER SECTION:
api.example.net.	60	IN	A	203.0.113.42

;; Query time: 18 msec
;; SERVER: 127.0.0.53#53(127.0.0.53) (UDP)
;; WHEN: Mon Dec 30 12:01:02 UTC 2025
;; MSG SIZE  rcvd: 58

Інтерпретація: Зверніть увагу на резолвер (127.0.0.53 підказує systemd-resolved) і час запиту. Якщо час запиту — сотні мсек або періодично таймаутить — DNS винен, поки не доведено протилежне.

Рішення: Використовуйте IP (203.0.113.42) для тестів шляху й захоплень пакетів, щоб уникнути шуму DNS.

Завдання 3: Запустіть mtr у TCP‑режимі до порту сервісу (не ICMP)

cr0x@server:~$ mtr -rwz -c 200 -T -P 443 203.0.113.42
Start: 2025-12-30T12:02:10+0000
HOST: server                         Loss%   Snt   Last   Avg  Best  Wrst StDev
  1.|-- 10.10.0.1                     0.0%   200    0.4   0.6   0.3   2.1   0.2
  2.|-- 192.0.2.10                    0.0%   200    1.2   1.5   1.0   5.4   0.6
  3.|-- 198.51.100.9                  0.0%   200    2.8   3.0   2.2   9.7   0.8
  4.|-- 203.0.113.1                   0.0%   200    9.9  10.3   8.7  22.1   2.1
  5.|-- 203.0.113.42                  6.0%   200   18.2  14.1  11.0  85.3  10.7

Інтерпретація: mtr у TCP‑режимі ближчий до вашого реального трафіку. Втрати на останньому хопі при чистих проміжних хопах — значущі. Розкид і worst‑значення важливі: 85 ms worst не фатально, але 6% втрат — так.

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

Завдання 4: Запустіть mtr з ICMP, щоб визначити ICMP rate limiting vs реальні втрати пересилання

cr0x@server:~$ mtr -rwz -c 200 203.0.113.42
Start: 2025-12-30T12:03:44+0000
HOST: server                         Loss%   Snt   Last   Avg  Best  Wrst StDev
  1.|-- 10.10.0.1                     0.0%   200    0.5   0.6   0.3   1.6   0.2
  2.|-- 192.0.2.10                    0.0%   200    1.3   1.4   1.0   4.1   0.4
  3.|-- 198.51.100.9                 22.0%   200    3.0   3.2   2.4  11.8   1.1
  4.|-- 203.0.113.1                   0.0%   200   10.2  10.5   8.8  21.9   2.0
  5.|-- 203.0.113.42                  0.0%   200   12.9  13.6  11.2  40.5   4.4

Інтерпретація: Хоп 3 показує 22% втрат, але пізніші хопи — 0% втрат. Це класична ситуація: ICMP відповіді хопу 3 обробляються з низьким пріоритетом або rate limited, а не реальна втрата пересилання.

Рішення: Не ескалюйте постачальнику тільки через це. Віддавайте перевагу TCP mtr до реального порту й корелюйте з tcpdump.

Завдання 5: Перевірте помилки та дропи на локальному інтерфейсі (нудно, але часто вирішально)

cr0x@server:~$ ip -s link show dev eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
    link/ether 52:54:00:12:34:56 brd ff:ff:ff:ff:ff:ff
    RX:  bytes packets errors dropped  missed   mcast
     987654321  123456      0    421       0   10234
    TX:  bytes packets errors dropped carrier collsns
     876543210  120001      0     19       0       0

Інтерпретація: RX dropped 421 вказує на локальні дропи (переповнення черги, драйвер або навантаження CPU хоста). Не завжди фатально, але це не «інтернет».

Рішення: Якщо дропи зростають під час інцидентів — перевіряйте навантаження хоста, NIC‑ring buffer, qdisc і оффлоади. Якщо бачите errors/carrier — підозрюйте кабелювання або віртуальний NIC.

Завдання 6: Перевірте маршрутизацію та вибір source IP

cr0x@server:~$ ip route get 203.0.113.42
203.0.113.42 via 10.10.0.1 dev eth0 src 10.10.0.23 uid 1000
    cache

Інтерпретація: Підтверджує, який шлюз і source IP використовуються. Неправильний source IP — тихий вбивця при policy routing або кількох інтерфейсах.

Рішення: Якщо source IP неправильний — виправте правила маршрутизації, ip rule або бінд додатка. Якщо шлюз несподіваний — може бути асиметрична маршрутизація.

Завдання 7: Шукати виснаження conntrack (таймаути, що пахнуть «нові з’єднання падають»)

cr0x@server:~$ sudo sysctl net.netfilter.nf_conntrack_count net.netfilter.nf_conntrack_max
net.netfilter.nf_conntrack_count = 262132
net.netfilter.nf_conntrack_max = 262144

Інтерпретація: Ви фактично на 100%. Нові з’єднання можуть відкидатись або затримуватись, що дає випадкові connect‑таймаути, які «чарівним» чином зникають.

Рішення: Підвищте nf_conntrack_max обережно (вплив на пам’ять), зменшіть churn з’єднань, скоротіть таймаути там, де безпечно, або перемістіть NAT/state на інші пристрої.

Завдання 8: Захопіть трафік під час таймауту (SYN retransmits vs server silence)

cr0x@server:~$ sudo tcpdump -ni eth0 host 203.0.113.42 and tcp port 443 -vv
tcpdump: listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
12:06:01.120001 IP (tos 0x0, ttl 64, id 43121, offset 0, flags [DF], proto TCP (6), length 60)
    10.10.0.23.53124 > 203.0.113.42.443: Flags [S], seq 3021001001, win 64240, options [mss 1460,sackOK,TS val 1000 ecr 0,nop,wscale 7], length 0
12:06:02.121045 IP (tos 0x0, ttl 64, id 43122, offset 0, flags [DF], proto TCP (6), length 60)
    10.10.0.23.53124 > 203.0.113.42.443: Flags [S], seq 3021001001, win 64240, options [mss 1460,sackOK,TS val 2000 ecr 0,nop,wscale 7], length 0
12:06:04.123210 IP (tos 0x0, ttl 64, id 43123, offset 0, flags [DF], proto TCP (6), length 60)
    10.10.0.23.53124 > 203.0.113.42.443: Flags [S], seq 3021001001, win 64240, options [mss 1460,sackOK,TS val 4000 ecr 0,nop,wscale 7], length 0

Інтерпретація: SYN‑ретрансляції без повернення SYN‑ACK. Або SYN не доходить до сервера, або SYN‑ACK не доходить назад, або локально їх відкидає conntrack/файрвол.

Рішення: Захопіть пакети також на сервері, якщо можливо. Якщо сервер бачить SYN, але клієнт не бачить SYN‑ACK — підозрюйте шлях у зворотному напрямку/асиметрію або stateful‑пристрій, що відкидає відповідь.

Завдання 9: Захопіть на сервері, щоб довести, чи приходить SYN

cr0x@server:~$ sudo tcpdump -ni eth0 src 10.10.0.23 and tcp port 443 -vv
tcpdump: listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
12:06:01.129900 IP 10.10.0.23.53124 > 203.0.113.42.443: Flags [S], seq 3021001001, win 64240, options [mss 1460,sackOK,TS val 1000 ecr 0,nop,wscale 7], length 0
12:06:01.130010 IP 203.0.113.42.443 > 10.10.0.23.53124: Flags [S.], seq 901200200, ack 3021001002, win 65160, options [mss 1440,sackOK,TS val 7000 ecr 1000,nop,wscale 7], length 0

Інтерпретація: Сервер відправляє SYN‑ACK. Якщо клієнт не бачив його, шлях у зворотному напрямку відкидає пакети. Це не проблема додатка — це мережа.

Рішення: Ескалюйте до мережевої команди/провайдера з доказами або перевіряйте проміжні файрволи/NAT на асиметрію маршруту чи скидання стану.

Завдання 10: Виявлення PMTU blackhole за допомогою tracepath

cr0x@server:~$ tracepath -n 203.0.113.42
 1?: [LOCALHOST]                      pmtu 1500
 1:  10.10.0.1                          0.471ms
 2:  192.0.2.10                         1.312ms
 3:  198.51.100.9                       3.004ms
 4:  203.0.113.1                       10.142ms
 5:  203.0.113.42                      13.012ms reached
     Resume: pmtu 1500 hops 5 back 64

Інтерпретація: Якщо tracepath повідомляє нижчий PMTU (наприклад 1472/1460/1400) або зависає з «no reply», можливо PMTU‑проблема.

Рішення: Якщо підозрюєте PMTU blackhole — тестуйте DF‑ping і налаштовуйте MTU/MSS clamping.

Завдання 11: Підтвердити PMTU за допомогою ping з “do not fragment”

cr0x@server:~$ ping -c 3 -M do -s 1472 203.0.113.42
PING 203.0.113.42 (203.0.113.42) 1472(1500) bytes of data.
ping: local error: message too long, mtu=1500
ping: local error: message too long, mtu=1500
ping: local error: message too long, mtu=1500

--- 203.0.113.42 ping statistics ---
3 packets transmitted, 0 received, +3 errors, 100% packet loss, time 2046ms

Інтерпретація: Цей вивід вказує, що ваш локальний інтерфейсний MTU — 1500, і ви спробували payload, що його перевищує після заголовків. Це локальна проблема розміру, а не проблема маршруту.

Рішення: Повторіть з правильним розміром. Для MTU 1500 ICMP payload 1472 зазвичай коректний; якщо бачите «message too long», можливо ви на тунельному інтерфейсі або MTU відрізняється від очікуваного. Підтвердіть MTU за допомогою ip link.

Завдання 12: Перевірте локальний MTU і тунелі, які приховано його зменшують

cr0x@server:~$ ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
3: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000

Інтерпретація: WireGuard інтерфейс MTU 1420 — поширений. Якщо трафік йде через wg0 або інкапсулюється, ефективний MTU нижчий за 1500.

Рішення: Якщо ваш шлях використовує тунель — встановіть відповідний MTU і обмежте TCP MSS на краю.

Завдання 13: Знайдіть дропи в логах файрвола та лічильниках nftables

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
    iif "lo" accept
    tcp dport 22 accept
    counter packets 1024 bytes 65536 drop
  }
}

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

Рішення: Додайте явні accept‑правила для сервісу, або виправте state tracking/маршрутизацію, щоб відповіді відповідали established‑стану.

Завдання 14: Перевірте поведінку systemd-resolved і здоров’я апстрим‑DNS

cr0x@server:~$ resolvectl status
Global
       Protocols: -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
resolv.conf mode: stub
Current DNS Server: 192.0.2.53
       DNS Servers: 192.0.2.53 192.0.2.54

Link 2 (eth0)
    Current Scopes: DNS
         Protocols: +DefaultRoute -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
Current DNS Server: 192.0.2.53
       DNS Servers: 192.0.2.53 192.0.2.54

Інтерпретація: Ви знаєте, якими резолверами реально користуєтесь. «Ми використовуємо Google DNS» часто — міф із попереднього terraform‑модуля.

Рішення: Тестуйте кожен резолвер безпосередньо через dig @server. Якщо один нестабільний — видаліть його або виправте.

mtr правильно: читайте його як SRE

mtr — це time‑series traceroute. Це також генератор поганих інцидентів, якщо його неправильно інтерпретувати. Основна пастка: втрати, показані на проміжному хопі, не обов’язково означають втрати для вашого трафіку. Багато маршрутизаторів занижують пріоритет TTL‑expired ICMP‑відповідей; вони все одно коректно форвардять пакети.

Правила великого пальця, що вбережуть вас від помилок

  • Довіряйте втратам лише якщо вони доходять до фінального хопу. Втрата на хопі N, яка зникає на N+1 — зазвичай rate limiting ICMP‑відповідей.
  • Надавайте перевагу TCP‑mtr до порту сервісу. ICMP може оброблятись інакше, ніж ваш трафік, особливо через провайдерів і файрволи.
  • Дивіться на розподіл латентності (avg, worst, stdev), а не тільки «Loss%». Черги можуть псувати UX без високих втрат.
  • Запустіть достатньо зразків (-c 200 або більше) для виявлення періодичності. П’ять пакетів — це гороскоп.
  • Прив’яжіть тести до реального IP. CDN можуть направляти різних клієнтів на різні edge‑сервери; потрібна стабільна ціль.

Жарт №1: mtr — як конференц‑дзвінок: хтось завжди «відпадає», і це зазвичай та людина, що нічого корисного не робить.

Як виглядає «гарний» доказ із mtr

Гарні докази — порівняльні й послідовні:

  • mtr TCP на порт 443 показує 5–10% втрат на фінальному хопі під час інциденту.
  • tcpdump показує SYN‑ретрансляції і відсутність SYN‑ACK на стороні клієнта.
  • Захоплення на сервері показує, що SYN‑ACK покидає інтерфейс (або ні).
  • Тести з іншої точки показують іншу поведінку (питання маршрутизації) або ту саму (проблема кінцевої точки).

tcpdump правильно: спіймайте таймаут на дроті

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

Стратегія захоплення: не тонути у даних

  • Фільтруйте агресивно: host + port + protocol. Якщо захоплювати все — пропустите момент, що найбільше важить.
  • Захоплюйте обидва напрямки, коли можливо: на стороні клієнта й на сервері. Асиметрична маршрутизація ненавидить однобічні захоплення.
  • Корелюйте за відмітками часу: зберігайте час інциденту й використовуйте монотоничні годинники якщо можете. Якщо NTP винен — ви постраждаєте двічі.

На що дивитися при TCP‑таймаутах

  • SYN‑ретрансляції: проблема шляху підключення, фільтрація, зворотний шлях або conntrack.
  • SYN/SYN‑ACK/ACK пройшли, але TLS зависає: PMTU, middlebox‑втручання або перерозподіл пакетів через дивний MTU.
  • Дані відправлені, але немає ACK, повторні передачі: downstream‑втрати або stateful‑пристрій відкидає пакети.
  • RST: активне відхилення файрволом або сервіс не слухає порт.

Ще одна операційна істина: таймаути — це не помилки, це відсутність доказів. tcpdump дає ці докази.

Усунення причини: MTU, маршрутизація, DNS, conntrack та інші

Клас виправлень 1: DNS «випадкові» таймаути

DNS часто виглядає як мережа, бо все його використовує. Типові режими відмов:

  • Один резолвер повільний або періодично відкидає UDP.
  • EDNS0‑відповіді фрагментуються; фрагменти відкидають; клієнти переходять на TCP і затримуються.
  • Split‑horizon повертає не маршрутизовані IP залежно від того, який резолвер відповів.

Що робити:

  • Тестуйте кожен резолвер напряму використовуючи dig @192.0.2.53 і dig @192.0.2.54 з короткими таймаутами.
  • Якщо великі відповіді таймаутять — тестуйте з +tcp і подумайте про обмеження EDNS buffer size на резолверах або клієнтах.
  • На systemd‑resolved системах підтвердіть, які сервери активні; не припускайте.

Клас виправлень 2: PMTU blackholes

PMTU blackhole — класика: малі запити працюють, великі зависають, зазвичай під час TLS або великих заголовків/кукі. Причина часто — заблоковані ICMP «fragmentation needed». TCP відправляє з DF‑битом, ніколи не дізнається про менший MTU і ви отримуєте повтори аж до таймауту.

Що робити:

  • Дозволіть необхідні типи ICMP через файрволи (принаймні «fragmentation needed» і «time exceeded», де потрібно).
  • Clamp TCP MSS на краях тунелів (WireGuard, IPsec, GRE), щоб кінцеві вузли ніколи не відправляли занадто великі сегменти.
  • Встановіть правильний MTU на тунельних інтерфейсах і перевірте, що маршрути реально їх використовують.

Клас виправлень 3: виснаження conntrack/NAT

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

Що робити:

  • Підвищуйте nf_conntrack_max і тюньте таймаути, якщо робоче навантаження багатоз’єднаннєве.
  • Зменшуйте churn: ввімкніть keep‑alives, повторне використання з’єднань, налаштуйте пули.
  • Перенесіть NAT/state на пристрої розраховані для цього або усуньте NAT, де можливо.

Клас виправлень 4: асиметрична маршрутизація

Асиметрична маршрутизація сама по собі не погана; інтернет так працює постійно. Вона стає проблемою, коли stateful‑пристрої припускають симетрію (файрволи, NAT) або коли source validation відкидає пакети, що повертаються іншим інтерфейсом.

Що робити:

  • Перевіряйте маршрутизацію за допомогою ip route get і захоплень на обох кінцях.
  • Якщо маєте кілька uplink’ів — синхронізуйте policy routing і переконайтеся, що відповіді йдуть тим самим шляхом при проходженні stateful‑пристроїв.
  • Перевірте налаштування reverse path filtering (rp_filter) при multi‑homed хостах, коли відповіді приходять іншим інтерфейсом.

Клас виправлень 5: локальні дропи, NIC/драйвер або черги

Іноді проблема в мережі — це ваш хост, який ріже пакети під навантаженням. Дивіться дропи інтерфейсу, softirq‑тиск CPU і поведінку qdisc.

  • Якщо ip -s link показує дропи під час інцидентів — перевіряйте CPU і softirqs.
  • Перевірте оффлоади за допомогою ethtool -k, якщо підозрюєте дивності; відключайте вибірково для налагодження, а не назавжди через забобони.
  • Розгляньте fq_codel або cake на краю, якщо bufferbloat викликає стрибки латентності.

Жарт №2: Якщо ви «виправили» таймаути перезавантаженням файрвола — ви не вирішили проблему, ви натиснули snooze з повноваженнями.

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

Міні‑історія 1: Інцидент через хибне припущення

Компанія мала мульти‑регіональний API. Користувачі в одній географії скаржилися на випадкові помилки оформлення замовлення: деякі запити проходили, інші таймаутилися на 10–15 секунд. Команда додатку наполягала, що це беку — їхні дашборди показували підвищену латентність на шарі API. Вони почали масштабувати.

Перше хибне припущення було тонким: вони вважали, що «таймаути» означають «сервер повільний». Насправді curl -w показав, що саме time_connect стрибав, а не starttransfer. Ця одна метрика змінила розслідування з додатка на мережевий шлях.

mtr з мережі клієнта, що відтворювала збій, показав втрати лише на останньому хопі при використанні TCP на порт 443. ICMP mtr був чистим. Це важлива деталь: мережа могла форвардити ICMP і навіть частково TCP, але не стабільно на цей порт сервісу. Команда нарешті запустила tcpdump на сервері і побачила: SYN приходять, SYN‑ACK йдуть… і нічого. Клієнт ніколи не бачив SYN‑ACK.

Реальна причина — асиметрична маршрутизація, введена «тимчасовою» зміною апстриму. SYN входив через провайдера A, а повертався через провайдера B через tweak порядку маршрутів. Stateful‑файрвол апстриму чекав зворотнього шляху через A і відкидав SYN‑ACK як «invalid».

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

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

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

Потім почались періодичні збої: discovery іноді зависав, а потім відновлювався. Це не було постійно, тому політично дратувало. Логи додатка показували таймаути при викликах залежностей по hostname; виклики за IP працювали. Ротація on‑call набула забобону, що «DNS привидний».

Захоплення пакетів розповіло історію. DNS‑відповіді для певних записів були більші через DNSSEC і велику кількість A/AAAA. Локальний резолвер застосовував EDNS0 з великим UDP‑буфером. Десь по шляху — конкретно NAT‑пристрій зі старою політикою фрагментації — фрагментовані UDP‑відповіді відкидали. Клієнти переходили на TCP, але резолвер мав замалу TCP‑ємність і почав чергувати. Тепер ви мали «випадкові» DNS‑таймаути залежно від запису і розміру відповіді.

Оптимізація була доброю наміром, але змінила форму трафіку: менше запитів в апстрим, але більші й більш «вибухові» відповіді локально, і більше фрагментації. Виправлення включало зменшення оголошеного EDNS buffer size, забезпечення TCP‑fallback‑ємності і оновлення NAT‑політики для коректної роботи з фрагментами. Команда також додала моніторинг розподілу часу запитів DNS, а не тільки «рейт успіху».

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

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

Фінансова контора мала репутацію нудної практики зміни. Вони підтримували runbook, який вимагав захоплення доказів з обох кінців для будь‑яких періодичних мережевих збоїв. Це не було круто. Але саме це завершило інцидент до обіду.

Якось вранці декілька батч‑джобів почали падати з «connection timed out» до зовнішнього партнера. Внутрішні сервіси були в порядку. Мережа підозрювала партнера. Команда додатків підозрювала мережу. Усі готували улюблені звинувачення.

On‑call дотримався runbook: запустив TCP mtr до порту партнера, захопив tcpdump під час збою і записав точний 5‑tuple. Захоплення на клієнті показало SYN‑ретрансляції. Захоплення на edge‑файрволі показало, що SYN виходять, але SYN‑ACK не повертаються. Це не «можливо» — це напрямкова спостережливість.

Потім тест повторили з іншого egress IP і побачили чисті з’єднання. Отже проблема не в партнері «взагалі». Вона була специфічна для маршруту. Вони ескалували до апстрим‑провайдера з mtr і пакетними доказами, і провайдер підтвердив зламаний шлях до того префіксу з однієї точки пірингу.

Розв’язання було по суті паперовою роботою і перехресним маршрутом, але швидкість дала нудна дисципліна: завжди збирати принаймні одне пакетне захоплення на межі, яку ви контролюєте. Runbook не зробив їх розумнішими. Він зробив їх швидшими і менш піддаваними для суперечок.

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

  • mtr показує 30% втрат на хопі 4, але призначення в порядку → ICMP rate limiting на хопі 4 → Ігноруйте проміжні втрати, якщо вони не доходять до фінального хопу; підтверджуйте TCP mtr і tcpdump.
  • HTTPS підключається, але «зависає» під час TLS handshake → PMTU blackhole або занадто велике MSS через тунель → Перевірте tracepath, DF‑ping і виправте MTU/MSS clamping; дозвольте ICMP fragmentation‑needed.
  • Нові з’єднання випадково таймаутять, існуючі працюють → conntrack/NAT майже повний → Перевірте nf_conntrack_count; підвищте ліміти і зменшіть churn з’єднань.
  • Тільки один ISP‑шлях має таймаути → асиметрична маршрутизація або upstream peering issue → Доведіть захопленнями (SYN приходить, SYN‑ACK відходить, не отримано); налаштуйте маршрути або ескалюйте з доказами.
  • Таймаути корелюють зі сплесками трафіку → черги/bufferbloat або насичення CPU файрвола → Дивіться розподіл латентності (worst/stdev), дропи інтерфейсу і лічильники файрвола; застосуйте fq_codel/cake і масштабування.
  • DNS «інколи» падає, особливо для певних імен → EDNS/фрагментація або один поганий резолвер у списку → Тестуйте кожен резолвер напряму; зменшіть EDNS buffer, забезпечте TCP‑fallback, видаліть ненадійний резолвер.
  • mtr TCP на порт працює, але додаток все одно таймаутить → проблеми на рівні додатка або перевантаження сервера → Використайте curl timing breakdown; профілюйте додаток і сервер; не звинувачуйте мережу зарано.
  • Пакети видно, що виходять із сервера, але клієнт їх не отримує → зворотній шлях відкидає (ACL, stateful файрвол, rp_filter) → Перевірте симетрію маршрутів; тюньте rp_filter; виправте політики stateful‑пристроїв.

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

Чекліст A: 15‑хвилинна триаж (один оператор, мінімальний доступ)

  1. Запустіть curl -w timings, щоб класифікувати DNS vs connect vs TLS vs app.
  2. Розв’яжіть hostname до IP за допомогою dig; використовуйте IP для тестів.
  3. Запустіть mtr -T -P <port> до IP з принаймні 200 зразками.
  4. Запустіть ICMP mtr один раз, щоб виявити патерни rate limiting ICMP (не переактивуйтеся).
  5. Перевірте локальні дропи інтерфейсу з ip -s link.
  6. Перевірте маршрутизацію з ip route get.
  7. Якщо connect таймаути: запустіть tcpdump з фільтром host+port під час відтворення.

Чекліст B: Довести асиметрію або stateful‑скидання (коли ви контролюєте обидва кінці)

  1. Запустіть tcpdump на клієнті: фільтр host SERVER and tcp port SERVICE.
  2. Запустіть tcpdump на сервері: фільтр host CLIENT and tcp port SERVICE.
  3. Відтворіть таймаут і збережіть відмітки часу та 5‑tuple.
  4. Якщо сервер бачить SYN і відправляє SYN‑ACK, але клієнт не бачить SYN‑ACK: return path drop/асиметрія.
  5. Якщо сервер не бачить SYN: forward path drop або неправильна маршрутизація/ACL перед сервером.
  6. Корелюйте з лічильниками файрвола/nft і натиском conntrack.

Чекліст C: Перевірка PMTU / MTU (коли «мале працює, велике — падає»)

  1. Запустіть tracepath -n до цілі; зафіксуйте підказки PMTU.
  2. Визначте тунелі і MTU інтерфейсів за допомогою ip link show.
  3. Тестуйте DF‑ping декількох розмірів (в межах локального MTU).
  4. Clamp MSS на краю тунелю; дозвольте критичний ICMP; повторно перевірте TLS‑handshake.

Операційні поради, які варто впровадити

  • Завжди збирайте пакетне захоплення під час збою. Десятити секундне захоплення коштує години здогадок.
  • Вимірювання робіть на рівні сервісного порту (TCP mtr, tcpdump). ICMP — інший клас трафіку і обробляється інакше.
  • Тримайте «відомо‑хорошу» точку спостереження (невелика VM в іншій мережі), щоб відрізняти «вашу мережу» від «світу».

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

1) Чому mtr показує втрати на проміжному хопі, але не на призначенні?

Бо маршрутизатор занижує пріоритет ICMP TTL‑expired відповідей (або rate limits їх), але продовжує форвардити ваші пакети. Довіряйте end‑to‑end втратам.

2) Чи завжди варто використовувати mtr -T?

Для діагностики таймаутів додатка на конкретному TCP‑порті — так. ICMP‑тести корисні для підказок PMTU і загальної досяжності, але TCP‑режим відповідає вашому робочому навантаженню.

3) Як визначити, що таймаут — це DNS?

Використайте curl -w і дивіться time_namelookup. Також запитуйте напряму dig +time=1 +tries=1. Якщо DNS повільний — все здається повільним.

4) Який найпростіший сигнал PMTU blackhole?

TCP connect працює, але TLS‑handshake або великі відповіді зависають, часто з повторними передачами. tracepath може натякнути, але пакети і тести MSS/MTU підтверджують.

5) Чому тільки деякі користувачі бачать таймаути?

Різні маршрути, різні резолвери, різні MTU (VPN), різна поведінка NAT або різні CDN‑edge. «Деякі користувачі» часто означає «деякі шляхи».

6) Чи можна безпечно запускати tcpdump на продакшн‑серверах?

Так, якщо ви фільтруєте жорстко і захоплюєте недовго. Використовуйте фільтри host/port, не пишіть гігантські pcap‑файли на навантажений диск і не залишайте його працювати без нагляду.

7) mtr показує чисті результати, але користувачі все одно таймаутять. Що робити?

mtr не бачить чергувань додатка, проблем TLS або перевантаження сервера. Використайте curl timing breakdown, метрики сервера і tcpdump, щоб знайти, чи пакети зависають після connect.

8) Як зрозуміти, що conntrack — винуватець?

Коли nf_conntrack_count наближається до nf_conntrack_max і нові з’єднання падають, а існуючі лишаються стабільними. Часто зустрічається на NAT‑шлюзах.

9) Яку цитату варто пам’ятати під час цих інцидентів?

Ідея від Werner Vogels (парафраз): «Все ламається постійно; проєктуйте і експлуатуйте системи, враховуючи, що відмови нормальні».

Практичні наступні кроки

Випадкові таймаути перестають бути «випадковими», щойно ви виміряєте правильний рівень і захопите відповідні пакети. Зробіть наступне:

  1. Стандартизувати швидку класифікацію: DNS vs connect vs TLS vs app за допомогою curl -w.
  2. Використовувати TCP mtr до реального порту сервісу і брати достатню вибірку для виявлення періодичності.
  3. Захопити tcpdump під час реального збою принаймні на одній контрольованій кінцевій точці; якщо можливо — на обох кінцях.
  4. Якщо виявлено PMTU/MTU — виправляйте належним чином (MTU, MSS clamping, дозволені ICMP), а не сподівайтеся на повтори.
  5. Якщо виявлено conntrack‑тиск — ставте це як capacity: підвищуйте ліміти, зменшуйте churn і моніторьте серйозно.

Найважливіше: запишіть, що ви дізналися. Коли таймаут повернеться (а він повернеться), вам потрібен буде runbook, а не сеанс спіритизму.

← Попередня
Docker «connection refused» між сервісами: виправляйте мережі, а не симптоми
Наступна →
Адаптивна типографіка, яка добре виглядає: clamp() правильно

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