Packet Filter, otra gran opcion!

PF a la batalla!

Dentro del mundo Unix, hay varias formas de hacer lo mismo,
y considero yo, todo tiene su ámbito de aplicación, es decir, es poco inteligente poner Ubuntu (Desktop) como servidor, o un AIX como un Desktop.
Pues bien, si a OpenBSD nos referimos, su ámbito se acomoda muy bien entre los servidores/firewalls.

Packet Filter o pf para los amigos, es su prolijo y simple firewall.

- Como primer punto, podemos destacar, una interfaz que permite de manera simple centralizar las principales tareas.
La interfaz de usuario para manejar el firewall de OpenBSD es ‘pfctl’, desde el cual podremos habilitar / deshabilitar el firewall, cargar un archivo de configuración,
o listar las reglas según su tipo.
Para habilitar PF usamos:
#pfctl -e
para deshabilitar PF:
#pfctl  -d

Para cargar un archivo de configuración:
#pfctl -f /path/del/archivo

Para listar las reglas de filtrado:
#pfctl -sr
Para las reglas de nat:
#pfctl -sn
Y para ver las estadisticas:
#pfctl -si

Espectacular dirán, pero no me sirve de mucho todo esto, si no se como configurar las reglas (rules)!. Pues avancemos entonces!

- Como segunda característica y quizás la mas importante, es que la sintaxis es muy simple, y no por eso deja de ser potente.
Lleva mas tiempo comprender como usar el Sticky bit que el PF!
Par cargar las reglas, hay que escribirlas en un archivo y cargar el archivo como vimos un poco mas arriba.

Las reglas siguen una sentencia bien simple:

action [direction] [log] [quick] [on interface] [inet|inet6] [proto protocol] \
[from src_addr [port src_port]] [to dst_addr [port dst_port]] \
[flags tcp_flags] [state]

Donde action, puede ser pass o block, es evidente para que sirve cada uno.
Con direction especificamos si queremos matchear paquetes que entran o salen, por lo que usaremos in u out.
La opción log, hace que pf loguee los paquetes que matchean con dicho filtro.
Pasaremos por alto la opción quick por ahora, y veremos que es mas que obvio que con ‘on interface‘, podemos remplazarlo por ‘on pcn0‘ por ejemplo,
y matcheará solo los paquetes que entren o salgan (según hayamos definido en direction) sobre la interfaz definida.
Con inet6 definimos la regla para que matche paquetes sobre el IPv6,  en caso contrario (IPv4) usamos inet.
Como siempre, un buen firewall, nos permite seleccionar un mínimo de características sobre los paquetes que matchearemos, esto es:
Que protocolo es, de donde (ip y puerto) viene y a donde va (ip y puerto), y en el caso de los paquetes tcp, los flags activados.
Simplemente, entonces:

Seguido de proto escribiremos tcp, udp, icmp, icmp6 o cualquier protocolo en /etc/protocols (ej. proto tcp),
si queremos, podemos especificar la dirección de origen con from (ej. from 192.168.1.1),
adicionalmente podemos marcar de que puerto debe provenir el paquete, lo hago con port (ej. port 22),
para matchear los paquetes según a “donde va”, usamos to y port (ej. to 192.168.3.4 port 3218).

Antes de hablar de los flags tcp, quiero destacar una característica útil:
Cuando nos toca definir puertos, pf nos perfime definir rangos y comparaciones aritmeticas.

  • != (desigual)
  • < (menor que)
  • > (mas grande que)
  • <= (menor o igual)
  • >= (mayor o igual)
  • : ( rango inclusivo)

Por ejemplo (de paso repasamos):

pass in on pcn0 inet tcp from 192.168.1.1 to 192.168.1.2 port >= 1024
o bien
block out on pcn1 tcp to 10.10.10.3 port 20:30

Tcp flags:

