Alter.Org.UA  
 << Back Home EN en   Donate Donate www/www1/www2

Patches for IPFW

by Alter (alterX@alter.org.ua (remove X))

Добавляются

  • команды zshow (zero+show), replace (del+add)
  • опция -Q для игнорирования ЛЮБЫХ ошибок в правилах.
  • skipto tablearg
  • via table(), в таблицы можно заносить имена интерфейсов
  • условие if-index - номер интерфейса (например для vlan55 номером будет 55) (полезность под вопросом)
  • индексирование правил (таблица) на уровне ядра для быстрой обработки skipto tablearg, а также быстрого добавления и удаления большого количества правил. На хорошо нагруженной машинке (50kpps, 500Mbit на вход и выход на обеих сетевухах) перестройка 4000 правил занимает до 15 секунд. Без патча - более 10 минут. И после переписывания с учетом обновлений удалось отроутить 100 kpps и 800 Мбит при терпимой загрузке.
  • mapped table - для таблиц, содержащих много мелких элементов /32 делается бинарный поиск подсети (например, /23, задается sysctl net.inet.ip.fw.def_map_mlen), а внутри - поиск по таблице. Работает существенно быстрее. Сделано как radix tree, элементами которого являются массивы (1 элемент на каждый IP из блока).
  • map table - для разбиения крупных подсетей на одинаковые блоки по хешу. Например, /16 разбить на 256 подсеток. Можно по 3му октету IP'шки (hoffset 16, hlen 8). А можно по 4му (hoffset 24, hlen 8). hoffset задает номер бита, с которого начинается хеш, hlen - длина хеша в битах. Устроено так:
    • Есть base_addr + net_mask - чтобы понять, интересует ли нас это пакет вообще (например, /0, вообще все IPv4)
    • hash offset - hash len - чтобы выдернуть из IP'шки индекс. (например, hoffset=0, hlen=24 - все сетки /24)
    • И есть array(counter + value) - собственно массив, из которого выбирается элемент по индексу, полученному на шаге 2 (например, маршруты для этих самых сеток). Если выбранный элемент не отмечен как действительный, пакет не матчится. Если действительный - меняем счетчики и запоминаем value.
    (полезность под вопросом)
  • счетчики пакетов/байтов на каждом элементе таблицы
  • индексирование pipe'ов (таблица) dummynet на уровне ядра для работы с большим к-вом шейперов упраляется sysctl net.inet.ip.dummynet.full_indexing
  • счетчики трафика с ограничением - count-upd, count-check, count-exceed.
  • команда nexthop. В отличие от fwd устанавливает next-hop для пакета и переходит к следующему правилу ipfw.
  • оптимизация dummynet io_fast. При установке значения в 2 dummynet не будет добавлять пакет в очередь вообще, если трафик не превышает допустимый предел. При значении 1 пакет добавляется и тут же удаляется из очереди (что несколько медленнее).
  • вместо списка портов можно использовать таблицы bmap для быстрого разделения трафика по сервисам. Ограничения на к-во элементов нет, скорость проверки не зависит от размера списка. Удобно для приоритезации игрового трафика.
  • Ускоренные ipfw tags (ftag) - допускается 32 штуки. Преимущество - они все хранятся в одном блоке памяти в виде bitmap'а. Кроме того, значение кешируется в локальной переменой на время прохода через ipfw. Обычные tag'и требуют выделения отдельного блока под каждый tag. Проверка обычного tag'а - линейный поиск по связному списку. Проверка/установка ftag'а - быстрая битовая операция над unit32.
  • Локальные ipfw tags (ltag) - допускается 32 штуки. Не сохраняются при выходе из таблицы ipfw (т.е. при проходе через др. интерфейс, divert'е или после выхода из pipe/queue). Преимущество - не требуют выделения памяти вообще.


Patch download:
9.2-STABLEipfw.92.20150115.patch.gz all-inclusive
9.2-STABLEipfw.92.single-patchs.rar/tgz (109.4 Kb/129 Kb) separated patchs
7.2-RELEASE-p8ipfw.72.20120614u.patch.gz all-inclusive

Патчи для IPFW, 9.2-RELEASE.

Есть кумулятивный патч, добавляющий все фичи сразу. Для желающих добавлять инкрементально - ipfw.92.single-patchs.rar/tgz (109.4 Kb/129 Kb)

Патчи для IPFW, 7.2-RELEASE.

ipfw.72.20120614u.patch.gz

Патч содержит весь комплект изменений (см. выше). Ниже приведены примеры использования

FreeBSD bugtrack ID: 156770

Патч совместим с 7.3 и 7.4 за исключением конфликта с пока неиспользуемыми

#define	IP_FW3			48   /* generic ipfw v.3 sockopts */
#define	IP_DUMMYNET3		49   /* generic dummynet v.3 sockopts */
в in.h


Example 1
# interface-based dispatch
ipfw table 1 add %vlan516 55
ipfw table 1 add %em0 10
ipfw add 1 skipto tablearg ip from any to any via table(1)

# IP-based dispatch
ipfw table 60 add mapped 192.168.0.2  1602
ipfw table 60 add mapped 192.168.0.3  1603
ipfw table 60 add mapped 192.168.0.4  1604
ipfw add 2 skipto tablearg ip from any to table(60)

# port-based dispatch (TCP/UDP only)
ipfw bmap 13 add 25,137-139,445
ipfw add 3 deny ip from any to any dst-port bmap(13)

# Limit traffic amount for some IPs
ipfw counter create 4096  # init counter table, up to 4096 items
ipfw counter add @2 set-limit 10g # init counter 2 with 10Gb limit
ipfw counter add @4 set-limit 10g # init counter 4 with 10Gb limit
ipfw counter set-limit @2 5g # reconfig counter 2 with 5Gb limit
# make dispatch table
ipfw table 50 add mapped 192.168.0.2  2
ipfw table 50 add mapped 192.168.0.4  4
# update counters
ipfw add 4 count ip from any to table(50) count-upd tablearg
# block users exceeded traffic limit
ipfw add 5 deny ip from any to table(50) count-exceed tablearg

# count traffic and block users with exceeded limit (variant 2)
ipfw add 4 deny ip from any to table(50) count-check tablearg


Example 2
#!/bin/sh
. /etc/rc.conf


# Tables
# 1  - UA
# 2  - Google peer
# 6  - local nets
# 7  - peer nets
# 8  - lan nets
# 10 - transparent proxy users
# 11 - blocked users
# 50 - UA-out
# 51 - UA-in
# 60 - W-out
# 61 - W-in

# Tags
# 1  - from UA-IX
# 2  - to UA-IX
# 6  - local traffic (directly between server and clients)
# 7  - peer traffic
# 8  - internal (lan, inter-lan) traffic

# 16 - from LOCAL (locally handled clients) - out
# 26 - to LOCAL                             - in
# 17 - from PEER
# 27 - to PEER
# 18 - from LAN   (all handled networks)
# 28 - to LAN
# 19 - from ME
# 29 - to ME


ftag=${ipfw_ftag:-"tag"}

trusted_smtp_clients="table(14)"
blocked_smtp_clients="table(15)"
local_nets="table(6)"
peer_nets=" table(7) or table(2) "
lan_nets="table(8)"
win_ports="$win_ports"

rule_game_ports_out="bmap(2)"
rule_game_ports_in="bmap(3)"

rule_win_ports="$win_ports"
rule_denied_ports="$win_ports,25"


cat > /etc/firewall.conf.1 << EOF
replace 1 allow ip from any to any
replace 51001 allow ip from any to any

# out
table 40 flush
table 40 add %$user_if   16
table 40 add %$user9_if  16
table 40 add %$user7_if  16
table 40 add %$user3_if  16
table 40 add %$user2_if  16
table 40 add %$user12_if 16
table 40 add %$user8_if  16
table 40 add %$user10_if 27
table 40 add %$user11_if 27
table 40 add %vlan522    16
table 40 add %$user88_if 16
table 40 add %$core_if   16
table 40 add %$world_if  3
table 40 add %$world0_if 3
table 40 add %lo0        4
table 40 add %vlan4089   4

# in
table 41 flush
table 41 add %$user_if   40
table 41 add %$user9_if  40
table 41 add %$user7_if  40
table 41 add %$user3_if  40
table 41 add %$user2_if  40
table 41 add %$user12_if 40
table 41 add %$user8_if  40
table 41 add %$user10_if 28
table 41 add %$user11_if 28
table 41 add %vlan522    40
table 41 add %$user88_if 40
table 41 add %$core_if   19
table 41 add %$world_if  18
table 41 add %$world0_if 18
table 41 add %lo0        19
table 41 add %vlan4089   19

#client->server DST games+http(s)+telnet+ssh+dns
bmap 2 add 53,23,22,443
bmap 2 add $game_ports
bmap 2 add $web_ports
bmap 2 add $video_ports
bmap 2 add $skype_ports
#server->client SRC games+https+telnet+ssh+dns
bmap 3 add 53,23,22,443
bmap 3 add $game_ports
bmap 3 add $video_ports
bmap 3 add $skype_ports

bmap 13 add $win_ports
bmap 14 add $win_ports
bmap 14 add 25

replace 2 skipto 5 ip6 from any to any
# separate in/out
add     2 skipto 7 ip from any to any in

# dispatch according to interface (out)
add     2 skipto tablearg ip from any to any via table(40)

replace 3 divert natd ip from { $local_nat_nets } to any
replace	4 allow ip from any to any
replace 5 allow ip6 from any to any in
add     5 allow ip6 from any to any

# allow external SMTP, block Win-ports
del 7
add     7 skipto 9 ip from any to any not $rule_denied_ports

replace 8 deny ip from { $blocked_smtp_clients } to any 25
add     8 skipto 14 tcp from { $trusted_smtp_clients } to any 25
add	8 skipto 14 tcp from { $local_nets } to { $world_mx_ip or $our_relay or me } 25
add     8 deny log { tcp or udp } from { $local_nets } to any 25
add	8 allow ip from me to me
add     8 deny { tcp or udp } from any to any $win_ports

# dispatch according to interface (in)
replace 15 skipto tablearg ip from any to any via table(41)
add     15 skipto 40 ip from any to any

# out, user if(s)
replace 16 allow ip from any to not table(11)
add     16 allow tcp from { $pay_system_ips } 80,443 to any
add     16 allow ip from me to any
add     16 deny ip from any to any

# in, world if(s)
replace 18 divert natd ip from any to $user_nat_ip
del     19
add     19 allow tag 29 ip from any to me
add     19 skipto 115 tag 26 ip from any to any

######## WiFi shapers #########

### to 37/xxx, 12/xxx
pipe 100 config delay 100ms bw 5000kbit/s
pipe 101 config bw 18000kbit/s
pipe 103 config bw 18000kbit/s
delete  27
add     27 allow icmp from any to any
add     27 allow ip from $game_servers to any
add     27 allow { tcp or udp } from any 53,23,22 to any
add     27 allow { tcp or udp } from any $rule_game_ports_in to any
add     27 pipe 100 udp from any to any
add     27 pipe tablearg ip from any to table(101)
add     27 allow tcp from any 80 to any
add     27 allow ip from any to any

### from 37/xxx, 12/xxx
pipe 102 config bw 10000kbit/s
pipe 104 config bw 8000kbit/s
delete  28
add     28 skipto 40 icmp from any to any
add     28 skipto 40 ip from any to $game_servers
add     28 skipto 40 { tcp or udp } from any to any 53,23,22,80,443
add     28 skipto 40 { tcp or udp } from any to any $rule_game_ports_out
add     28 pipe tablearg ip from table(102) to any
add     28 pipe 100 udp from any to any
add     28 skipto 40 ip from any to any

### regular rules (continue) ###

# in, user if(s)
replace 40 skipto 110 tag 16 ip from not table(11) to any
# blocked users
del 109
add     109 count untag 6 ip from any to any
add     109 count untag 8 ip from any to any
add     109 allow { tcp or udp } from any to { $master_servers or me } 53
add     109 fwd 127.0.0.1,80 tcp from any to any 80
add     109 deny ip from any to any

replace 110 skipto 111 ip from any to any not tagged 16,19
add     110 skipto 120 tag 6 ip from any to any tagged 26,29

# only local interfaces are checked here!
# so, local traffic will be checked 

replace 112 skipto 120 ip from any to any tagged 1-2,7-8
#### IN (via local) ####
add     112 skipto 115 ip from any to any out
add     112 skipto 120 tag 8 ip from any to { $lan_nets or me }
add     112 skipto 120 tag 7 ip from any to { $peer_nets }
replace 113 skipto 120 tag 2 ip from any to table(1)
add     113 skipto 19001 ip from any to any tagged 16
add     113 skipto 120 ip from any to any

#### OUT (via local) / IN (via WORLD) ####
replace 115 skipto 120 tag 8 ip from { $lan_nets or me } to any
add     115 skipto 120 tag 7 ip from { $peer_nets } to any
replace 116 skipto 120 tag 1 ip from table(1) to any

#############################
# here comes dispatch rules
#############################

replace 900  skipto 19000 ip from any to any not ftagged 1,2
replace 1500 skipto 1502 ip from any to any ftagged 26
add     1500 skipto tablearg ip from table(50) to any
add     1500 skipto tablearg ip from any to table(51)
add     1500 count ip from any to any
replace 1501 skipto tablearg ip from table(50) to any
add     1501 skipto 38000 ftag 12 ip from any to any
replace 1502 skipto tablearg ip from any to table(51)
add     1502 skipto 38000 ftag 12 ip from any to any
replace 1503 allow ip from any to any

# fill mapped dispatch table
table 50 add mapped 10.0.0.10 1600
table 50 add mapped 10.0.0.11 1610
table 50 add mapped 10.0.0.12 1620

replace 51000 allow ip from any to any

delete 1 51000
EOF

echo "$ftag"
sed -e "s/tag/$ftag/g" < /etc/firewall.conf.1 > /etc/firewall.conf.2
sed -e "s/unftag/funtag/g" -e "s/unltag/luntag/g" < /etc/firewall.conf.2 > /etc/firewall.conf.1

cp /etc/firewall.conf.1 /etc/firewall.conf
ipfw -Q /etc/firewall.conf

History

Патч портирован в FreeBSD 9.2, также доступны инкрементальные патчи.

ipfw.92.20150115.patch.gz
ipfw.92.single-patchs.rar/tgz (109.4 Kb/129 Kb)
2015.01.14

Сделан unified diff, согласно стандартам разработки FreeBSD

ipfw.72.20120614u.patch.gz
2012.06.14

Патчи для IPFW, FreeBSD 7.1-RELEASE и 7.2-RELEASE.

ipfw.72.20110501.patch.gz
2011.05.02

Патчи для IPFW, FreeBSD 7.1-RELEASE и 7.2-RELEASE.

ipfw.71.patch.gz
ipfw.72.patch.gz

Команды zshow, replace, опция игнорирования всех ошибок -i объединена с -q. Т.к. в 7.2 прояснилось понятие игнорирования ошибок в -q, для игнорирования всех ошибок снова сделана отдельная опция - -Q

ipfw_idx.70.patch.gz
ipfw_idx.71.patch.gz
ipfw_idx.72.patch.gz

skipto tablearg, индексирование правил (таблица) на уровне ядра для быстрой обработки skipto tablearg, а также быстрого добавления и удаления большого количества правил


2010.01.01

Патч для IPFW, FreeBSD 7.0-STABLE.

ipfw.70.patch.gz

По прежнему добавляются команды zshow, replace, опция -i объединена с -q.


2008.06.30

Патч для IPFW от FreeBSD 6.3.

ipfw.63.patch.gz

Все нижеперечисленные патчи.

FreeBSD bugtrack ID: 116009
2008.06.30

Патчи для IPFW от FreeBSD 6.2-RELEASE-p5.

all updates

ipfw.62.patch.gz

Все нижеперечисленные патчи.


2007.09.03

zshow

ipfw-zshow.patch.gz

Добавляет команду 'zshow', которая показывает и сразу же обнуляет счетчики. Полезно для считалок трафика.

ipfw zshow 1000

2007.09.03

ignore errors + replace

ipfw-ignore_err_opt.patch.gz

Добавляет команду 'replace', которая добавляет правило, если его еще нет или заменяет если правило с таким номером уже существует.

ipfw replace 200 count ip from any to any via fxp0

Также добавляет ключик '-i', который заставляет ipfw игнорировать синтаксические ошибки в правиле и переходить к следующему. Полезно при загрузке набора правил из файла. Ключик можно использовать как в командной строке, так и в файле с правилами (т.е. для отдельных правил).

ipfw -i /etc/firewall.conf

2007.09.03


Mail to alterX@alter.org.ua (remove X)  
Автор: Alter (Александр А. Телятников) Сервер: Apache+PHP под FBSD © 2002-2017