miércoles, 2 de octubre de 2013

Bloquear dominios https (ej.: facebook)

Hola Gente, no sabía que tema usar para mi primera entrada, pero bueno, decidí hacerlo sobre uno de los trabajos mas recientes que he realizado, y es bloquear dominios por IP (más exactamente facebook jejejeje).
Hay que tener en cuenta que facebook.com usa tanto http como https, por tanto, hay que tener una serie de elementos en cuenta para que el bloqueo funcione.
Bueno, ya se sabe que facebook cuando se usa comun y silvestre (por http) va por el puerto 80 tcp igual que casi toooodas las paginas en Internet, tenemos varias opciones para manejar el bloqueo:
OUTPUT en caso de no usar proxy (ie.: squid).
FORWARD en caso de usar proxy (ie. squid)
O podemos hacer marcado en mangle y luego hacer DROP (eliminar paquetes sin más), REDIRECT (Util para mostrar un lindo portal que diga que hemos bloqueado el sitio y que hay que ponerse a laburar), o REJECT (Rechazar el paquete pero “dando aviso”)
En el caso del httpS, tenemos las siguientes opciones:
FORWARD en caso que se desee usar REJECT.
O también hacerlo en mangle en caso tal que solo deseemos hacer DROP.
Como han visto esto está lleno de opciones, por lo tanto hay que tomar decisiones, una de las más grandes con que me estrellé fue:

"usar --algo o no usar --algo, esa es la cuestión…"

--algo puede ser usado para "buscar" strings en iptables sin embargo esto acarrea un uso un poco mayor de recursos

Pero na!, al fin y al cabo decidí usar un bloqueo por IP basándome en los datos que arrojaba el comando dig +short facebook.com, la lista de IPs la encuentran en este archivo: http://goo.gl/tDZfsC
Esta lista de direcciones las podemos guardar en un archivo en el servidor con el nombre facebook.lst, y no me digan que se las ordene (y es que me ha dado tremenda pereza usar un simple sort XD)
Continuando con nuestra pequeña guia, ahora solo falta usar esa lista de IPs para bloquear facebook, una opcion es usar las lineas de iptables que describo a continuación cambiando la variable “${address}” por cada una de las IPs que les he dado anteriormente, otra opcion es usar el bucle que he preparado (while), así nos ahorramos tiempo:
Para el http (marcando en mangle para luego redirigir a una página dando aviso del bloqueo):
while read address; do
 iptables -t mangle -I PREROUTING -p tcp --dport 80 -d ${address}/32 -j MARK --set-mark 99
done < facebook.lst
Suponiendo que el portal es una página en el puerto 888 de nuestro servidor (192.168.0.1:888):
iptables -t nat -I PREROUTING -m mark --mark 99 -p tcp --dport 80 -j DNAT --to-destination 192.168.0.1:888
Si no quieren usar marcado o solo quieren simplemente bloquearlo sin más ni más pueden usar:

En OUTPUT:
while read address; do
 iptables -I OUTPUT -p tcp --dport 80 -d ${address}/32 -j DROP
done < facebook.lst

En FORWARD:
while read address; do
 iptables -I FORWARD -i eth0 -p tcp --dport 80 -d ${address}/32 -j DROP
done < facebook.lst

Ahora la parte del httpS
Cuando se usa DROP para httpS el navegador quedará “cargando…” lo cual puede llegar a confundir a más de uno, para evitar esto, podemos usar REJECT, pero el problema está dado en que REJECT consume un poquitín más de recursos que DROP.
while read address; do
 iptables -I FORWARD -p tcp --dport 443 -m state --state NEW,RELATED,ESTABLISHED -d ${address}/32 -j REJECT --reject-with tcp-reset
done < facebook.lst
Notese que en este caso usé NEW, RELATED, ESTABLISHED, esto "cortará" las sesiones establecidas en dicho sitio mediante httpS. Bien, creo que esto es todo por ahora, espero les sea útil.