Во FreeBSD для включения PF указываем в /etc/rc.conf:
pf_enable="YES"При необходимости выделения гарантированной полосы пропускания для голосового трафика задействуем ALTQ.
Пересобираем ядро с поддержкой ALTQ, указав в конфигурации:
options ALTQ
options ALTQ_CBQ # Class Bases Queuing (CBQ)
options ALTQ_RED # Random Early Detection (RED)
options ALTQ_RIO # RED In/Out
options ALTQ_HFSC # Hierarchical Packet Scheduler (HFSC)
options ALTQ_PRIQ # Priority Queuing (PRIQ)
options ALTQ_NOPCC # Required for SMP build
Далее для организации NAT для машин с SIP телефонами используем следующие настройки пакетного фильтра (/etc/pf.conf):
# Вернет ошибку, порт заблокирован
set block-policy return
# тайм-аут UDP сессии должен быть равен или больше, чем время регистрации SIP
# Таймер тайм-аута. Обычно достаточно 300 секунд.
set timeout { udp.first 300, udp.single 150, udp.multiple 900 }
# переменные
int_if = "fxp0"
ext_if = "fxp1"
int_net = "192.168.1.0/24"
ipphone1 = "192.168.1.18"
ipphone2 = "192.168.1.19"
# Включим очереди для внешнего интерфейса. Отделим голосовой трафик от данных
altq on $ext_if hfsc bandwidth 512Kb queue { q_voice, q_other }
queue q_voice bandwidth 3.84Kb priority 6 hfsc(realtime 96Kb)
queue q_other bandwidth 416Kb hfsc { q_pri, q_std, q_low }
queue q_pri bandwidth 200Kb priority 3 hfsc(red realtime 64Kb)
queue q_std bandwidth 200Kb priority 2 hfsc(default red )
queue q_low bandwidth 3.84Kb priority 1 hfsc(red )
# Для каждого IP- телефона свое правило трансляции nat.
# Параметр static-port нужен для сохранения временного порта UDP.
# Это нужно чтобы удаленный SIP прокси знал к какой сессии привязан наш IP телефон.
nat on $ext_if proto udp from $ipphone1 to any -> ($ext_if) static-port
nat on $ext_if proto udp from $ipphone2 to any -> ($ext_if) static-port
# Правило NAT для остальных устройств локальной сети
nat on $ext_if from $int_net to any -> ($ext_if)
pass in quick on lo0 all
pass out quick on lo0 all
# Разрешаем SIP трафик с телефонов на локальном интерфейсе
pass in quick on $int_if proto udp from $ipphone1 to any tag VOIP keep state
pass in quick on $int_if proto udp from $ipphone2 to any tag VOIP keep state
pass in quick on $ext_if proto tcp from any to any port 22 keep state \
queue(q_std,q_pri)
pass in quick on $ext_if proto tcp from any to any port 80 keep state \
queue q_low
pass out quick on $ext_if tagged VOIP queue q_voice keep state
pass out quick on $ext_if proto tcp from any to any port 22 keep state \
queue(q_std,q_pri)
pass out quick on $ext_if proto tcp from any to any flags S/SA keep state \
queue(q_std,q_pri)
pass out quick on $ext_if proto udp from any to any port 53 queue q_pri \
keep state
# Разрешаем с внешнего интерфейса наружу tcp, udp, icmp
pass out quick on $ext_if proto { tcp, udp, icmp } all keep state
block in log all
Конфигурация была протестирована на VoIP телефоне Cisco 7960,
NAT прокси и outbound_proxy не используются, в телефоне настроен прокси-сервер SIP и порт контроля 5060/udp. Функция STUN в телефоне включена, хотя некоторые коммерческие SIP-прокси могут работать без него.
Проверить очереди:
pfctl -vsq -v
Очистить таблицы состояний:
pfctl -F state
Проверка правил:
pfctl -s rules -v
URL: http://www.arg.su/ru-RU/node/128 http://www.bastard.net/~kos/pf-voip.html
Обсуждается: http://www.opennet.dev/tips/info/2220.shtml