IPSec, tcpdump and firewalls

La red de la empresa es un quilombo. Tenemos la red de la oficina por un lado, con los desktops en una red privada y los servers en una red pública (parte de la red pública del edificio donde está la oficina). Tenemos dos CoLos, uno en Rotterdam (Verizon; no me pidan comentarios) y otro en Amsterdam (xs4all; parece que le da housing a la mitad de .nl). En el primero tenemos tres rangos públicos y al menos dos privados, y en el otro tenemos sólo un rango público y unos dos o tres privados, incluyendo un cross-over entre los dos firewalls para hacer fail-over. En resumen, 5 redes públicas y vayasabersecuántas privadas desperdigadas.

Para complicar un poco más las cosas, montamos (bueno, yo no tuve nada que ver, pero ya trabajaba acá) una VPN entre los dos CoLos, teniendo ambas puntas en los firewalls (sin contar de que una punta tenemos dos; uno duerme hasta que el otro se cae).

El último ingrediente de esta sopa: graficamos el tráfico con MRTG (si, ya sé de Munin, ya lo sugerí, pero son como 80 servers en total) sacando los datos por SNMP (que, como dicen en todos lados, de simple tiene sólo el nombre). Pero para el caso es simple: un cliente corre en el server graficador, en este caso en Rotterdam, y en el nodo a graficar un servidorcito SNMP; el tráfico es por UDP.

'Bueno, ¿y dónde está la complicación?', se preguntarán. Les cuento.

Esta gente (notar cómo cuando se mandan una 'cagada' me despego :-P) tiene unos firewalls implementados a mano en bash. No es la típica ristra de reglas iptables, sino algo un poco más elaborado, con funcioncitas, pero aún así son 1400 líneas de bash y otras 630 de configuración (en bash también, obvio; no hay manera más fácil de hacer configuración de scripts bash que en bash mismo). Ya les comenté de shorewall también, pero todo a su tiempo.

Entonces me tocó la tarea de poner a andar el SMNP contra los firewalls de Amsterdam. Parece una boludez, sobre todo porque el MRTG tiene scripts con los que crear la configuración automáticamente leyendo lo que hay disponible por el mismo protocolo (lo diseñadores tuvieron la decencia de ponerle 'descubribilidad'). Por simple que parezca, no andaba nipatrásnipadelante. Le dimos quichicientas vueltas y náa.

Lo más raro fue cuando empezamos a usar tcpdump en las interfaces externas de los firewalls. Filtrando por el puerto 161 (snmp), en el firewall de Amsterdam veíamos el tráfico entrante pero no el saliente. Eso nos llevó a pensar que el firewall estaba jodiendo, pero entonces vimos que el tráfico que generaba el gráfico para el otro firewall, el durmiente, hacía lo mismo: veíamos el request pero no la respuesta. Pero el gráfico andaba. Y para complicar las cosas, con IPSec andando no deberíamos ver el tráfico, pues tcpdump no sabe desencriptar esos paquetes, sino apenas reconocerlos.

Entonces sospechamos.

Probando el tcpdump en el firewall de la red de Rotterdam vimos un comportamiento simétrico: no veíamos el request pero si la respuesta. Y sospechamos mas fuerte.

Mirando con mas fuerza me dí con que los scripts de firewall tenían un par de bugs: la función que seteaba las excepciones para el firewall mismo no era llamada nunca y además llamaba a iptables con parámetros erróneos.

La conclusión a la que llegamos, basada únicamente en lo que pudimos ver, es que el túnel anda, y que IPSec hace cosas raras con los paquetes; creemos que cuando los termina de procesar un paquete lo inyecta en la interfaz por la que entró, y eso es lo que hace que veamos el tráfico para un lado. Algún día que esté muy aburrido me voy a poner a ver si esta teoría es cierta.