== Sytuacja: ==
Masz firewall/router oparty o netfilter/iptables. Filtrujesz ruch pomiędzy wieloma stacjami, do tego masz masę vlanów, róźne klasy adresowe, sieci przyłączone itd itp - liczba oraz poziom skomplikowania twoich reguł rośnie wykładniczo a co za tym idzie wydajność twojego fw/routera przy dużym ruchu spada.
Jednym z problemów może być koszt przeszukiwania długiego łańcucha reguł by trafić na tą pasującą. Przykładowo filtrujemy stacje po ich adresach źródłowych celem dostępu do konkretnej uslugi np. http (tcp/80):
iptables -A FORWARD -p tcp -s 192.168.0.2 -m state --state NEW -j do-http
iptables -A FORWARD -p tcp -s 192.168.0.3 -m state --state NEW -j do-http
iptables -A FORWARD -p tcp -s 192.168.0.4 -m state --state NEW -j do-http
...
iptables -A FORWARD -p tcp -s 192.168.1.2 -m state --state NEW -j do-http
...
iptables -A FORWARD -p tcp -s 192.168.0.2 -m state --state NEW -j do-http
...
iptables -A FORWARD -p tcp -s 10.0.0.2 -m state --state NEW -j do-http
...
i tak kolejno dla każdego klienta, vlanu, sieci , blablabla.
Super działa. Wydajnie? hmm. Dla małej ilości reguł oraz małego ruchu tak, ale gdy reguły zaczynamy liczyć w setkach, tysiącach a wykorzystanie pasma przekracza kilkadziesiąt lub kilkaset Mbit/s - taka polityka może "zatkać" nam maszynę.
Jest na to sposób.
TaaaaDAaaaaaa - **IPSet** (http://ipset.netfilter.org/)
Jest to narzędzie pozwalające nam użyć tablic (umiejscowionych w kernel-space) wypełnionych danymi. Następnie całość wykorzystać w naszych regułach iptables.
== Typy struktur i tablic w IPSet. ==
* ipmap - przechowuje adresy IP (max 65535), tworząc podajemy klasę lub przedział adresów
* macimap - przechowuje adresy IP + adresy mac - tworzymy tak jak ipmap
* portmap - przechowujemy w niej porty bądź zestawy portów
* iphash - przechowuje adresy IP, ale w odróżnieniu od ipmap jest to dynamiczna tablica hashowa
* nethash - "hash" zawierający maski sieci (CIDR)
* ipporthash - "hash" dla pary : adres IP + port
* ipportiphash - "hash" dla tripletu: adres IP + port + adres IP
* ipportnethash - "hash" dla tripletu: adres IP + port + maska sieci (CIDR)
* iptree - drzewo adresów IP (opcjonalnie możemy podać czas przechowywania wpisu w drzewie)
* iptreemap - podobnie do iptree używa drzew do przechowywania jednak ostatni oktet adresu zapisany jest za pomocą mapy bitowej
* setlist - lista w której trzymamy inne "sety"
== Używamy IPSet ==
Dla powyższego przykładu możemy użyć np. ipshash.
* ładujemy moduł
modprobe ip_set_iphash
* tworzymy nasz set o nazwie np. "httpclients"
ipset -N httpclients iphash
* Super, mamy nasz "set", wypełnijmy go teraz danymi.
ipset -A httpclients 192.168.0.2
...
ipset -A httpclients 10.0.0.2
...
ipset -A httpclients 123.123.123.1
* całość wykorzystujemy w naszym łańcuchu iptables
iptables -A FORWARD -m set --match-set httpclients -m state --state NEW -m comment --comment "Klienci z dostepem do http" -j do-http
Prosto, szybko, przejrzyście.
Wystarczającą dokumentację można znaleźć w man-ie bądź na http://ipset.netfilter.org/