Arch Linux: “містичні” таймаути з DNS та “в пошуках Ethernet-істини”
0 (0)

Автор |  19/01/2026
Click to rate this post!
[Total: 0 Average: 0]

Вже пару місяців, як на робочому ноуті Lenovo ThinkPad T14 Gen 5 з Arch Linux виникла проблема з відкриттям нових сайтів – перші 10-15 секунд сайт завантажується “шматочками”, наприклад:

Але потім “розчехляється”, і все починає працювати чудово:

Нарешті, як почав налаштовувати нормальну домашню мережу з VPN (див. FreeBSD: Home NAS, part 3 – WireGuard VPN, Linux peer та routing), а потім для неї – DNS (див. FreeBSD: Home NAS, part 4 – локальний DNS з Unbound), то дійшли руки розібратись і з цієї проблемою.

І проблема виявилась дуже цікавою. Причину шукав довго, і перепровірив купу різних налаштувань – від IPv6 і DNS до драйверу мережової карти.

Головне, що проблема не те щоб була критичною – в цілому інет працював, а тому я іноді починав шукати причину, потім закидував, потім знов повертався.

The issue: “communications error to 192.168.0.1#53: timed out”

Що цікаво, що проблема спостерігалась тільки на Ethernet-підключені – на WiFi все працювало чудово.

А на Ethernet репродьюсилось на різних кабелях і через різні роутери.

Значить – що? Значить – або Сєня щось наковиряв руками у своєму Linux, або десь колись прилетів “кривий” апдейт чи до ядра, чи до драйвера, чи до якось бібліотеки.

Вже не пам’ятаю чому, але спершу грішив на DNS, бо ми ж знаємо, що:

І такі да – під час спроб зарепродьюсити це вдалось саме з DNS, під час тестів з dig – тому довго копав в цю сторону.

Виглядала проблема так: робимо dig, 10-15 запитів проходять нормально, а потім прилітає “communications error to 192.168.0.1#53: timed out“:

$ time dig google.com +short @192.168.0.1
;; communications error to 192.168.0.1#53: timed out
...

real    0m5.018s
user    0m0.004s
sys     0m0.008s

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

Логічно? Так.

Тому і всі подальше тести я робив вже в циклі з dig:

$ for i in {1..50}; do { time dig +nocookie +noedns +tries=1 +time=2 google.com >/dev/null; } 2>&1; done
...
real    0m0.016s
...
real    0m2.015s
...
real    0m0.013s
...
real    0m1.392s

І такий результат був постійно – пачка запитів проходить нормально – “real 0m0.016s“, а потім на якомусь одному – таймаут і “real 0m2.015s” (бо +time=2 – чекати 2 секунди, а не дефолтні 5).

Ця ж проблема була видна з tcpdump: в 09:57:47 запит відправлений, але відповіді не отримано, через 2 секунди, в 09:57:49 – новий запит, і на нього вже відповідь прийшла:

...
09:57:47.717951 IP setevoy-work.40923 > _gateway.domain: 13058+ [1au] A? google.com. (51)
09:57:49.729589 IP setevoy-work.45441 > _gateway.domain: 63641+ [1au] A? google.com. (51)
09:57:49.730249 IP _gateway.domain > setevoy-work.45441: 63641 6/4/4 A 142.250.109.101, A 142.250.109.100, A 142.250.109.139, A 142.250.109.138, A 142.250.109.102, A 142.250.109.113 (260)
...

Аналогічно видна проблема з strace:

$ strace -r -e trace=network dig google.com
...
     0.002788 socket(AF_INET, SOCK_DGRAM, IPPROTO_IP) = 15
...
     ;; communications error to 192.168.0.1#53: timed out
     5.005754 socket(AF_INET, SOCK_DGRAM, IPPROTO_IP) = 16
...

Тут в 0.002788 відкритий сокет для відправки запиту, а через 5 секунд (5.005754) – бо зараз dig запускався без +time=2 – відкривається новий сокет для нового запиту, бо на попередній відповіді не було.

В пошуках Немо проблеми

Тут опишу що взагалі перевіряв – квест вийшов той ще.

Хоча записав не все, робив більше, але основне зберіг – вже давно є звичка закидувати в чорнетку поста на RTFM під час дебагу проблем.

Перевірка DNS в Linux

Перше – що з DNS в системі?

В /etc/resolv.conf заданий роутер:

# Generated by NetworkManager
nameserver 192.168.0.1

Міняємо на 1.1.1.1 чи на 8.8.8.8 – проблема залишається.

Окей… Може, в системі ще якийсь активний резолвер, і починається “DNS-гонка в ядрі” – запит “блукає” між ними?

Перевіряємо systemd-resolved – ні, не запущений:

$ systemctl status systemd-resolved
○ systemd-resolved.service - Network Name Resolution
     Loaded: loaded (/usr/lib/systemd/system/systemd-resolved.service; disabled; preset: enabled)
     Active: inactive (dead)
...

Може, dnsmasq?

Теж виключений:

