rx_dispatcher=1
или rx_dispatcher=2
Неблокирующий алгоритм диспетчеризации в DPI, распределяющий сессии по рабочим потокам накладывает ограничение на то, какой белый IP-адрес может быть назначен абоненту из пула:
expr $(ps -p `pidof fastdpi` H -o comm|grep wrk|wc -l) / $(ps -p `pidof fastdpi` H -o comm|grep rx|wc -l)
Посмотреть, какой белый адрес был назначен серому, можно командой
fdpi_ctrl list status --service 11 --ip 192.168.4.20
В NAT 1:1 белый адрес выделяется сразу при назначении услуги, в CG-NAT в момент начала сессии. Также выделенный абоненту белый адрес рапортуется в Radius Accounting в целях его логирования в биллинге.
Заранее предсказать, какой именно адрес будет выдан абоненту из пула невозможно: это зависит от разных факторов и в частности от текущей загрузки пула.
Действительно, время жизни сессии в NAT ограничено, так как количество сессий у абонента — ограниченный ресурс и большое количество неактивных сессий в пуле уменьшает производительность NAT и общую.
У NAT нет возможности отличить, сессия стала неактивной в результате аварии или просто в ней нет никакой активности, и закрывает такие долго висящие сессии по таймауту неактивности. Такое поведение предусмотрено стандартом и поддержано большинством производителей CG-NAT.
В СКАТ время жизни сессий можно корректировать следующими параметрами:
lifetime_flow_long=600
— время жизни в секундах неактивных TCP-сессийlifetime_flow=60
— время жизни в секундах остальных сессий
Поэтому при необходимости поддержания длительных неактивных соединений рекомендуется использовать механизм tcp keep-alive
, когда периодически в сессии передается пустой пакет, который сигнализирует, что сессия все еще активна.
Настроить tcp keep-alive
можно как индивидуально для приложения на стороне сервера или клиента, так и на уровне операционной системы для всех приложений сразу.
Пример настройки на ssh сервере: в файл /etc/ssh/ssh_config
добавить строку:
ServerAliveInterval 60
Пример настройки на ssh клиенте: в файл ~/.ssh/config
добавляем строки:
Host * ServerAliveInterval 60
или в командной строке:
ssh -o TCPKeepAlive=yes -o ServerAliveInterval=60 user@example.com
Пример настройки для всех приложений в CentOS: в файл /etc/sysctl.conf
добавить строки:
net.ipv4.tcp_keepalive_time = 600 net.ipv4.tcp_keepalive_intvl = 60 net.ipv4.tcp_keepalive_probes = 20
Подробнее:
По умолчанию на одном белом IP для CG-NAT доступны 64512 портов (65535-1023, первые 1024 порта не используются, т.к. являются системными), каждый порт — это одна TCP сессия и одна UDP. Количество сессий, которое создают абоненты отличается: физ. лица создают меньше сессий, юр. лица больше (поэтому для юр. лиц нужно использовать отдельный пул с другим лимитами на количество сессий), абонент с торрентом может создать в пике до 1000 сессий.
В среднем физическое лицо создает 50-60 одновременно работающих сессий, т.е. 64512/60=1075 физ. лиц можно спрятать за одним серым IP, но на практике такую значительную переподписку использовать не рекомендуется, т.к. многие популярные сервисы (почта, видео, поиск) используют защиту от атак ботнет сетей, основанную на IP-адресах. Поэтому если с одного адреса им придет слишком много запросов, они могут принять это за атаку и заблокировать часть запросов или включить капчу, что создаст неудобства для абонентов.
Также необходимо учесть особенность механизма освобождения портов в NAT Pool:
Рекомендации при создании и эксплуатации NAT Pool:
fdpi_ctrl load profile --service 11 --profile.name test_nat_2000 --profile.json '{ "nat_ip_pool" : "111.111.111.0/24", "nat_tcp_max_sessions" : 2000, "nat_udp_max_sessions" : 2000, "nat_type" : 0 }'
Используется команда создания пула, идентичного прежнему, но с другими настройками nat_tcp_max_sessions
и nat_udp_max_sessions
fdpi_ctrl load profile --service 11 --profile.name test_nat_2000 --profile.json '{ "nat_ip_pool" : "111.111.111.0/24,222.222.222.0/25", "nat_tcp_max_sessions" : 2000, "nat_udp_max_sessions" : 2000, "nat_type" : 0 }'
Используется команда создания пула, идентичного прежнему, но с дополнительным пулом, указанным через запятую.
Для удобства установим jq (утилиту для работы с данными в формате JSON):
yum install epel-release yum-utils yum-config-manager --disable epel yum --enablerepo epel install jq
После чего сохраним информацию об абонентах текущего пула, удалим и создадим пул и подключим к нему абонентов:
fdpi_ctrl list all --service 11 --profile.name test_nat_4000 --outformat json|jq '.lservices[] | .login | select(. != null)' > save_users.txt fdpi_ctrl list all --service 11 --profile.name test_nat_4000 --outformat json|jq -r '.lservices[] | .ipv4 | select(. != null)' >> save_users.txt fdpi_ctrl del all --service 11 --profile.name test_nat_4000 fdpi_ctrl del profile --service 11 --profile.name test_nat_4000 fdpi_ctrl load profile --service 11 --profile.name test_nat_4000 --profile.json '{ "nat_ip_pool" : "111.111.111.0/30", "nat_tcp_max_sessions" : 4000, "nat_udp_max_sessions" : 4000, "nat_type" : 0 }' fdpi_ctrl load --service 11 --profile.name test_nat_4000 --file save_users.txt
Не забудьте изменить в командах имя пула и его новые параметры на нужные вам.
Если у абонента всего один серый адрес и требуется выдать абоненту конкретный белый адрес, то нужно учитывать зависимость между серыми и белыми адресами, которая накладывается алгоритмом неблокирующей диспетчеризации адресов в DPI.
белый_адрес_абонента & mask = серый_адрес_абонента & mask
где mask зависит от числа рабочих потоков:
Фактически для младших версий СКАТ абонентам с четными серыми адресами нужно выдавать четные белые адреса, а нечетными — нечетные. Достаточно учитывать только младший байт NNN в IP адресе XXX.YYY.ZZZ.NNN
Соответственно для старших версий нужно учитывать равенство 2 младших бит IP адреса.
При одном рабочем потоке зависимость между адресами исчезает.
Точное значение маски можно посмотреть в логе DPI:
grep nat_hash_mask /var/log/dpi/fastdpi_alert.log
Если старт был давно, то выполнить reload
service fastdpi reload
Пример для СКАТ-20:
абоненту с серым адресом 10.0.0.15 требуется выдать белый адрес 188.99.99.27
маска=3
15&3=3 равно 27&3=3 - это значит, такой адрес выдать можно (в противном случае пришлось бы поменять или выдаваемый абоненту серый адрес, или назначаемый ему белый)
Назначаем адрес абоненту командой:
fdpi_ctrl load profile --ip 10.0.0.15 --service 11 --profile.json '{ "nat_ip_pool" : "188.99.99.27/32", "nat_type" : 1 }'
1. В профиле должны быть пулы одного размера1). Правильно:
type_profile=1, ref_cnt=0 d3 { "nat_ip_pool" : "1.1.2.0/28,1.1.3.0/28", "nat_tcp_max_sessions" : 2000, "nat_udp_max_sessions" : 2000, "nat_type" : 0 } 11 (0x400)
Неправильно:
type_profile=1, ref_cnt=0 d3 { "nat_ip_pool" : "1.1.2.0/28,1.1.3.0/26", "nat_tcp_max_sessions" : 2000, "nat_udp_max_sessions" : 2000, "nat_type" : 0 } 11 (0x400
2. Для абонентов которые в блокировке, следует подключать другой профиль, с другими пулами. Многие сетевые устройства, при блокировке, могут генерировать большое количество запросов, что приводит к использованию свободных портов у публичного адреса.
3. Посмотреть равномерность распределения приватных адресов по публичным адресам в профиле.
fdpi_ctrl list all status --service 11 --profile.name nat_pool |grep whiteip|cut -f7|sort|uniq -c|sort -n
4. Посмотреть количество абонентов, которые используют порты сверх значения переменной $P. В среднем абонент использует около 600 портов.
fdpi_ctrl list all status --service 11 --profile.name nat_pool | awk 'BEGIN {FS="[=| }\t]+"} $15>$P {print $1, $14, $15}' | wc -l
5. Посмотреть, как распределились адреса по пулам (подсетям) в профиле.
fdpi_ctrl list all status --service 11 --profile.name nat_pool |grep whiteip|cut -f7|cut -d"." -f1,2,3|sort|uniq -c|sort -n
rx_dispatcher=1
или rx_dispatcher=2