Packet-Filter Networking

Priorizar los paquetes ACK usando PF y ALTQ

Introducción

Me dio por probar la configuración que pone Daniel Hartmeier en su sitio web.

Allí habla de la priorización de paquetes TCP que llevan la flag ACK.

Daniel es el principal commiter del software PF (packet filter) de OpenBSD, a él lo encuentran en: dhartmei at cvs {dot} openbsd {dot} org.

¿Que es ACK?

La flag ACK es una bandera que se activa dentro de un paquete TCP para indicar que se ha recibido un paquete adecuadamente. Cuando el destino no envia un ACK, el emisor retransmite creyendo que se ha perdido.

El Problema

El problema se da porque cada vez que se nos envian datos (estamos descargando) nuestro sistema envia ACK's de confirmación, hasta ahi no pasa nada, pero que sucede cuando al mismo tiempo que estamos descargando intentamos subir (upload) un archivo?, por ejemplo subiendo un attachment (archivo adjunto) para enviarlo por correo?

Nuestro sistema tendra que empezar a responder rápidamente a las peticiones del cliente, intentando enviarle los datos que mas pueda, por lo tanto los ACK's de nuestra descarga entraran en un periodo de espera (cola) y por ende el sistema remoto pensara que estamos muy lentos para responder, disminuira la ventana de transmisión y hará que nuestra conexión vaya mas lenta …

En resumen, si intentamos descargar un archivo y subir otro al mismo tiempo, nuestra conexión se pondrá MUY lenta …

Que hacer?

Una tecnica que no es única del firewall PF, es intentar priorizar los ACK's, esto significa darle mayor relevancia al proceso de respuesta en la comunicación, de esta forma aunque estemos subiendo archivos a la internet, nuestro querido amigo PF se encargará de responder los ACK a tiempo, haciendo que nuestra conexión se mantenga MUY estable.

En resumen: si ponemos un software que sea capaz de organizar el asunto de salida y entrada de paquetes, podremos evidenciar que aunque estemos subiendo archivos al internet, nuestras descargas se mantendran como si no lo estuvieramos haciendo. Maravilloso no?

En linux y otros sistemas operativos tambien se puede hacer, pero si alguien ha intentado hacerlo en linux a mano, se habrá dado cuenta que es algo complicado.

La ventaja de usar OpenBSD es que by default ya vienen muchos servicios preconfigurados listos para usar, solo basta con cambiar un parámetro en alguna de las variables del archivo /etc/rc.conf.

Por ejemplo, tenemos servicios listos para usar como: snmp, sensorsd (sensores de HW), firewall, correo electronico, antispam, ipsec, etc …

Para mis pruebas modifique el archivo /etc/rc.conf para habilitar el PF, adicione estas reglas al /etc/pf.conf y listo, eso fue todo. Además las pruebas las hice en una maquina virtual (VirtualBox), así que no hay excusa para no instalar OpenBSD, aunque sea para pruebas ;)

Edicion del archivo de reglas

# vi /etc/pf.conf

Habilitamos PF

# pfctl -e
pf enabled

Hacemos que PF recargue las reglas en el archivo indicado

# pfctl -f /etc/pf.conf

Las reglas que agregué son las mismas que se encuentran en el ejemplo de Daniel, lo unico que cambio es el nombre de interfaz y el enlace de subida que en mi caso es de 250kbps. Mi canal de bajada es de 512kbps. Para el ejercicio se trabajo con el scheduler PRIQ (encolamiento de prioridad, el cual trabaja de 0 a 15, donde 0 es el valor mas bajo)

Aqui esta lo que se agrega al archivo pf.conf, pongo comentarios para la sintaxis.

pf.conf

# defino mi interfaz de salida como pcn0
ext_if="pcn0"
# Habilito ALTQ en esa 
# interfaz con el scheduler PRIQ y definiendo 230Kbps de subida.
altq on $ext_if priq bandwidth 230Kb queue { q_pri, q_def }
# Defino una cola con prioridad 7
queue q_pri priority 7
# Defino otra cola con prioridad 1, que sera la por defecto
queue q_def priority 1 priq(default)
# Regla de filtrado, permitale salir al paquete siempre y cuando sea un paquete TCP que lleve la bandera 
# S (SYN) y vaya para cualquier lado, 
# verificando las banderas SA. asignele las colas definidas.
pass out on $ext_if proto tcp from $ext_if to any flags S/SA 
keep state queue (q_def, q_pri)
# Lo mismo pero de entrada
pass in on $ext_if proto tcp from any to $ext_if flags S/SA 
keep state queue (q_def, q_pri)

Esas líneas de filtrado actualmente se pueden cambiar por:

pf.conf

pass out on $ext_if proto tcp from $ext_if to any queue (q_def, q_pri)
pass in on $ext_if proto tcp from any to $ext_if queue (q_def, q_pri)

Dado que las flags S/SA y el keep state (mantenga los estados - recuerde los estados de las comunicaciones) se asumen by default

Entonces el truco de estas reglas es que la priorización se hace por el tipo de paquete y como los paquetes ACK no llevan payload (carga = datos) entonces hacen match (coinciden) con la cola de prioridad mas alta (7), en cambio el resto de paquetes que viajan por la red se asignan a la cola de prioridad 1.

Demostracion de la mejora

Una vez recargado el PF, podemos descargar un archivo y obtenemos las siguientes gráficas:

1. Descarga normal, sin subir archivos …

center|thumb|600px|Descarga normal sin priorizacion de ACK

para descargar uso wget, que se puede instalar desde los paquetes con el comando: “pkg_add -i wget”.

2. Grafica en el tiempo de la descarga y subida de archivos

center|thumb|600px|Grafica en el tiempo de la descarga y subida de archivos

Observen las zonas de colores …

La narajanda es el tiempo cuando estoy descargando nada mas, la línea azul indica recepción de datos (estoy descargando) y la naranjada indica transmisíon, la cual es muy baja, simplemente los ACK's de respuesta.

La zona roja, es la que muestra el efecto de subir un archivo a Internet, en este caso hice un attachment en GMAIL, observen como poco a poco, aumenta la transmisión y se disminuye la recepción, eso significa que los ACK's que antes salian libremente, ahora se estan quedando encolados.

3. Observen en esta gráfica como se disminuye la tasa de descarga (4k), algo muy negativo …

center|thumb|600px|Descarga con ancho de banda reducido por la subida del archivo

La zona verde me muestra que sucede una vez el archivo terminó de subir a GMAIL. todo se normaliza. La siguiente gráfica muestra una prueba similar durante mas tiempo, donde se comprueba la estabilidad de la velocidad de conexión durante el upload de un archivo.

center|thumb|600px|Grafica con priorizacion de ACK

La moraleja de este post no es que OpenBSD es el mejor S.O. (;) para manejar calidad de servicio (QoS), la moraleja es que podemos tener un sistema de priorización efectivo en 3 comandos y 5 líneas de firewall. ;)

! Larga vida a PF y ALTQ !

Más información

Configuración básica de PF.

Consulte el manual oficial de PF.

Articulo original en OpenBSD Colombia.

Más información sobre el manejo de las flags (banderas) de los paquetes TCP en: http://www.openbsd.org/faq/pf/filter.html#tcpflags


Personal Tools