Siendo que hoy en día, es muy común recibir escaneos remotos, es también muy común, querer filtrar dichos escaneos, los cuales llegan a ser interesante mente sofisticados en el protocolo TCP.
Anteponiendo ‘flag’, podremos especificar que flags activadas debe tener el paquete para que matchee. Se hace de la siguiente manera:
Primero ponemos las flags que buscamos que esten activas, seguidas de una barra “/”, y despúes las flags donde debe buscar, por ejemplo:
S/SA significa que busque el flag SYN activado solo entre los flags SYN y ACK. Para comprender esto, conviene que leas sobre escaneos aqui.

Aquí esta los distintos flags que se pueden usar.

  • F : FIN – Finish; end of session
  • S : SYN – Synchronize; indicates request to start session
  • R : RST – Reset; drop a connection
  • P : PUSH – Push; packet is sent immediately
  • A : ACK – Acknowledgement
  • U : URG – Urgent
  • E : ECE – Explicit Congestion Notification Echo
  • W : CWR – Congestion Window Reduced

Macros
Dentro del  archivo de configuración, se pueden definir ciertos “macros”.
Por ejemplo, si escribimos
int_ext = “pcn0″
creamos una constante.

O bien, podemos crear una lista:
puertos = “{ 21 22 23 443 }”
o bien
ip_denegadas = “{ 192.168.1.0/24, 10.0.0.1 }”

luego, para usarlas usaremos $puertos o $ip_denegadas.
Otra cosa, que resulta muy interesante, que el mismo PF nos permite el manejo de queueing ( o control de ancho de banda ), esto no lo veremos en este articulo, pero les dejo el link http://www.openbsd.org/faq/pf/queueing.html, y dicho sea de paso, este pequeño articulo es un “extracto” traducido de http://www.openbsd.org/faq/pf/index.html.

Conclusión:

PF es un potente firewall, que es muy simple de usar, y teniendo en cuenta que OpenBSD es seguramente el sistema operativo mas seguro, nos brinda un excelente entorno para transformar una pc en un firewall por excelencia.

IProute, el gran director II

En el primer artículo sobre IpRoute pudimos aproximarnos al uso cotidiano  y casero que le podemos dar a esta poderosa herramienta,
pero en esta ocasión vamos a avanzar sobre utilidades mas avanzadas.

IpRoute no solo centraliza la administración de la red en nuestro linux, si no que nos brinda herramientas que antes uno
no podía ni imaginar, sin pagar un alto costo por sistemas dedicados. Por ejemplo: Proxy ARP, control del ancho de banda, multicasting,.. y una de las cosas que mas me interesa es la posibilidad de trabajar con múltiples tablas de ruteo (balanceo de carga).

Tablas de Ruteo

Con IProute podemos manejar las distintas tablas de ruteo del kernel de linux.
Simplificando ideas, tener varias tablas de ruteo, nos permite acceder a distintas redes con el agregado de poder elegir de forma minuciosa (ya sea por dirección de destino, Type of service, scope, o interfaz de salida) la ruta a seguir de un determinado paquete (como adelanto, imaginate si pudieras usar el poder de matcheado de iptables, para marcar un paquete, el cual direccionaremos a la tabla de router que querramos! ).

Ejemplos de uso:
Tipico ejemplo, tengo dos conexiones a internet, una de 3mb con Fibertel y una de arnet de 1mb.
Atraz de Linux’sBox tengo un servidor de juegos, y una red de maquinas que acceden para navegar y usar msn y otra que se conecta a juegos online.
Objetivo: Distribuir las maquinas entre las 2 conexiones para que la red no se me sature.

Otro ejemplo común, es cuando tengo dos conexiones, y quiero balancear el uso de p2p en la red.

En mi caso hoy quiero utilizar estas herramientas para balancear trafico http entre dos proxyweb

Comenzando:

El kernel soporta 256 tablas de ruteo (de la 0 a la 255), lo que es generalmente, mas que suficiente.
Por defecto se le asigna el numero 255 a la tabla de ruteo local,  la cual en la mayoría de los casos no tocaremos, ya que esta contiene los broadcast y direcciones de las interfaces locales, esta tabla es la que manejan los ip address e ifconfig, para poder verla usamos: ip route show table local.

