↓ До тексту
  1. Статті/

nf_conntrack_max - коли сервер мовчки губить з'єднання

·2 хвилини
cat /etc/passwd
Автор
cat /etc/passwd
Технічний блог про Linux, DevOps та Open Source технології.
Зміст

Уяви: сервер працює роками, і тут під навантаженням починає губити з’єднання - то сайт не відкрився, то NAT підвис. А процесор вільний, пам’ять є, у логах додатку пусто. Дуже часто винуватець один - переповнена таблиця conntrack.

Що це взагалі таке?
#

Netfilter (той самий, що за iptables/nftables) вміє стежити за з’єднаннями - щоб розуміти, що оцей пакет належить уже відкритій сесії, а не прилетів з нізвідки. Це зветься connection tracking, скорочено conntrack. Кожне відстежуване з’єднання - окремий рядок у таблиці всередині ядра.

nf_conntrack_max - це максимальна кількість таких рядків. Коли вони закінчуються, ядру нема куди записати нове з’єднання, і воно просто викидає пакет, лишаючи в dmesg класику:

1
nf_conntrack: table full, dropping packet

Ось це і є та сама «незрозуміла» втрата з’єднань на рівному місці.

Модуль nf_conntrack вмикається сам, щойно ти користуєшся NAT або stateful-правилами. На звичайному десктопі його може й не бути; на роутері, шлюзі, реверс-проксі чи балансувальнику - майже завжди.

Як перевірити
#

Межа і скільки зараз зайнято:

1
2
3
4
5
# максимум
cat /proc/sys/net/netfilter/nf_conntrack_max

# скільки з'єднань відстежується прямо зараз
cat /proc/sys/net/netfilter/nf_conntrack_count

Якщо count підкрадається до max - час бити на сполох. Той самий максимум можна глянути й через sysctl:

1
sysctl net.netfilter.nf_conntrack_max

Детальніше - утилітою conntrack (пакет conntrack):

1
2
3
4
5
apt install conntrack

conntrack -C          # скільки записів зараз
conntrack -S          # статистика, зокрема лічильник drop
conntrack -L | head   # самі з'єднання

Рядок drop у conntrack -S - це пакети, які вже загубились через переповнення. Якщо він росте - діагноз підтверджено.

На що це впливає
#

  • Роутери, NAT-шлюзи, балансувальники, проксі - там тисячі одночасних з’єднань, і таблиця переповнюється найлегше. На домашньому ПК про conntrack можна й не згадувати.
  • Переповнення = втрата пакетів. Не гальмування, а саме мовчазні обриви нових з’єднань, поки старі не звільнять місце. Тому й ловиться важко.
  • Пам’ять. Кожен запис займає ~300 байт. Мільйон з’єднань - це вже сотні мегабайт у ядрі, тож задирати max у космос «про всяк випадок» не варто.
  • Таймаути. Записи висять ще довго після закриття сесії (established TCP за замовчуванням тримається аж 5 днів), тож таблиця буває повна навіть при помірному трафіку.

Як збільшити
#

Наживо, до перезавантаження:

1
sysctl -w net.netfilter.nf_conntrack_max=524288

Щоб лишилось назавжди - у /etc/sysctl.d/99-conntrack.conf (або в /etc/sysctl.conf):

1
net.netfilter.nf_conntrack_max = 524288

І застосувати:

1
sysctl -p

Для дуже навантажених систем варто підняти ще й розмір хеш-таблиці, щоб пошук по ній лишався швидким:

1
echo 131072 > /sys/module/nf_conntrack/parameters/hashsize

Орієнтир простий: тримай nf_conntrack_count помітно нижче за max, поглядай на лічильник drop - і сервер перестане «мовчки» губити з’єднання.

Related