Implementación Firewall Alta Disponibilidad

Se describen algunos detalles de la implementación de un cluster de firewall para obtener una configuración de alta disponibilidad basada en OpenBSD.
Esta implementación está basada en una anterior cuyas bases se describen en este documento.

Nota. En la versión 4.7 de OpenBSD se hizo un cambio en la sintaxis de algunas reglas, principalmente las referidas a nat y redirección.
Las reglas ejemplo del documento anterior son de versión 4.4 y deben ser corregidas para adecuarlas a versiones actuales.

Requerimientos

Para la nueva configuración se agregaron algunos requerimientos adicionales:

  • Usar configuración activo/activo en lugar de activo/pasivo.
  • Agregar más conexiones de internet.
  • Disponer de contingencia para servicios entrantes y no solo salientes.
  • Contar con un servcio de proxy reverso para compartir direcciones IP entre distintos servers conectados al firewall.
  • Permitir que las reglas de firewall se adapten a posibles cambios de IP de servers externos.

Detalles de implementación

Lograr una configuración activo/activo es bastante sencillo en versiones más nuevas de OpenBSD (no era posible en la versión que se usó en la configuración anterior). Se logra cambiando algunos parámetros en el archivo de configuración de la interface carp correspondiente.

Tomando el ejemplo usado en el anterior documento:

En el equipo master:

ifconfig if1 201.202.203.204 netmask 255.255.255.0
ifconfig carp1 201.202.203.210 vhid 1 advsbase 0 pass 1234 carpdev if1

En el equipo backup:

ifconfig if1 201.202.203.205 netmask 255.255.255.0
ifconfig carp1 201.202.203.210 vhid 1 advsbase 10 pass 1234 carpdev if1

Para lograr una configuración activo/activo las interfaces carp deben configurarse de la siguiente forma:

En el equipo 1 (ex master):

ifconfig carp1 201.202.203.210 carpnodes 1:0,2:100 balancing ip pass 1234 carpdev if1

En el equipo 2 (ex backup):

ifconfig carp1 201.202.203.210 carpnodes 1:100,2:0 balancing ip pass 1234 carpdev if1

Consultar ifconfig(8), para tener en claro todas las opciones disponibles. La forma de hacer el balanceo (en este caso la opción ip) puede ser lo que más se necesite considerar dependiendo del tipo de switch a donde se conecten los equipos.
Nota: Si bien el balanceo activo/activo funciona perfectamente, hay que tener algunas precauciones cuando se hacen redirecciones o NAT usando las direcciones IP de carp, de manera de asegurar que una conexión que sale por un equipo del cluster, regrese por el mismo equipo.

El agregado de más conexiones de internet en principio no genera problemas, sobre todo si es posible configurar vlans de manera de no estar limitado por el número de interfaces físicas disponibles. En OpenBSD el comando ifconfig permite configurar una interface vlan en forma muy sencilla.

Lo que sí se complica al utilizar más interfaces es el monitoreo de los distintos enlaces y sobre todo las posibles combinaciones de estados, que pueden definir cambios de reglas de firewall.

En todos los casos se ha usado el daemon ifstated.

La complejidad radica en que si para 2 conexiones se pueden tener 4 estados posibles, que serían por ejemplo: UP_ALL, DOWN_ALL, DOWN_1, DOWN_2, cuando se tienen 4 conexiones ya son 16 las combinaciones posibles.

Para terminar de hacer interesante la configuración el cliente solicitó en un caso que se usara una conexión de internet que no estaba físicamente en el site donde estaban los firewall, sino en un site remoto. Aprovechando que los dos sites están enlazados por una conexión dedicada de un importante ancho de banda, se decidió configurar una VPN con OpenVPN en modo bridge entre los dos sites, de manera que en el firewall principal se generó una interface virtual de tipo tun, que a los fines prácticos se manejó como una interface más del equipo.

La necesidad de tener contingencia para conexiones entrantes, agregó un grado de complejidad al sistema.

En la anterior implementación solo se tenía contingencia para los servicios salientes, de manera que el firewall solo debía cambiar las reglas que rutean el tráfico de un determinado tipo, a otra conexión de internet.

Para el caso de los servicios entrantes en algunos casos se debía asociar una dirección IP a un nombre de sitio web o servidor SMTP o POP3/IMAP.

Se propuso una solución usando un servicio de DNS dinamico que tiene tiempos de refresco bajos (60 seg normalmente), con alias de los nombres de hosts.
En este caso el firewall además de cambiar las reglas para permitir el tráfico por el enlace alternativo, cambia el registro del DNS de manera que las nuevas conexiones entrantes se dirijan al enlace que corresponda.

Se usó el comando ddclient para cambiar los registros de DNS. La implementación requirió cierta “inteligencia” en los scripts para detectar posibles errores de actualización. Para el servicio de proxy reverso, se usó squid corriendo en los dos equipos del cluster, redirigiendo el tráfico al server correspondiente conectado en una DMZ.b En relación a las reglas de firewall adaptables a los posibles cambios de IP de servers externos, se apeló al uso de tablas del sistema de packet filtering (pf).

En forma muy general la idea es la siguiente:

Suponiendo que se quiera habilitar acceso ssh restringido a un determinado server externo, una posible configuración sería:

# Macro con la IP del server (server.empresa.com)

server = "190.191.192.1"

# Regla de firewall

pass in on $int_if inet proto tcp to $server port ssh

Si la IP de server.empresa.com cambia, hay que editar el archivo pf.conf, cambiar el valor de la macro y volver a cargar las reglas.

Ahora bien, si en lugar de una macro se usa una tabla, la configuración sería:

# Tabla para server.empresa.com

table persist file /etc/pf.data/server

# Regla de firewall

pass in on $int_if inet proto tcp to port ssh

Aparentemente no hay diferencia, pero es perfectamente posible generar un proceso externo (ejemplo script que corra por cron) que verifique la dirección IP de server.empresa.com y si detecta un cambio actualice la tabla de pf. De esta manera las reglas de firewall se adaptarán a los cambios de IP externos, sin necesidad de intervención manual.

Conclusión

La versatilidad de OpenBSD permite configurar un sistema de firewall que resuelve muchas necesidades y la posibilidades que brinda un sistema operativo permiten implementaciones más allá del simple filtrado de paquetes.