El número 254 se lo gano la tabla principal (main) donde esta alojadas las rutas que soliamos ver en un route -n y finalmente, siempre hay algo que debermos explicar en otro momento, y en este caso nos referimos a las tablas 253 (default) y 0 (llamada para unspect , sirve para manejar todas las tablas! :s )

Esta configuración esta guardada en /etc/iproute2/rt_tables#
# reserved values
#
255     local
254     main
253     default
0       unspec
#

Y es justamente en este archivo donde definiremos nuestras tablas personalizadas.
Como es costumbre en un sistema *nix-like, usamos nuestro editor de texto preferido y nos disponemos a editar este archivo,
donde colocaremos un ID y un ALIAS, el ID debe estar entre 1 y 252 ya que los otros valores están ocupados, el alias sera el nombre que le asignaremos
a la tabla para llamarla de una forma amigable.
Una vez editado nuestro archivo puede quedar algo asi:# reserved values
#
255     local
254     main
253     default
0       unspec
#
# Tablas personalizadas
#
#  Tabla para Red Arnet
1 arnet
#  Tabla para red Fibertel
2 fibertel

Simple no? si, por ahora es asi de simple.
Usando ip route show table arnet/fibertel , podemos observar que no hay nada dentro de las tablas.
Ahora bien, dentro de cada tabla, puede haber varios tipos de rutas, y estos son:

Unicast:
La mas común de todas las tablas, tan común, que cuando no sepamos de que tipo es una ruta, muy probablemente sea Unicast.
Este tipo de rutas, establece una gateway para una red.
Por ejemplo, cuando queremos llegar a la red 10.1.1.0/27 (ver subnetting) atravez de nuestro router (cuya ip es 192.168.1.1) usaremos:
ip route add 10.1.1.0/27 via 192.168.1.1
Y el ejemplo mas común es el de la ruta de ultima milla, ruta por defecto, puerta de enlace, o default gateway:
ip route add default gw 192.168.1.1
ó bien
ip route add 0.0.0.0/0 via 192.168.1.1
Broadcast:
Otra ruta muycomún. Esta tipo de ruta, solo se encuentra en la tabla local, y especifica una dirección de broadcast de una interfaz.
Para mirar esas rutas podemos usar:
ip route show type broadcast table local
Lo que nos mostrara solo las rutas tipo broadcast de la tabla local
Local:
Tan comunes como las broadcast, las rutas del tipo local, quienes pueden ser un poco complicadas de explicar por un concepto poco logico, para la forma de pensar humana, ya que, esta ruta, dice, para llegar a la dirección 10.0.0.1 parta de la interfaz eth1 y use 10.0.0.1 como dirección de origen.
que??
Si bueno, miremos esto:
Agregamos una dirección ipv4 a nuestra interfaz eth1
ip addr add 10.0.0.1 dev eth1
Veamos lo siguiente:
ip route sh type local table local
Veremos que automaticamente, se ha agregado la si siguiente linea:
10.0.0.1 dev eth1  proto kernel  scope host  src 10.0.0.1
Con esto, si hacemos un ping a dicha ip (10.0.0.1) funciona de 10, pero si la borramos (ip route del 10.0.0.1 dev eth1 table local),
veremos como el tonto de nuestro kernel no sabe como llegar!!!!
Entonces, este tipo de rutas, como dijimos, le dicen al kernel, que para llegar a la ip 10.0.0.1 user la interfaz eth1, con la dirección 10.0.0.1.
Volvamos a los tipos de rutas