$ systemctl status dnsmasq
○ dnsmasq.service - dnsmasq - A lightweight DHCP and caching DNS server
     Loaded: loaded (/usr/lib/systemd/system/dnsmasq.service; disabled; preset: disabled)
     Active: inactive (dead)
...

Значить, DNS-запити йдуть напряму до роутера, і… Що? Тупить роутер з відповідями? До нього не доходять запити – іноді губляться?

Що це може бути?

  • локальний firewall на Linux чи роутері?
    • ні – вимикав, проблема залишалась
  • race між кількома локальними DNS-сервісами?
    • виключили вище
  • power management мережевої карти – вона уходить в sleep?
    • маловірогідно, але далі перевіряв і це
  • баг драйвера мережевої карти?
    • можливо, бо проблема з’явилась не так давно, до цього на цьому ноуті і цій системі все працювало без проблем
  • якісь проблеми конкретно з UDP?
    • теж ніж – робив dig +tcp google.com, проблема залишалась
  • відповідь на DNS-запит повертається з іншого IP?
    • екзотична ідея, але як варіант – на роутері кілька мережевих інтерфейсів, об’єднаних в bridge, і – теоретично – роутер може відправити відповідь з іншої
    • але це прям щось дуже неординарне, та і проблема виникала однаково на різних роутерах, і раніше її не було

IPv6 та DNS

Не пам’ятаю чому, але десь на початку грішив на IPv6 під час виконання DNS.

/etc/gai.conf керує алгоритмом вибору адрес у glibc (GAI = getaddrinfo()), і визначає яку адресу (IPv4 чи IPv6) програма, яка робила DNS-запит вибере першою у випадку, якщо DNS повернув і A, і AAAA записи.

Можна включити IPv4 first – розкоментувати строку:

...
precedence ::ffff:0:0/96 100
...

Перевіряємо, що повернеться першим – адреса IPv4, чи IPv6:

$ getent ahosts google.com
142.250.130.100 STREAM google.com
...  
2a00:1450:4025:800::64 STREAM 
...

Першим IPv4, але теж не допомогло.

Пробував виключити в ядрі IPv6 взагалі:

$ sudo sysctl -w net.ipv6.conf.all.disable_ipv6=1
$ sudo sysctl -w net.ipv6.conf.default.disable_ipv6=1

Тут здавалось, що проблема знайдена – бо перший раз все пройшло без проблем, але ні – потім знов таймаути.

NIC Offloading

NIC Offloading – це коли частина операцій виконується на самому мережевому інтерфейсі, тобто offload деяких задач з CPU ноутбука на контролер карти.

Перевіряємо активні з ethtool -k:

$ sudo ethtool -k enp0s31f6 | grep on
rx-checksumming: on
tx-checksumming: on
        tx-checksum-ip-generic: on
scatter-gather: on
        tx-scatter-gather: on
tcp-segmentation-offload: on
...
generic-segmentation-offload: on
generic-receive-offload: on
rx-vlan-offload: on
tx-vlan-offload: on
receive-hashing: on
...

Самі цікаві тут:

  • TSO (TCP Segmentation Offloading): процесор віддає карті один великий шматок даних (наприклад, 64 КБ), а карта сама “нарізає” його на маленькі TCP-пакети по 1500 байт
  • GSO (Generic Segmentation Offloading): те саме, що й TSO, але більш універсальне (працює не лише для TCP)
  • GRO (Generic Receive Offloading): зворотний процес – карта отримує багато дрібних пакетів, “склеює” їх в один великий і лише тоді віддає процесору, що економить ресурси CPU
  • RX та TX Checksum Offloading: карта сама перевіряє контрольні суми (CRC) вхідних пакетів – якщо пакет “битий”, карта його просто викидає, навіть не повідомляючи операційну систему

По черзі вимикаємо їх, і перевіряємо:

  • sudo ethtool -K enp0s31f6 gro off: не допомогло
  • sudo ethtool -K enp0s31f6 gso off: не допомогло
  • sudo ethtool -K enp0s31f6 tso off: не допомогло
  • sudo ethtool -K enp0s31f6 rx off: не допомогло, і стало навіть гірше

Насправді те, що після відключення RX Checksum Offloading стало гірше – вже було підказкою: якщо до цього мережева карта сама фільтрувала помилки, то тепер вони всі повалили до ядра, що створило додаткове навантаження і хаос у черзі пакетів, тому корисні DNS-відповіді стали губитися ще частіше.

NIC Power Management

EEE (Energy Efficient Ethernet) має зменшувати витрати енергії на роботу карти.

Перевіряємо:

$ sudo ethtool --show-eee enp0s31f6
EEE settings for enp0s31f6:
enabled - active
17 (us)
        Supported EEE link modes:  100baseT/Full
                                   1000baseT/Full
        Advertised EEE link modes:  100baseT/Full
                                    1000baseT/Full
        Link partner advertised EEE link modes:  100baseT/Full
                                                 1000baseT/Full

Зараз “enabled – active” – вимикаємо:

$ sudo ethtool --set-eee enp0s31f6 eee off

