Blokowanie Facebooka, Twittera i innych serwisów społecznościowych

Poniżej zostanie zaprezentowany sposób na blokowanie szeregu adresów IP przy pomocy filtru pakietów iptables. Zostanie tutaj także użyty ipset, który to będzie zawierał niepożądane przez nas klasy adresów. Tego typu mechanizm można wykorzystać do blokowania np. facebooka czy też innych serwisów społecznościowych o ile posiadamy informacje na temat adresów ip, na których te serwisy działają. Dodatkowo, jeśli mamy router z większą ilością pamięci RAM/flash i korzystamy przy tym z jakiegoś klienta torrent na routerze, np transmission, możemy załadować blacklisty adresów IP bezpośrednio do pamięci i przy pomocy iptables w prosty sposób zablokować niegrzecznych użytkowników sieci p2p.
Musimy się pierw zaopatrzyć w odpowiednie pakiety:

# opkg update
# opkg install ipset kmod-ipt-ipset

Po instalacji trzeba zresetować router, bo niektóre potrzebne moduły nie zostaną od tak załadowane.

# reboot

Listy w ipsecie tworzymy w następujący sposób:

# ipset create facebook hash:net family inet maxelem 5000

Opcja maxelem definiuje ile elementów może się znajdować w secie. Zależność jest prosta im ten parametr ma większą wartość, tym więcej pamięci operacyjnej dany set konsumuje, dlatego też trzeba go dobierać ostrożnie.
Załóżmy teraz, że użytkownicy naszej sieci zbyt często przesiadują na fejsie (lub dowolnych innych stronach) i chcemy im trochę popsuć zabawę. Na necie można znaleźć adresy IP używane przez facebooka. Mając adresy, możemy zacząć je dodawać do seta:

root@the-mountain:~# ipset add facebook 66.220.144.0-66.220.159.255
root@the-mountain:~# ipset add facebook 69.63.176.0-69.63.191.255
root@the-mountain:~# ipset add facebook 69.171.224.0-69.171.255.255
root@the-mountain:~# ipset add facebook 204.15.20.0-204.15.23.255
root@the-mountain:~# ipset add facebook 65.201.208.24/29
root@the-mountain:~# ipset add facebook 65.204.104.128/28
root@the-mountain:~# ipset add facebook 66.92.180.48/28
root@the-mountain:~# ipset add facebook 66.93.78.176/29
root@the-mountain:~# ipset add facebook 66.199.37.136/29
root@the-mountain:~# ipset add facebook 67.200.105.48/30
root@the-mountain:~# ipset add facebook 74.119.76.0/22
root@the-mountain:~# ipset add facebook 173.252.64.0/18
root@the-mountain:~# ipset add facebook 31.13.80.1-31.13.93.238

By zacząć blokować połączenia z powyższymi klasami adresów, dodajemy do naszego skryptu firewalla poniższe wpisy:

iptables -t raw -N ipset_in 
																		  
iptables -t raw -A PREROUTING -j ipset_in
iptables -t raw -A ipset_in -m set --match-set facebook src -j DROP

Od tej pory cała komunikacja z fejsem będzie niemożliwa, nie ważne co dana osoba spróbuje zrobić by się połączyć, nie uda jej się to, no chyba, że skorzysta z VPN.
By ten mechanizm był trwały, trzeba zapisać wzór listy wraz z jej adresami. Robimy to przez wydanie poniższego polecenia:

root@the-mountain:~# ipset save facebook
create facebook hash:net family inet hashsize 1024 maxelem 5000
add facebook 31.13.80.4/30
add facebook 31.13.81.0/24
add facebook 31.13.80.16/28
add facebook 66.92.180.48/28
add facebook 31.13.80.8/29
add facebook 31.13.93.192/27
add facebook 31.13.80.64/26
add facebook 65.201.208.24/29
add facebook 31.13.80.32/27
add facebook 204.15.20.0/22
add facebook 31.13.84.0/22
add facebook 65.204.104.128/28
add facebook 66.199.37.136/29
add facebook 31.13.80.128/25
add facebook 31.13.80.1
add facebook 31.13.82.0/23
add facebook 66.93.78.176/29
add facebook 31.13.93.232/30
add facebook 74.119.76.0/22
add facebook 31.13.93.0/25
add facebook 31.13.93.236/31
add facebook 173.252.64.0/18
add facebook 67.200.105.48/30
add facebook 69.171.224.0/19
add facebook 31.13.80.2/31
add facebook 31.13.92.0/24
add facebook 31.13.93.238
add facebook 31.13.93.128/26
add facebook 66.220.144.0/20
add facebook 31.13.93.224/29
add facebook 31.13.88.0/22
add facebook 69.63.176.0/20

Możemy także przekierować wyjście do pliku, z którego to set zostanie automatycznie utworzony, a adresy dodane przy starcie routera:

root@the-mountain:~# mkdir /etc/ipset/
root@the-mountain:~# ipset save facebook > /etc/ipset/facebook

Dopisujemy do naszego skryptu firewalla w bloku start() na samym początku poniższą linijkę:

ipset restore -exist -f /etc/ipset/facebook

