С недавнего времени начались проблемы с инетом. Причём после шлюза всё нормально пингуется, а в локалке идут страшные потери пакетов, страницы недогружаются. Полазив в инете, понял, что проблема может крыться в переполнении таблиц NAT'а. А если быть точнее, то в переполнении таблиц ipnat'a. Именно его я использую для трансляции адресов.
Для начала проверим состояния ipnat'a.
#ipnat -s
mapped in 86303767 out 3841584134added 104357220 expired 0no memory 905283 bad nat 2172013inuse 29996rules 18wilds 2
Заодно посмотрим топ качков (слева колличество открытых соединений):
#ipnat -l | awk '{print $2}'| sort | uniq -c | sort -r | grep "10.0." | less
3185 10.0.19.702238 10.0.19.941807 10.0.19.801701 10.0.3.111 973 10.0.19.116 744 10.0.19.68 672 10.0.3.83 663 10.0.19.75 654 10.0.19.136 590 10.0.19.38 526 10.0.3.230 412 10.0.19.91 399 10.0.19.120 363 10.0.19.83 272 10.0.19.39 263 10.0.19.92 240 10.0.19.56 208 10.0.19.72 188 10.0.19.6
Теперь посмотрим на максимальное значение
#ipf -T listfr_flags min 0 max 0xffffffff current 0fr_active min 0 max 0 current 0fr_control_forwarding min 0 max 0x1 current 0fr_update_ipid min 0 max 0x1 current 0fr_chksrc min 0 max 0x1 current 0fr_pass min 0 max 0xffffffff current 134217730fr_tcpidletimeout min 0x1 max 0x7fffffff current 864000fr_tcpclosewait min 0x1 max 0x7fffffff current 480fr_tcplastack min 0x1 max 0x7fffffff current 480fr_tcptimeout min 0x1 max 0x7fffffff current 480fr_tcpclosed min 0x1 max 0x7fffffff current 120fr_tcphalfclosed min 0x1 max 0x7fffffff current 14400fr_udptimeout min 0x1 max 0x7fffffff current 240fr_udpacktimeout min 0x1 max 0x7fffffff current 24fr_icmptimeout min 0x1 max 0x7fffffff current 120fr_icmpacktimeout min 0x1 max 0x7fffffff current 12fr_iptimeout min 0x1 max 0x7fffffff current 120fr_statemax min 0x1 max 0x7fffffff current 4013fr_statesize min 0x1 max 0x7fffffff current 5737fr_state_lock min 0 max 0x1 current 0fr_state_maxbucket min 0x1 max 0x7fffffff current 26fr_state_maxbucket_reset min 0 max 0x1 current 1ipstate_logging min 0 max 0x1 current 0fr_nat_lock min 0 max 0x1 current 0ipf_nattable_sz min 0x1 max 0x7fffffff current 2047ipf_nattable_max min 0x1 max 0x7fffffff current 30000ipf_natrules_sz min 0x1 max 0x7fffffff current 127ipf_rdrrules_sz min 0x1 max 0x7fffffff current 127ipf_hostmap_sz min 0x1 max 0x7fffffff current 2047fr_nat_maxbucket min 0x1 max 0x7fffffff current 22fr_nat_maxbucket_reset min 0 max 0x1 current 1nat_logging min 0 max 0x1 current 0fr_defnatage min 0x1 max 0x7fffffff current 1200fr_defnatipage min 0x1 max 0x7fffffff current 120fr_defnaticmpage min 0x1 max 0x7fffffff current 6ipfr_size min 0x1 max 0x7fffffff current 257fr_ipfrttl min 0x1 max 0x7fffffff current 120ippr_ftp_debug min 0 max 0xa current 0
Мда... До переполнения осталось 4 записи. Ну что ж, будем тюнинговать. Перед этим обязательно прочесть заметку в конце статьи "А что же мы получаем, включая LARGE_NAT". Открываем файл /usr/src/sys/contrib/ipfilter/netinet/ip_nat.h и ищем словосочетание #undefine LARGE_NAT (#undef LARGE_NAT) и меняем на #define LARGE_NAT. Этим мы включили "большое нат", то есть намного увеличили значение (теперь оно будет 180000, после пересборки ядра, конечно же :) ). Но мне показалось и этого мало :), мало ли, потом опять будет что-то. Поэтому я реши немного изменить некоторые значения в этом файле (первая строка, что будет при включённом "большом нате", вторая - на что изменил)
// # define NAT_SIZE 2047# define NAT_SIZE 4093
// # define RDR_SIZE 2047# define RDR_SIZE 4093
// # define HOSTMAP_SIZE 8191# define HOSTMAP_SIZE 16383
// # define NAT_TABLE_MAX 180000# define NAT_TABLE_MAX 300000
// # define NAT_TABLE_SZ 16383# define NAT_TABLE_SZ 32765
Как видим, почти в 2 раза увеличил.
Теперь пересобираем ядро и наслаждаемся новыми переменными. (Как пересобрать ядро читаем здесь).
После пересборки смотрим наши переменные
#ipf -T list
fr_flags min 0 max 0xffffffff current 0fr_active min 0 max 0 current 0fr_control_forwarding min 0 max 0x1 current 0fr_update_ipid min 0 max 0x1 current 0fr_chksrc min 0 max 0x1 current 0fr_minttl min 0 max 0x1 current 4fr_icmpminfragmtu min 0 max 0x1 current 68fr_pass min 0 max 0xffffffff current 134217730fr_tcpidletimeout min 0x1 max 0x7fffffff current 864000fr_tcpclosewait min 0x1 max 0x7fffffff current 480fr_tcplastack min 0x1 max 0x7fffffff current 60fr_tcptimeout min 0x1 max 0x7fffffff current 480fr_tcpclosed min 0x1 max 0x7fffffff current 60fr_tcphalfclosed min 0x1 max 0x7fffffff current 14400fr_udptimeout min 0x1 max 0x7fffffff current 240fr_udpacktimeout min 0x1 max 0x7fffffff current 24fr_icmptimeout min 0x1 max 0x7fffffff current 120fr_icmpacktimeout min 0x1 max 0x7fffffff current 12fr_iptimeout min 0x1 max 0x7fffffff current 120fr_statemax min 0x1 max 0x7fffffff current 4013fr_statesize min 0x1 max 0x7fffffff current 5737fr_state_lock min 0 max 0x1 current 0fr_state_maxbucket min 0x1 max 0x7fffffff current 26fr_state_maxbucket_reset min 0 max 0x1 current 1ipstate_logging min 0 max 0x1 current 1fr_nat_lock min 0 max 0x1 current 0ipf_nattable_sz min 0x1 max 0x7fffffff current 32765ipf_nattable_max min 0x1 max 0x7fffffff current 300000ipf_natrules_sz min 0x1 max 0x7fffffff current 4093ipf_rdrrules_sz min 0x1 max 0x7fffffff current 4093ipf_hostmap_sz min 0x1 max 0x7fffffff current 16383fr_nat_maxbucket min 0x1 max 0x7fffffff current 30fr_nat_maxbucket_reset min 0 max 0x1 current 1nat_logging min 0 max 0x1 current 1fr_defnatage min 0x1 max 0x7fffffff current 1200fr_defnatipage min 0x1 max 0x7fffffff current 120fr_defnaticmpage min 0x1 max 0x7fffffff current 6fr_nat_doflush min 0 max 0x1 current 0ipf_proxy_debug min 0 max 0xa current 0ipfr_size min 0x1 max 0x7fffffff current 257fr_ipfrttl min 0x1 max 0x7fffffff current 120ipl_suppress min 0 max 0x1 current 1ipl_logmax min 0 max 0x7fffffff current 7ipl_logall min 0 max 0x1 current 0ipl_logsize min 0 max 0x80000 current 8192ippr_ftp_debug min 0 max 0xa current 0
Видим, что так же изменились некоторые другие переменные, которые мы тюнинговали.
Заметка: А что же мы получаем, включая LARGE_NAT?
Когда я заюзал на новом сервачке LARGE_NAT, то столкнулся с некоторой проблемой: рвуться сессии NAT'a, если они неактивны 10 минут. Хотя, если посмотреть на вывод ipf -T list, то там указано 864000 (то есть неделя). В чём же может быть дело? А дело, как выяснилось, именно в определении LARGE_NAT. Если посмотреть внимательно код в файле ip_nat.c, то можно увидеть, что время обрыва сессии принудительно устанавливается в 10 минут, если включён LARGE_NAT. Меня такое не устравало и я пошёл искать в инете инфу по этому поводу. На одном из форумов кинули линк, где шла (год был 2003) переписка по этому поводу. Почитав внимательно, и понял, что LARGE_NAT используеся, когда мы имеем тысячи подсетей (а у меня их не больше 30). Да и насколько я понял, особый смысл в этом параметре именно ограничение сессии в 10 минут, посколько для тысяч сетей колличество одновременно открытых NAT-сессий может достигать миллионов. Соотвественно, таблица NAT'a быстро бы переполнялась. Для себя же я решил: не использовать LARGE_NAT, а просто увеличить те значения, которые мне нужно, чего и вам советую. Сервак с таким конфигом работает уже несколько дней, нареканий нет, обслуживает несколько сотен юзеров.