PeerGuardian w oparciu o ipset
Kategoria: Artykuły, etykiety: peerguardian, iptables, ipset
Dodany: 2013-12-15 03:34
(zmodyfikowany: 2014-02-20 09:45)
Przez: morfik
Wyświetleń: 8979
Wiele klientów torrenta umożliwia ładowanie zewnętrznej listy z zakresami adresów ip i ta lista ma służyć jako swego rodzaju filtr połączeń chroniący nas przed różnego rodzaju organizacjami, które mogą zbierać i przetwarzać informacje na temat naszego ip i tego co porabia w sieci p2p. Oczywiście, kwestia czy korzystać z takiego typu rozwiązania jest bardzo dyskusyjna i wiele osób jest zdania, że to tak naprawdę w niczym nie pomoże, a wręcz może nawet przyczynić się do samounicestwienia sieci p2p -- jest duże prawdopodobieństwo, że na takiej liście znajdują się adresy, które nic złego nie robią. Np. moje ip figuruje na trzech czy czterech blacklistach i co ja mogę z tym zrobić? Dzielę ip z paroma set ludźmi i prawdopodobieństwo, że jest tam ktoś kto nie umie obsługiwać kmpa jest bliskie 100% i może ja nic nie robię złego, to i tak zostaję wciągnięty na listę, a jeśli taki wpis się zaaplikuje np. w qbittorrencie, to do komunikacji z takim ip już nie dojdzie. W sumie to te wszystkie organizacje antypiracie mogłyby poczekać, aż sieć się sama zniszczy przez tego typu rozwiązania.
Także jak widać taki filter może czasem przynieść więcej szkody niż pożytku, zwłaszcza gdy się go używa lekkomyślnie, czyli na zasadzie, że ten blokuje więcej adresów, to musi być lepszy. Poniżej opiszę wykorzystanie rozszerzenia ipset, przy którego pomocy w prosty sposób zostanie zablokowany szereg klas adresów. Całość raczej nie skupia się na implementacji filtra przy pomocy ipset, to tylko przykład do czego ipset może posłużyć, a że ja nie umiem teoretycznie pisać, to muszę na przykładach.
Nie obejdzie się bez instalacji dodatkowych pakietów. Pakiet ipset jest wymagany, reszta jest opcjonalna w zależności od tego z jakiej funkcjonalności chcemy korzystać:
# aptitude install ipset gawk xtables-addons-common xtables-addons-dkms iptables-persistent
Po zainstalowaniu pakietów xtables-addons-common i xtables-addons-dkms będziemy mieć dostęp do CELu STEAL w iptables. On działa tak samo jak DROP, z tym, że, jak piszą w manualu, "Like the DROP target, but does not throw an error like DROP when used in the OUTPUT chain." Nie mam pojęcia jak się zachowuje DROP, bo dopiero co się uczę, także nie wiem na czym polega ta różnica, w każdym razie, jak chce się mieć STEAL, to trzeba doinstalować ten pakiet. xD
Z kolei pakiet iptables-persistent odpowiada za prosty skrypt iptables ładujący reguły na starcie systemu. Zawsze można sobie stworzyć własny skrypt i dodać go do autostartu ale jak ktoś jest leniwy, to może skorzystać z tego rozwiązania. Konfiguracja iptables jest przechowywana w /etc/iptables/ w plikach rules.v4 oraz rules.v6. Raczej nazw nie trzeba wyjaśniać. Musimy jeszcze stworzyć sobie katalog, w którym będziemy trzymać własne listy z adresami ip:
# mkdir /etc/peerblock/
W założeniu projektu jest by listy były uaktualniane raz na dzień oraz ładowane przy starcie systemu automatycznie. Problem w tym, że reguły iptables będą opierać się na ipsecie, a konkretnie na zdefiniowanych setach adresów ip i bez nich skrypt iptables wyrzuci błąd i filter się nie odpali, co się przełoży na brak filtrowania adresów ip. Żeby to ogarnąć trzeba zmienić kolejność uruchamiania usług przy starcie systemu. Musimy napisać skrypt tworzący sety i ładujący do nich zakresy ip i ten skrypt musi się wykonać zanim zostaną załadowane reguły iptables. Zatem tworzymy skrypt /etc/init.d/peerblock . Nie jestem może jakimś mistrzem w pisaniu skryptów startowych ale naskrobałem coś takiego:
### BEGIN INIT INFO
# Provides: peerblock
# Required-Start: mountkernfs $local_fs
# Required-Stop: $local_fs
# Should-Start:
# Should-Stop:
# Default-Start: S
# Default-Stop: 0 6
# X-Start-Before:
# X-Stop-After:
# Short-Description: ipset lists
# Description: ipset lists
### END INIT INFO
SCRIPTNAME="peerblock"
BT_LEVEL1="bt_level1"
BT_SPYWARE="bt_spyware"
BT_WEBEXPLOIT="bt_webexploit"
WHITELIST="whitelist"
load_bt_level1()
{
echo "Tworzenie seta $BT_LEVEL1 w ipset..."
ipset create $BT_LEVEL1 hash:net family inet maxelem 290000
echo "aplikowanie listy $BT_LEVEL1..."
cat /etc/peerblock/$BT_LEVEL1.gz |
gunzip |
cut -d: -f2 |
grep -E "^[-0-9.]+$" |
gawk '{print "add bt_level1 "$1}' |
ipset restore -exist;
}
flush_bt_level1()
{
ipset flush $BT_LEVEL1
ipset destroy $BT_LEVEL1
}
load_bt_spyware()
{
echo "Tworzenie seta $BT_SPYWARE w ipset..."
ipset create $BT_SPYWARE hash:net family inet maxelem 4000
echo "aplikowanie listy $BT_SPYWARE..."
cat /etc/peerblock/$BT_SPYWARE.gz |
gunzip |
cut -d: -f2 |
grep -E "^[-0-9.]+$" |
gawk '{print "add bt_spyware "$1}' |
ipset restore -exist;
}
flush_bt_spyware()
{
ipset flush $BT_SPYWARE
ipset destroy $BT_SPYWARE
}
load_bt_webexploit()
{
echo "Tworzenie seta $BT_WEBEXPLOIT w ipset..."
ipset create $BT_WEBEXPLOIT hash:net family inet maxelem 2000
echo "aplikowanie listy $BT_WEBEXPLOIT..."
cat /etc/peerblock/$BT_WEBEXPLOIT.gz |
gunzip |
cut -d: -f2 |
grep -E "^[-0-9.]+$" |
gawk '{print "add bt_webexploit "$1}' |
ipset restore -exist;
}
flush_bt_webexploit()
{
ipset flush $BT_WEBEXPLOIT
ipset destroy $BT_WEBEXPLOIT
}
load_whitelist()
{
echo "Tworzenie seta $WHITELIST w ipset..."
ipset create $WHITELIST hash:net family inet maxelem 50
echo "aplikowanie listy $WHITELIST..."
cat /etc/peerblock/$WHITELIST |
gawk '{print "add whitelist "$1}' |
ipset restore -exist;
}
flush_whitelist()
{
ipset flush $WHITELIST
ipset destroy $WHITELIST
}
case "$1" in
start)
load_bt_level1 && load_bt_spyware && load_bt_webexploit && load_whitelist || exit 1
;;
stop)
flush_bt_level1 && flush_bt_spyware && flush_bt_webexploit && flush_whitelist || exit 1
;;
force-reload|restart)
flush_bt_level1 && flush_bt_spyware && flush_bt_webexploit && flush_whitelist && sleep 2
load_bt_level1 && load_bt_spyware && load_bt_webexploit && load_whitelist || exit 1
;;
*)
echo "Usage: $SCRIPTNAME {start|stop|restart}"
exit 1
;;
esac
exit 0
Trzeba także wyedytować /etc/init.d/iptables-persistent zmieniając mu nagłówek. Ale zanim to zrobimy, musimy pierw usunąć skrypt z autostartu, czyli wywalić linki w katalogach /etc/rc*.d . Można to zrobić albo ręcznie albo przy pomocy update-rc.d:
# update-rc.d iptables-persistent remove
# ls -al /etc/rc*.d/ | grep -i iptables
Jeśli ls nie zwróci wyniku, znaczy, że linki zostały usunięte. Edytujemy teraz nagłówek skryptu /etc/init.d/iptables-persistent :
### BEGIN INIT INFO
# Provides: iptables-persistent
# Required-Start: mountkernfs $local_fs
# Required-Stop: $local_fs
# Should-Start: peerblock
# Should-Stop: peerblock
# Default-Start: S
# Default-Stop: 0 6
# X-Start-Before:
# X-Stop-After:
# Short-Description: Set up iptables rules
# Description: Loads/saves current iptables rules from/to /etc/iptables
# to provide a persistent rule set during boot time
### END INIT INFO
Dopisać w nim trzeba Should-Start: peerblock oraz Should-Stop: peerblock . Should-Start daje pierwszeństwo na wykonanie się skryptom w tej dyrektywie. Natomiast Should-Stop wywoła skrypt przed tymi zdefiniowanymi w nim. Innymi słowy, by iptables-persistent wystartował potrzebny jest start peerblocka, a przy zamykaniu systemu iptables-persistent się wykona przed peerblockiem. Można by oczywiście dodać to w Required-Start/Stop ale wtedy przy braku skryptu peerblock, ten skrypt się nie odpali i zgłosi błąd. Should-Start/Stop jest bezpieczny i w przypadku nawet braku skryptu peerblock, ten skrypt zostanie wykonany. Z kolei, to co widnieje tutaj jako peerblock zostało wzięte ze stworzonego przez nas skryptu, z pola Provides:. Te dwie nazwy muszą do siebie pasować, to na ich podstawie system określa, który skrypt ma jako pierwszy wystartować.
By wszystko działało tak jak tego oczekujemy, czyli by filtr został utworzony przed uruchomieniem sieci, trzeba wyedytować jeszcze plik /etc/init.d/networking . I tak jak w przypadku iptables-persistent , trzeba pierw usunąć dowiązania do tego skryptu przy pomocy update-rc.d . Gdy już to zrobimy, edytujemy mu nagłówek:
### BEGIN INIT INFO
# Provides: networking ifupdown
# Required-Start: mountkernfs $local_fs urandom
# Required-Stop: $local_fs
# Should-Start: peerblock iptables-persistent
# Should-Stop: peerblock iptables-persistent
# Default-Start: S
# Default-Stop: 0 6
# Short-Description: Raise network interfaces.
# Description: Prepare /run/network directory, ifstate file and raise network interfaces, or take them down.
### END INIT INFO
Dodajemy teraz skrypty do autostartu:
# update-rc.d iptables-persistent defaults
# update-rc.d peerblock defaults
# update-rc.d networking defaults
I sprawdzamy, czy linki zostały utworzone:
# ls -al /etc/rc{0,6}.d/ | grep -i peer
lrwxrwxrwx 1 root root 19 Dec 13 07:07 K09peerblock -> ../init.d/peerblock*
lrwxrwxrwx 1 root root 19 Dec 13 07:07 K09peerblock -> ../init.d/peerblock*
# ls -al /etc/rc{0,6}.d/ | grep -i iptables
lrwxrwxrwx 1 root root 29 Dec 13 07:07 K08iptables-persistent -> ../init.d/iptables-persistent*
lrwxrwxrwx 1 root root 29 Dec 13 07:07 K08iptables-persistent -> ../init.d/iptables-persistent*
# ls -al /etc/rc{0,6}.d/ | grep -i network
lrwxrwxrwx 1 root root 20 Dec 13 07:07 K07networking -> ../init.d/networking*
lrwxrwxrwx 1 root root 20 Dec 13 07:07 K07networking -> ../init.d/networking*
# ls -al /etc/rcS.d/ | grep -i peer
lrwxrwxrwx 1 root root 19 Dec 13 07:07 S14peerblock -> ../init.d/peerblock*
# ls -al /etc/rcS.d/ | grep -i iptables
lrwxrwxrwx 1 root root 29 Dec 13 07:07 S15iptables-persistent -> ../init.d/iptables-persistent*
# ls -al /etc/rcS.d/ | grep -i network
lrwxrwxrwx 1 root root 20 Dec 13 07:07 S16networking -> ../init.d/networking*
Warto zwrócić uwagę na numerki przy nazwach: peerblock ma S14 , iptables-persistent ma S15 , networking ma S16, czyli startują w odpowiedniej kolejności. A patrząc po cyfrach przy literze K, również kolejność wykonywania skryptów przy zamykaniu systemu jest taka jak być powinna.
update-rc.d działa automatycznie na podstawie zdefiniowanych nagłówków. Czasami jednak trzeba ręcznie dostosować wywoływanie skryptów. Nie da się tego zrobić przy pomocy update-rc.d ale można skorzystać z graficznego bum albo też i konsolowego sysv-rc-conf . W każdym razie zostawiamy jak jest i przechodzimy do dalszej części konfiguracji filtra.
Mamy co prawda skrypt ładowany przy starcie systemu ale ten skrypt nie pobiera list, on je tylko ładuje do ipseta. Generalnie ku temu jest kilka powodów: pierwszym jest oczywiście spowolnienie startu systemu, kolejnym powodem może być brak sieci. Jak nie patrzeć, sieć zostanie dopiero uruchomiona jak listy zostaną zaaplikowane, czyli muszą już istnieć na dysku. Najlepszym wyjściem w tej sytuacji jest rozdzielenie kwestii pobierania i aplikowania list. Listy, jak już napisałem wcześniej, będą aktualizowane co dzień. Dlatego najlepiej po prostu obarczyć tym zadaniem crona i z plików, które on stworzy, ładować adresy ip do ipseta.
Tworzymy zatem kolejny skrypt /etc/cron.daily/peerblock_list :
#!/bin/bash
BT_LEVEL1="bt_level1"
BT_SPYWARE="bt_spyware"
BT_WEBEXPLOIT="bt_webexploit"
echo "pozyskiwanie listy $BT_LEVEL1..."
curl -L "http://list.iblocklist.com/?list=bt_level1&fileformat=p2p&archiveformat=gz" > /etc/peerblock/$BT_LEVEL1.gz
echo "pozyskiwanie listy $BT_SPYWARE..."
curl -L "http://list.iblocklist.com/?list=bt_spyware&fileformat=p2p&archiveformat=gz" > /etc/peerblock/$BT_SPYWARE.gz
echo "pozyskiwanie listy $BT_WEBEXPLOIT..."
curl -L "http://list.iblocklist.com/?list=ghlzqtqxnzctvvajwwag&fileformat=p2p&archiveformat=gz" > /etc/peerblock/$BT_WEBEXPLOIT.gz
Skrypt ten pobiera listy z http://list.iblocklist.com i zapisuje je w /etc/peerblock/ Tych list jest tam oczywiście więcej i można sobie dowolnie wybrać. Jak widać sam skrypt jest utworzony w cron.daily . By skrypt się wykonywał codziennie wystarczy go tam umieścić, trzeba tylko przypilnować by skrypt miał prawa do wykonywania. Druga sprawa dotyczy tego kiedy te skrypty się uruchamiają. Można to podejrzeć przez plik /etc/crontab :
# cat /etc/crontab
# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
# m h dom mon dow user command
17 * * * * root cd / && run-parts --report /etc/cron.hourly
25 19 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 19 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 19 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
#
Domyślnie to tam była chyba 6 rano, ja sobie zmieniłem to na 19.
Mamy zainstalowaną bazę, teraz przyszła kolej na załadowanie reguł do ipseta oraz konfigurację iptables.
Powrócę może do tego skryptu startowego i wykroję z niego interesujący nas kawałek by pokazać na jakiej zasadzie będzie się odbywać. Interesują nas te dwie funkcje:
load_bt_level1()
{
echo "Tworzenie seta $BT_LEVEL1 w ipset..."
ipset create $BT_LEVEL1 hash:net family inet maxelem 290000
echo "aplikowanie listy $BT_LEVEL1..."
cat /etc/peerblock/$BT_LEVEL1.gz |
gunzip |
cut -d: -f2 |
grep -E "^[-0-9.]+$" |
gawk '{print "add bt_level1 "$1}' |
ipset restore -exist;
}
flush_bt_level1()
{
ipset flush $BT_LEVEL1
ipset destroy $BT_LEVEL1
}
Druga z nich opróżnia i niszczy set. Pierwsza zaś tworzy set o długości 290000 wpisów. Jest to trochę więcej niż ma lista. Z tym, że im więcej się stworzy pustych wpisów tym więcej one zmarnują miejsca. Choć przy długości 290000, jest to koło 3,5MiB zjadanego RAMu. To i tak sporo lepiej w porównaniu do qbittorrenta, który za obsługę tej samej listy chciał 200MiB. Po stworzeniu seta i po tym jak cron pobierze listę adresów i zapisze ją w /etc/peerblock/bt_level1.gz , plik jest wypakowywany, z tym, że format listy nie jest do przyjęcia przez ipset. Wpisy w liście wyglądają jak poniżej:
# List distributed by iblocklist.com
China Internet Information Center (CNNIC):1.2.4.0-1.2.4.255
China Internet Information Center (CNNIC):1.2.8.0-1.2.8.255
SMSHoax FakeAV Fraud Trojan:1.9.75.8-1.9.75.8
SMSHoax FakeAV Fraud Trojan:1.9.189.65-1.9.189.65
...
...
...
A trzeba je przeformatować do postaci:
add bt_level1 2.115.176.190
add bt_level1 62.52.2.0/26
add bt_level1 212.174.156.0/23
...
...
...
cut -d: -f2 dzieli linijki po znaku dwukropka i części powstałe w taki sposób oznacza kolejno 1,2, etc. W tym przypadku, jako, że linijka ma tylko jeden dwukropek, zostanie podzielona na 2 części oraz zostanie wycięty kawałek od dwukropka do końca wiersza. Z kolei grep -E "^[-0-9.]+$" nie wiem co dokładnie znaczy ale chyba wyciąga z wyniku wpisy, które mają cyfry, kropki i znak minusa powtórzone co najmniej raz. Czyli wynik w postaci:
62.27.97.232-62.27.97.235
Zakresy ip, takie jak widoczne powyżej, zostaną automatycznie przepisane przez ipset z uwzględnieniem maski podsieci. Jeśli kogoś ciekawi jak zostanie rozpisany przykładowy zakres z uwzględnieniem maski może odpalić ipcalc:
$ ipcalc 62.27.97.232-62.27.97.235
deaggregate 62.27.97.232 - 62.27.97.235
62.27.97.232/30
Można tez i w drugą stronę, co nam pokaże jakie adresy faktycznie się kryją pod maską:
$ ipcalc 62.27.97.232/30
Address: 62.27.97.232 00111110.00011011.01100001.111010 00
Netmask: 255.255.255.252 = 30 11111111.11111111.11111111.111111 00
Wildcard: 0.0.0.3 00000000.00000000.00000000.000000 11
=>
Network: 62.27.97.232/30 00111110.00011011.01100001.111010 00
HostMin: 62.27.97.233 00111110.00011011.01100001.111010 01
HostMax: 62.27.97.234 00111110.00011011.01100001.111010 10
Broadcast: 62.27.97.235 00111110.00011011.01100001.111010 11
Hosts/Net: 2 Class A
W każdym razie po wyodrębnieniu zakresu trzeba jeszcze do niego dodać na początku frazę add bt_level1 przy pomocy gawk '{print "add bt_level1 "$1}' i mamy gotową listę, która może zostać zaaplikowana w ipsecie.
By móc zniszczyć set, trzeba pierw usunąć reguły z iptables, w przeciwnym razie dostaniemy taki komunikat:
# ipset destroy bt_level1
ipset v6.20.1: Set cannot be destroyed: it is in use by a kernel component
Dlatego właśnie było trochę zamieszania z tymi skryptami startowymi.
Ja w powyższy sposób zaimplementowałem sobie 3 listy z adresami ip. Ale jest jeszcze jedna, którą warto mieć -- to lista, z adresami, którym udzielimy dostępu do naszej maszyny. Jak już wspomniałem na początku, te filtry mogą i z pewnością będą blokować sporo adresów, które są niewinne i dlatego przydałoby się mieć już gotowe rozwiązanie na wypadek gdy ktoś z naszych znajomych trafi na taką listę.
Tworzymy zatem plik /etc/peerblock/whitelist . Ja póki co miałem drobne problemy z pobieraniem pakietów z ftp://ftp.deb-multimedia.org . Jako, że ip domeny to 91.121.10.104, to można je dodać sobie do tego pliku:
# cat /etc/peerblock/whitelist
91.121.10.104
...
...
...
Przyszła pora na konfigurację iptables. Reguły dla ipv4 są trzymane w /etc/iptables/rules.v4 . Edytujemy ten plik i wklejamy do niego poniższą zawartość:
*raw
:PREROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A PREROUTING -p tcp -m set --match-set whitelist src -j ACCEPT
-A OUTPUT -p tcp -m set --match-set whitelist dst -j ACCEPT
-A PREROUTING -p tcp -m multiport ! --sports 80,443 -m set --match-set bt_level1 src -j STEAL
-A PREROUTING -p udp -m multiport ! --sports 80,443 -m set --match-set bt_level1 src -j STEAL
-A OUTPUT -p tcp -m multiport ! --dports 80,443 -m set --match-set bt_level1 dst -j STEAL
-A OUTPUT -p udp -m multiport ! --dports 80,443 -m set --match-set bt_level1 dst -j STEAL
-A PREROUTING -m set --match-set bt_spyware src -j STEAL
-A OUTPUT -m set --match-set bt_spyware dst -j STEAL
-A PREROUTING -m set --match-set bt_webexploit src -j STEAL
-A OUTPUT -m set --match-set bt_webexploit dst -j STEAL
COMMIT
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -i eth0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -i tun0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -m state --state INVALID -j DROP
-A INPUT -p tcp -j REJECT --reject-with tcp-reset
-A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable
-A INPUT -j REJECT --reject-with icmp-proto-unreachable
-A OUTPUT -m state --state INVALID -j DROP
COMMIT
UWAGA:po aktualizacji pakietów od xtables:
[UPGRADE] xtables-addons-common:amd64 2.3-1 -> 2.4-1
[UPGRADE] xtables-addons-dkms:amd64 2.3-1 -> 2.4-1
cel -j STEAL nie jest już wspierany. Zamiast niego można posłużyć się -j DROP .
W tabeli filter jest mój standardowy filtr pakietów. Zaś ten oparty o ipset został zrzucony do tabeli raw. Generalnie pakiety przez iptables przechodzą poniższymi trasami:
Pakiet stworzony na naszej maszynie:
- łańcuch OUTPUT tabeli raw
- łańcuch OUTPUT tabeli mangle
- łańcuch OUTPUT tabeli nat (tylko nowe połączenia)
- łańcuch OUTPUT tabeli filter
Pakiet przeznaczony dla naszej maszyny:
- łańcuch PREROUTING tabeli raw
- łańcuch INPUT tabeli mangle
- łańcuch INPUT tabeli filter
Jak widać z powyższej rozpiski, pakiety pierw trafiają do tabeli raw i tam można je wstępnie odfiltrować. Posiada ona dwa łańcuchy, po jednym dla pakietów przychodzących i wychodzących. Teraz wystarczy zrozumieć regułki zapisane w pliku powyżej.
Kluczowa sprawa to wywołanie modułu przy pomocy parametru -m set i dopasowanie pakietów do odpowiedniego filtra w ipsecie przy pomocy --match-set whitelist. Ja mam 4 filtry, po 1 regule dla każdego, w każdym łańcuchu, łącznie daje 8 wpisów. Białą listę dajemy na początek, tak by pakiety, które by zostały zablokowane przez przez 3 pozostałe filtry, były przepuszczane bez większego problemu i wędrowały do tabeli filter. Druga lista (bt_level1 ) jest to typowa lista p2p i generalnie lepiej jest jej nie używać na portach 80 i 443, czyli na stronach www, bo ona nawet googla blokuje. Najlepiej ustawić sobie zakres portów, na których klient bittorrenta może dokonywać połączeń, u mnie qbittorrent ma zabronione łączenie się na porty poniżej numeru 1024 i na dobrą sprawę ustawiłem mu zakres 2k portów od 20-22k. I praktycznie można by sprecyzować ten zakres + tam parę innych domyślnych dla bittorenta w regule iptables i to by wystarczyło ale w sumie jeśli nie spodziewamy się wizyt na innych portach, to można i taką konfigurację zostawić. Pozostałe dwa filtry są już użyte bardziej restrykcyjnie ale to dlatego, że zakresów ip jest tam relatywnie niewielki i w ciągu dnia mi się trafia 20-30 pakietów, które zostają zablokowane w tych listach. Różnica w stosunku do tego dużego filtra polega na tym, że te dwa mniejsze filtrują ruch również na http i https.
Jeśli pakiety zostaną zablokowane z jakiegoś ip, a my nie wiemy z jakiego. Możemy włączyć logowanie dodając do regułek iptables poniższą linijkę:
-A OUTPUT -p tcp -m multiport ! --dports 80,443 -m set --match-set bt_level1 dst -j LOG -m limit --limit 10/m --log-level 4 --log-prefix "*** BT_LEVEL1 *** "
Oczywiście to tylko przykład logowania, prawdopodobnie trzeba będzie go dostosować. Jedna rzecz o której trzeba pamiętać to by dodać go przed faktyczną regułą filtrującą, w przeciwnym razie nie przejdą przez nią pakiety i nie zostaną zalogowane.
I to w sumie wszystko, testowałem tego peerguardiana opartego o ipset i iptables i działa. W każdym razie, jeśli kogoś przeraża tego typu działanie, może pokusić się o prawie gotowe rozwiązanie: https://sourceforge.net/projects/peerguardian/. Wymaga tylko skompilowania i instalacji. W każdym razie posiada gui i zjada więcej RAMu niż ipset.
BTW, można stworzyć jeden plik filtru z uwzględnieniem reguł iptables oraz setów ipset i odpowiednio je wywołać zamiast robić to w dwóch osobnych plikach.