nat:
Tipo de ruta utilizada cuando se crea NAT
unreachable:
Este tipo de rutas se generan automáticamente cuando se recibe un paquete ICMP unreachable.
prohibit:
Exactamente igual a unreachable pero con ICMP prohibit
blackhole:
Este tipo de ruta es similar a /dev/null, es decir, lo que matchea contra esta ruta, es descartado
throw:
Si blackhole es un  /dev/null throw es un archivo tipo pipe (fifo), es decir, cuando una conexión llega a matchear contra esta ruta, se envia a la conexión nuevamente a ser manejada por el proceso de selección de ruta normal, con un destino especifico.

Pues bien, teniendo una idea, de como crear rutas, y de como funcionan (siempre teniendo en cuenta el comando ip route get), podemos crear las rutas que necesitemos en nuestras tablas personalizadas, por ejemplo:
Hagamos un mini ejemplo de como conectarnos a dos proveedores

#Vale aclarar primero, que si no tenemos una interfaz para llegar a 10.0.0.2 habrá un error
#además estoy suponiendo que ya creaste las tablas arnet y fibertel en /etc/iproute2/rt_tables

#Ahora si insertamos una ruta por defecto en la tabla arnet
ip route add default via  10.0.0.2  dev eth1 table arnet
# y otra en la tabla fibertel
ip route add default via 192.168.5.1 dev eth2 table fibertel

Ahora bien, antes de seguir, para entender la siguiente linea, quizas necesites leer los articulos de NetFilter, para comprender que estamos haciendo.
iptables -t mangle -A OUTPUT  -p tcp –dport 80 -j MARK  –set-mark 1
iptables -t mangle -A OUTPUT  -p tcp –dport 1863  -j MARK  –set-mark 2

Con esto solo nos falta unas lineas mas,

ip rule add fwmark 1 table arnet
ip rule add fwmark 2 table fibertel

Analicemos esto un poco:
Al igual que con los otros objetos, podemos listar el contenido de la tabla rule con
ip rule list
nos mostrará algo asi:
Onix:~# ip rule ls
0:      from all lookup local
32766:  from all lookup main
32767:  from all lookup default

Estas reglas (rules) determinan la forma en que los paquetes ingresaran en una tabla u otra. Si ya te has familiarizado con el funcionamiento de tablas, podrás notar,
que en este caso, los paquetes entran primero en la tabla local, ya que de seguro, es la primera contra la cual matchearan (anteriormente explicamos su uso). Al salir de
esta tabla, pasaran a la tabla main, donde encontraran su destino.
Para entender de forma práctica el uso de ip rule, podemos ver una forma alternativa de hacer lo mismo que hicimos con ‘ip rule add fwmark……’:
ip rule add from 192.168.1.0/24 table arnet
Y con eso, diriamos que todo lo que venga de la red 192.168.1.0/24 pasa a ser controlado por la tabla arnet.
fwmark nos permite leer una marca (que asigno iptables, y que es solo de uso interno) a un determinado paquete, y según esa marca destinarlo a una tabla.

Ahora pensemos que el poder de matcheado de IPtables nos permitirá dirigir el tráfico de la forma que necesitemos.

Un resumen de todo:
Primero, definimos tablas de ruteos, a las cuales le asignamos un default gateway. De esta manera nuestras tablas quedaron listas!
Pero ahora teniamos que decirles a los paquetes que pasen por esas tablas, así que lo que hicimos fue usar iptables, para “encontrar” los paquetes que queriamos
encaminar por una tabla en particular, y les agregamos una marca (fwmark, que es una marca solo de uso interno).
Nos faltaba la conexion entre los paquetes marcados y nuestras tablas, por lo que usamos ip rule, para definir que los paquetes marcados, pasen por las tablas de ruteo correspondientes, y de esa manera se completo el circuito.

Bien, hemos visto un poco mas del poder del comando ip, si todo va bien seguiremos aprendiendo sobre iproute2 y la cantidad de cosas que podemos hacer con el!

Cualquier duda específica pueden dejar un comentario con su mail y me comunicaré con uds.

/* A partir de marzo nos estamos mudando a http://netsecure.com.arhttp://www.netvulcano.com.ar */

Seguir

Get every new post delivered to your Inbox.