Не допомогло.

Ще пробував так: запускаємо ping з короткими інтервалами, аби карта не засинала:

$ ping -i 0.2 192.168.0.1

І одночасно запускаємо цикл з dig – але проблема залишається.

Окремо перевіряв налаштування Runtime Power Management:

Знаходимо адресу PCI для девайсу enp0s31f6:

$ ls -l /sys/class/net/enp0s31f6/device
lrwxrwxrwx 1 root root 0 Jan 19 09:38 /sys/class/net/enp0s31f6/device -> ../../../0000:00:1f.6

Або:

an 19 09:38 /sys/class/net/enp0s31f6/device -> ../../../0000:00:1f.6
[setevoy@setevoy-work ~]  $ lspci -D | grep Ethernet
0000:00:1f.6 Ethernet controller: Intel Corporation Ethernet Connection (18) I219-LM (rev 20)

І перевіряємо параметри power:

$ cat /sys/bus/pci/devices/0000:00:1f.6/power/control
on

on” – включена постійно, значить не має вимикатись.

Драйвер та Message Signaled Interrupts

Перевіряв драйвер:

$ lspci -k -s 00:1f.6
00:1f.6 Ethernet controller: Intel Corporation Ethernet Connection (18) I219-LM (rev 20)
        Subsystem: Lenovo Device 2327
        Kernel driver in use: e1000e
        Kernel modules: e1000e

Мережевий контролер – Intel I219-LM, і драйвер e1000e, про який пишуть, що він “капризний”.

Параметри interrupts:

$ cat /proc/interrupts | grep -i enp0s31f6 ... IR-PCI-MSI-0000:00:1f.6 0-edge enp0s31f6

IR-PCI-MSI-0000:00:1f.6 – драйвер використовує MSI (Message Signaled Interrupts), яка начебто на Linux може давати drops для UDP на деяких картах Intel.

Створив файл /etc/modprobe.d/e1000e.conf, задав interrupt mode в legacy (див. Linux* Driver for Intel(R) Ethernet Network Connection):

options e1000e IntMode=0

Ребутнувся, перевірив:

$ cat /proc/interrupts | grep -i enp0s31f6
  19:     240716         ...  IR-IO-APIC   19-fasteoi   enp0s31f6

Не допомогло – проблема все ще залишалась.

Та і dig +tcp google.com все одно працював з проблемами.

Final: rx_crc_errors та зменшення швидкості

Ну і те, що спочатку пропустив – перевірка помилок на інтерфейсі.

Пропустив, бо кількість помилок не росла під час тестів:

$ ip -s link show enp0s31f6
3: enp0s31f6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
    link/ether c4:c6:e6:e7:e4:26 brd ff:ff:ff:ff:ff:ff
    RX:  bytes packets errors dropped  missed   mcast           
     750558152  589207    104       0       0       0 
    TX:  bytes packets errors dropped carrier collsns           
      40067575  157761      0       2       0       0 
    altname enxc4c6e6e7e426

Або з ethtool:

$ sudo ethtool -S enp0s31f6 | grep -E "errors|missed|dropped|timeout|tx_aborted" | grep -v ": 0"
     rx_errors: 114
     tx_dropped: 26
     rx_crc_errors: 57

rx_crc_errors каже, що проблема з цілісністю пакетів, і – якщо з роутерам і кабелем все в порядку (а проблема спостерігалась на різних роутерах і з різними кабелями) – то скоріш за все проблема в самому RJ-45 на ноутбуці, хоча контакти виглядають нормально.

Спробував примусово зменшити швидкість на інтерфейсі з гігабіта до 100 Mbps:

$ sudo ethtool -s enp0s31f6 speed 100 duplex full autoneg on

І чудо! Все працює!

Повертаємо знов 1000:

$ sudo ethtool -s enp0s31f6 speed 1000 duplex full autoneg on

І проблема знову з’являється.

Можна було б просто залишити 100 Mbps – але ж я не для того підключений по кабелю і плачу за гігабітний GPON?

Благо, вдома є кілька USB-адаптерів з Ethernet, перемкнув кабель на нього:

$ ip a s enp0s13f0u2u3
2: enp0s13f0u2u3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether c8:4d:44:29:27:6b brd ff:ff:ff:ff:ff:ff
    altname enxc84d4429276b
    inet 192.168.0.198/24 brd 192.168.0.255 scope global dynamic noprefixroute enp0s13f0u2u3
...

Є гігабіт і Full Duplex:

$ sudo ethtool enp0s13f0u2u3
Settings for enp0s13f0u2u3:
        Supported ports: [ TP    MII ]
        Supported link modes:   10baseT/Half 10baseT/Full
                                100baseT/Half 100baseT/Full
                                1000baseT/Half 1000baseT/Full
        ...
        Speed: 1000Mb/s
        Duplex: Full
        ...
                               drv probe link timer ifdown ifup rx_err tx_err tx_queued intr tx_done rx_status pktdata hw wol
        Link detected: yes

І тепер все працює без проблем.

Loading