Este documento es un viaje; algunas partes se recorren con comodidad, y
en otras zonas se encontrará casi en la soledad. El mejor consejo que
puedo darle es que coja una gran taza de café o chocolate caliente, se
siente en un cómodo asiento, y absorba los contenidos antes de
aventurarse en el a veces peligroso mundo del hacking de redes.
Para un mayor entendimiento del uso de la infraestructura existente
sobre el sistema netfilter, recomiendo la lectura del Packet Filtering
HOWTO y el NAT HOWTO (disponibles en castellano). Para más información
sobre la programación del kernel, sugiero el Rusty's Unreliable Guide
to Kernel Hacking y el Rusty's Unreliable Guide to Kernel
Locking.
(C) 2000 Paul `Rusty' Russell. Bajo licencia GNU GPL.
netfilter es un sistema para manipular paquetes que se encuentra fuera
del interfaz normal de sockets de Berkeley. Consta de cuatro partes.
Primero, cada protocolo define "ganchos" (IPv4 define 5), que son puntos
bien definidos en el recorrido de un paquete a través de la pila de ese
protocolo. En cada uno de estos puntos, el protocolo llamará al sistema
netfilter con el paquete y el número del gancho.
En segundo lugar, hay partes del kernel que pueden registrarse para
escuchar los diferentes ganchos de cada protocolo. Entonces, cuando se le
pasa un paquete al sistema netfilter, éste comprueba si alguien se ha
registrado para ese protocolo y ese gancho; si es así, cada uno de los
que se ha registrado tiene la posibilidad de examinar (y quizá alterar)
el paquete en cuestión, y luego rechazarlo, permitir que pase, o pedirle
a netfilter que ponga el paquete en una cola para el espacio de usuario.
En tercer lugar, los paquetes que han sido colocados en la cola
son recogidos (por el controlador ip_queue_driver) para enviarlos al
espacio de usuario; estos paquetes se manejan asincrónicamente.
La parte final está constituida por comentarios útiles en el código y por
la documentación. Esto juega un papel decisivo en cualquier proyecto
experimental. El lema de netfilter es (robado descaradamente a Cort
Dougan):
``Entonces... ¿en qué es mejor esto que KDE?''
(Este lema casi dice `Azótame, pégame, hazme usar ipchains').
Además de este sistema crudo, se han escrito varios módulos que
proporcionan una funcionalidad similar a la que tenían los kernels
anteriores (pre-netfilter). En particular, un sistema NAT extensible, y
un sistema de filtrado de paquetes extensible (iptables).
No hay establecida una infraestructura para pasar paquetes al
espacio de usuario:
La programación del kernel se hace difícil
La programación del kernel tiene que hacerse en C/C++
Las políticas de filtrado dinámicas no pertenecen al kernel
2.2 introdujo una manera de pasar paquetes al espacio de usuario
mediante netlink, pero la reinyección de paquetes es lenta, y
sujeta a comprobaciones de `sanidad'. Por ejemplo, reinyectar un
paquete que afirma venir de una interfaz existente no es posible.
Montar un proxy transparente es una chapuza:
Tenemos que observar todos los paquetes para ver si hay
un socket ligado a esa dirección
root puede ligar (bind :-) a direcciones externas
No se pueden redirigir paquetes generados localmente
REDIRECT no maneja respuestas UDP: redirigir paquetes UDP al
puerto 1153 no funciona porque a algunos clientes no les gustan las
respuestas que vienen de otro puerto que no sea el 53.
REDIRECT no se coordina con la asignación de puertos tcp/udp: un
usuario podría conseguir un puerto (shadowed) por una regla REDIRECT.
(a user may get a port shadowed by a REDIRECT rule)
Ha sido interrumpido al menos dos veces desde la serie 2.1.
Has been broken at least twice during 2.1 series.
El código es extremadamente molesto. Considere el número de
apariciones de #ifdef CONFIG_IP_TRANSPARENT_PROXY en el 2.2.1: 34
apariciones en 11 ficheros. Compare esto con CONFIG_IP_FIREWALL, que
aparece 10 veces en 5 ficheros.
No es posible crear reglas de filtrado de paquetes independientes
de las direcciones de interfaz:
Se deben conocer las direcciones de interfaz locales para
distinguir los paquetes generados localmente o los que terminan
localmente de los paquetes redirigidos.
Incluso esto es insuficiente en casos de redirección o
enmascaramiento.
La cadena forward (redirección) sólo tiene información de la
interfaz de salida, lo que significa que usted tiene que figurarse de
dónde proviene el paquete utilizando sus conocimientos sobre la
topología de la red.
El enmascaramiento está encima del filtrado de paquetes:
Las interacciones entre el filtrado de paquetes y el enmascaramiento
hacen que sea complejo manejar un cortafuegos:
En el filtrado de entrada (input), los paquetes de respuesta
parecen ir destinados a la propia máquina
En el filtrado de redirección (forward), los paquetes
desenmascarados no se pueden ver
En el filtrado de salida (output), los paquetes parecen venir de la
máquina local
La manipulación del TOS, la redirección, el ICMP unreachable y el
marcado (mark) (que pueden proporcionan redirección de puertos, enrutado
y QoS) también están encima del código de filtrado de paquetes.
El código de ipchains no es ni modular ni extensible (p.ej.
filtrado de direcciones MAC, opciones de filtrado, etc).
La falta de una infraestructura suficiente ha llevado a la
profusión de distintas técnicas:
Enmascaramiento, además de módulos por cada protocolo
NAT estático veloz mediante código de enrutamiento (no tiene manejo
por protocolo)
Redirección de puertos (port forwarding), redirección, auto
redirección (auto forwarding)
Los Proyectos NAT y Servidor Virtual para Linux.
Incompatibilidad entre CONFIG_NET_FASTROUTE y el filtrado de
paquetes:
Los paquetes redirigidos tienen que atravesar tres cadenas de todos
modos
No hay manera de saber si estas cadenas pueden evitarse
No es posible la inspección de los paquetes rechazados a causa de
una protección de enrutado (p.ej. Source Address Verification).
No hay manera de leer automáticamente los contadores de las reglas
de filtrado de paquetes.
CONFIG_IP_ALWAYS_DEFRAG es una opción en tiempo de compilación,
cosa que le complica la vida a las distribuciones que quieren hacer un
kernel de propósitos generales.
Soy el único lo suficientemente tonto para hacer esto. Como coautor de
ipchains y como actual mantenedor del Cortafuegos IP del Kernel de Linux,
puedo ver muchos de los problemas que la gente tiene con el sistema
actual, además de saber lo que tratan de hacer.
Porque no soy un gran programador como todos desearíamos, y ciertamente
no he comprobado todas las situaciones, por falta de tiempo, equipo y/o
inspiración. Sí que tengo una batería de pruebas, a la que le animo que
contribuya.