Trzeba także pamiętać o dodaniu odpowiednich regułek w przypadku zatrzymywania skryptu, z tym, że je trzeba dodać na końcu bloku, a to z tego względu, że listy ipseta nie mogą zostać usunięte gdy operuje na nich iptables.

ipset flush faceboook &> /dev/null
ipset destroy faceboook &> /dev/null

Cały skrypt firewalla powinien się prezentować następująco:

#!/bin/sh /etc/rc.common
START=17
start() {
	ipset restore -exist -f /etc/ipset/facebook
	iptables -t raw -F
	iptables -t raw -X
	
	iptables -t raw -N ipset_in 
																			  
	iptables -t raw -A PREROUTING -j ipset_in
	iptables -t raw -A ipset_in -m set --match-set facebook src -j DROP	
	
	iptables -t filter -F
	iptables -t filter -X
	iptables -t filter -P INPUT DROP
	iptables -t filter -P FORWARD DROP
	iptables -t filter -P OUTPUT ACCEPT
	iptables -t filter -N tcp
	iptables -t filter -N udp
	iptables -t filter -N icmp_in
	iptables -t filter -N fw-interfaces
	iptables -t filter -N fw-open
	iptables -t filter -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
	iptables -t filter -A INPUT -m conntrack --ctstate INVALID -j DROP
	iptables -t filter -A INPUT -i lo -j ACCEPT
	iptables -t filter -A INPUT -p icmp -m conntrack --ctstate NEW -j icmp_in
	iptables -t filter -A INPUT -p udp -m conntrack --ctstate NEW -j udp
	iptables -t filter -A INPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -m conntrack --ctstate NEW -j tcp
	iptables -t filter -A INPUT -p tcp -j REJECT --reject-with tcp-reset
	iptables -t filter -A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable
	iptables -t filter -A INPUT -j REJECT --reject-with icmp-proto-unreachable
	iptables -t filter -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
	iptables -t filter -A FORWARD -m conntrack --ctstate INVALID -j DROP
	iptables -t filter -A FORWARD -m conntrack --ctstate NEW -j fw-interfaces 
	iptables -t filter -A FORWARD -m conntrack --ctstate NEW -j fw-open
	iptables -t filter -A FORWARD -j REJECT --reject-with icmp-host-unreachable
	iptables -t filter -A icmp_in -p icmp -i br-lan -s 192.168.1.0/24 -j ACCEPT
	
	iptables -t filter -A tcp -p tcp -i br-lan -s 192.168.1.0/24 -j ACCEPT
	
	iptables -t filter -A udp -p udp -i br-lan -s 192.168.1.0/24 -j ACCEPT
	iptables -t filter -A udp -p udp --sport 68 --dport 67 -s 0.0.0.0 -d 255.255.255.255 -j ACCEPT -m comment --comment "DHCP-broadcast"
	iptables -t filter -A udp -p udp --dport 68 -j ACCEPT -m comment --comment "Allow-DHCP-Renew"
	iptables -t filter -A fw-interfaces -i br-lan -s 192.168.1.0/24 -j ACCEPT
#	iptables -t filter -A fw-open -i eth0 -o br-lan -d 192.168.1.150 -p tcp --dport 22222 -j ACCEPT
#	iptables -t filter -A fw-open -i eth0 -o br-lan -d 192.168.1.150 -p udp --dport 22222 -j ACCEPT
#	iptables -t filter -A icmp_in -p icmp -i eth0 -j ACCEPT
#	iptables -t filter -A tcp -p tcp -i eth0 -m tcp --dport 22 -j ACCEPT
	iptables -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j SNAT --to-source 22.33.44.55
#	iptables -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j MASQUERADE
#	iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 22222 -j DNAT --to-destination 192.168.1.150
#	iptables -t nat -A PREROUTING -i eth0 -p udp --dport 22222 -j DNAT --to-destination 192.168.1.150
}
stop() {
	for TABLE in \
		"-t raw" \
		"-t mangle" \
		"-t filter" \
		"-t nat"
	do
		iptables $TABLE -F
		iptables $TABLE -X
	done
	iptables -t filter -N tcp
	iptables -t filter -N udp
	iptables -t filter -P INPUT DROP
	iptables -t filter -P FORWARD DROP
	iptables -t filter -A INPUT -i br-lan -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
	iptables -t filter -A INPUT -i lo -j ACCEPT
	iptables -t filter -A INPUT -i br-lan -p icmp -m conntrack --ctstate NEW -j ACCEPT
	iptables -t filter -A INPUT -i br-lan -p udp -m conntrack --ctstate NEW -j ACCEPT
	iptables -t filter -A INPUT -i br-lan -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -m conntrack --ctstate NEW -j ACCEPT
	iptables -t filter -A INPUT -p tcp -j REJECT --reject-with tcp-reset
	iptables -t filter -A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable
	iptables -t filter -A INPUT -j REJECT --reject-with icmp-proto-unreachable
	
	ipset flush facebook &> /dev/null
	ipset destroy facebook &> /dev/null
	
}

Samo tworzenie skryptu iptables zostało opisane w tym wątku.

Oczywiście ipset może także posłużyć jako filtr adresów w drugą stronę, tj. jeśli chcemy zezwolić naszej sieci na połączenia do określonych hostów, wtedy do listy ipseta dodajemy pożądane adresy i zmieniamy -j DROP na -j ACCEPT .