[OpenBSD]

[Anterior: authpf: shell de usuario para pasarelas de autenticación] [Contenido] [Siguiente: Cortafuegos para una red doméstica o una oficina]

PF: Cortafuegos en Alta Disponibilidad con CARP y pfsync


Índice de contenidos


Introducción a CARP

CARP son las siglas de Common Address Redundancy Protocol. Su objetivo principal es permitir que varias máquinas en el mismo segmento de red compartan una dirección IP. CARP es una alternativa segura y libre a los protocolos Virtual Router Redundancy Protocol (VRRP) y Hot Standby Router Protocol (HSRP).

CARP funciona permitiendo que un grupo de máquinas o nodos en el mismo segmento de red compartan una dirección IP. Este grupo de nodos se conoce como un "grupo de redundancia". Al grupo de redundancia se le asigna una dirección IP que se comparte entre los los miembros del grupo. Dentro del grupo, un nodo es denominado «maestro» (master) y el resto son nodos «de respaldo» (backups). El nodo maestro es el que en ese momento «posee» la IP compartida; es el que responde al tráfico o peticiones ARP dirigidas hacia esa IP. Cada nodo puede pertenecer a más de un grupo de redundancia a la vez.

Un uso común de CARP es crear un grupo de cortafuegos redundantes. La IP virtual que se asigna al grupo de redundancia se configura en las máquinas cliente como pasarela predeterminada. En el caso de que el cortafuegos maestro sufra un fallo o quede desconectado de la red, la IP se trasladará a uno de los cortafuegos de respaldo y el servicio continuará sin interrupción.

CARP soporta IPv4 e IPv6.

Funcionamiento de CARP

El nodo maestro del grupo envía avisos regulares a la red local para que los nodos de respaldo sepan que sigue activa. Si los nodos de respaldo no reciben el aviso del nodo maestro durante un período determinado de tiempo, entonces una de ellas asumirá las funciones de maestro (cualquier nodo de respaldo con los valores más bajos definidos por advbase y advskew).

Pueden existir varios grupos de CARP en el mismo segmento de red. Los avisos de CARP contienen un identificador denominado VHID (Virtual Host ID) que permite a los miembros del grupo identificar a qué grupo de redundancia pertenece el aviso.

Con el fin de evitar que un usuario malicioso en el segmento de red pueda falsificar avisos CARP, cada grupo se puede configurar con una contraseña. Cada paquete CARP enviado al grupo es así protegido por HMAC-SHA1.

Dado que CARP es un protocolo en sí mismo, debe ser expresamente autorizado por las reglas de filtrado:

pass out on $carp_dev proto carp keep state

$carp_dev es la interfaz física que CARP utiliza para comunicarse.

Configuración de CARP

Cada grupo de redundancia está representado por una interfaz de red virtual carp(4). Como tal, CARP se configura mediante ifconfig(8).
ifconfig carpN create

ifconfig carpN vhid vhid [pass password] [carpdev carpdev] \
   [advbase advbase] [advskew advskew] [state state] [group|-group group] \
   ipaddress netmask mask
carpN
El nombre de la interfaz virtual carp(4), donde N es un número entero que representa el número de la interfaz (por ejemplo, carp10).
vhid
El identificador Virtual Host ID. Es un número único que se usa para identificar el grupo de redundancia en la red. Los valores válidos son de 1 a 255.
password
La contraseña de autenticación que se usa cuando se comunica con otros nodos CARP en este grupo de redundancia. Esta contraseña debe ser compartida entre todos los miembros del grupo.
carpdev
Este parámetro opcional especifica la interfaz de red física que pertenece a este grupo de redundancia. Por omisión, CARP tratará de determinar qué interfaz usar buscando una interfaz física que se encuentre en la misma subred que la combinación de dirección IP y máscara dada a la interfaz carp(4).
advbase
Este parámetro opcional especifica con qué frecuencia, en segundos, se avisa de que somos miembros del grupo de redundancia. El valor predeterminado es 1 segundo. Los valores válidos son de 1 a 255.
advskew
Este parámetro opcional especifica el sesgo introducido en advbase al enviar avisos CARP. Mediante la manipulación de advskew, se puede elegir el nodo maestro CARP. Cuanto mayor sea el número, menos preferido será el nodo al elegirse un maestro. El valor predeterminado es 0. Los valores válidos son de 0 a 254.
state
Permite forzar el estado de una interfaz carp(4). Son estados válidos: init, backup y master.
group, -group
Agrega o elimina una interfaz carp(4) a un determinado grupo de interfaz. Por omisión, todas las interfaces carp(4) se agregan al grupo carp. Cada grupo posee un contador carpdemote que afecta a todas las interfaces carp(4) pertenecientes a ese grupo. Como se describe más adelante, puede ser útil agrupar ciertas interfaces para propósitos de conmutación (failover).
ipaddress
Dirección IP compartida entre los miembros del grupo de redundancia. Esta dirección no tiene que estar en la misma subred que la dirección IP de la interfaz física (si existe una dirección configurada en esta interfaz). Esta dirección, sin embargo, ha de ser la misma en todos los miembros del grupo.
mask
La máscara de subred de la IP compartida.

El comportamiento de CARP puede controlarse también mediante sysctl(8).

net.inet.carp.allow
Acepta o no la entrada de paquetes CARP. El valor predeterminado es 1 (sí).
net.inet.carp.preempt
Permite elegir al maestro a los miembros de un grupo de redundancia que tengan mejores advbase y advskew. Además, esta opción también permite la conmutación a un grupo de interfaces en el caso de que una interfaz cause baja. Si una interfaz física CARP habilitada no está disponible, CARP aumentará el contador de degradación (carpdemote) a 1 en el grupo de interfaces cuya interfaz carp(4) es miembro, lo que tendrá como efecto conmutar juntos a todos los miembros del grupo. net.inet.carp.preempt está a 0 (deshabilitado) por omisión.
net.inet.carp.log
Registra los cambios de estado, malos paquetes y otros errores. Puede estar entre 0 y 7, correspondientes a las prioridades de syslog(3). El valor predeterminado es 2 (cambios de estado únicamente).

Ejemplo de configuración de CARP

He aquí un ejemplo de configuración de CARP:
# sysctl -w net.inet.carp.allow=1
# ifconfig carp1 create
# ifconfig carp1 vhid 1 pass mekmitasdigoat carpdev em0 \
    advskew 100 10.0.0.1 netmask 255.255.255.0

Estas órdenes configuran lo siguiente:

El uso de ifconfig permite ver el estado de la interfaz carp1:

# ifconfig carp1
carp1: flags=8802<UP,BROADCAST,SIMPLEX,MULTICAST> mtu 1500
     carp: BACKUP carpdev em0 vhid 1 advbase 1 advskew 100
     groups: carp
     inet 10.0.0.1 netmask 0xffffff00 broadcast 10.0.0.255

Introducción a pfsync

La interfaz de red pfsync(4) expone ciertos cambios realizados en la tabla de estados de pf(4). Al monitorizar este dispositivo mediante tcpdump(8), se pueden observar en tiempo real los cambios en la tabla de estados. Además, la interfaz pfsync(4) puede enviar estos mensajes de cambio de estado por la red para que otros nodos ejecutando PF puedan fusionar estos cambios con sus propias tablas de estado. Del mismo modo, pfsync(4) también puede estar a la escucha de mensajes entrantes.

Funcionamiento de pfsync

Por omisión, pfsync(4) no envía ni recibe actualizaciones de la tabla de estados a través de la red; sin embargo, las actualizaciones se pueden monitorizar mediante tcpdump(8) o herramientas análogas en la máquina local.

Cuando pfsync(4) está configurado para enviar o recibir actualizaciones a través de la red, el comportamiento prederminado es usar multicast sobre la red local. Todas las actualizaciones se envían sin autenticación. La práctica más habitual es una de las dos siguientes:

  1. Conecte los dos nodos que deben intercambiar actualizaciones mediante un cable cruzado. Las interfaces así conectadas se utilizan como syncdev (véase más adelante).
  2. Use la opción syncpeer option de la orden ifconfig(8) (véase más adelante) para enviar las actualizaciones son enviadas como unicast al par, a continuación configure ipsec(4) entre los nodos para proteger el tráfico pfsync(4).

Cuando las actualizaciones se envían y reciben a través de la red, los paquetes pfsync deben ser autorizados por las reglas de filtrado:

pass on $sync_if proto pfsync

$sync_if debe ser la interfaz física por la que pfsync(4) se comunica.

Configuración de pfsync

Dado que pfsync(4) es una interfaz de red virtual, se configura mediante ifconfig(8).
ifconfig pfsyncN syncdev syncdev [syncpeer syncpeer] [defer|-defer]
pfsyncN
El nombre de la interfaz pfsync(4). pfsync0 existe por omisión si se usa el kernel GENERIC.
syncdev
El nombre de la interfaz física usada para enviar actualizaciones a pfsync.
syncpeer
Este parámetro opcional especifica la dirección IP de un nodo para intercambiar actualizaciones pfsync. Por omisión, las actualizaciones pfsync son «multicast» en la red local. Esta opción sobreescribe ese comportamiento y, en su lugar, envía «unicasts» al syncpeer especificado.
defer
Si se emplea el indicador defer, el paquete inicial de una nueva conexión que atraviesa el cortafuegos no se transmitirá hasta que o bien otro sistema pfsync(4) haya llevado a cabo la adición a la tabla de estados, o bien haya expirado el tiempo máximo (timeout). Esto añade pequeños retrasos, pero permite que el tráfico fluya cuando más de un cortafuegos debe manejar paquetes activamente («activo/activo»), por ejemplo, con determinadas configuraciones ospfd(8), bgpd(8) o carp(4).

Ejemplo de configuración de pfsync

He aquí un ejemplo de configuración de pfsync:
# ifconfig pfsync0 syncdev em1
Esta orden activa pfsync en la interfaz em1. Las actualizaciones serán transmitidas en «multicast» a la red, permitiendo que cualquier otro nodo que utilice pfsync pueda recibirlas.

Uso combinado de CARP y pfsync para Alta Disponibilidad

Al combinar las funcionalidades de CARP y pfsync, se puede usar un grupo de dos o más cortafuegos para crear un clúster de Alta Disponibilidad totalmente redundante.
CARP:
Gestiona la conmutación automática (failover) de un cortafuegos a otro.
pfsync:
Sincroniza la tabla de estados entre todos los cortafuegos. En caso de que se produzca una conmutación, el tráfico puede fluir sin interrupción a través del nuevo cortafuegos maestro.

Un escenario de ejemplo. Dos cortafuegos: fw1 y fw2.

         +----| WAN/Internet |----+ 
         |                        |
      em2|                        |em2   
      +-----+                  +-----+
      | fw1 |-em1----------em1-| fw2 |
      +-----+                  +-----+
      em0|                        |em0
         |                        | 
      ---+-----LAN compartida-----+---

Las interfaces em1 de los cortafuegos son conectados directamente mediante un cable cruzado. Ambos se conectan a la LAN en em0 y a una conexión WAN/Internet en em2 Las direcciones IP son las siguientes:

La política de red es que el cortafuegos fw1 sea el maestro.

Configuración de fw1:
! activa la función de anticipación y el "failover" de la interfaz de grupo 
# sysctl -w net.inet.carp.preempt=1

! configuración de pfsync
# ifconfig em1 10.10.10.1 netmask 255.255.255.0
# ifconfig pfsync0 syncdev em1
# ifconfig pfsync0 up

! configuración de CARP en el lado de la LAN
# ifconfig carp1 create
# ifconfig carp1 vhid 1 carpdev em0 pass lanpasswd \
     172.16.0.100 netmask 255.255.255.0

! configuración CARP en el lado de la WAN/Internet 
# ifconfig carp2 create
# ifconfig carp2 vhid 2 carpdev em2 pass netpasswd \
    192.0.2.100 netmask 255.255.255.0

Configuración de fw2:
! activa la función de anticipación y el "failover" de la interfaz de grupo
# sysctl -w net.inet.carp.preempt=1

! configuración de pfsync
# ifconfig em1 10.10.10.2 netmask 255.255.255.0
# ifconfig pfsync0 syncdev em1
# ifconfig pfsync0 up

! configuración de CARP en el lado de la LAN
# ifconfig carp1 create
# ifconfig carp1 vhid 1 carpdev em0 pass lanpasswd \
     advskew 128 172.16.0.100 netmask 255.255.255.0

! configuración CARP en el lado de la WAN/Internet
# ifconfig carp2 create
# ifconfig carp2 vhid 2 carpdev em2 pass netpasswd \
    advskew 128 192.0.2.100 netmask 255.255.255.0

Problemas operativos

Algunos problemas operativos comunes hallados con CARP/pfsync.

Configuración de CARP y pfsync durante el arranque

Dado que carp(4) y pfsync(4) son interfaces de red, pueden configurarse al inicio mediante la creación de un fichero hostname.if(5). El script de inicio netstart se ocupará de crear las interfaces y configurarlas.

Ejemplos:

/etc/hostname.carp1
inet 172.16.0.100 255.255.255.0 172.16.0.255 vhid 1 carpdev em0 \
    pass lanpasswd
/etc/hostname.pfsync0
up syncdev em1

Forzar el «failover» del nodo maestro

Puede haber momentos en que sea necesario forzar la conmutación (failover) o degradar el nodo maestro a propósito. Por ejemplo, por la necesidad de detener el nodo maestro para realizar diagnósticos o porque haya un problema de funcionamiento. El objetivo aquí es conmutar el tráfico a uno de los nodos de respaldo de forma que los usuarios no noten ningún impacto.

Para forzar la conmutación de un determinado grupo de CARP, tumbe la interfaz carp(4) del nodo maestro. Esto causará que el nodo maestro se anuncie con un valor de advbase y advskew «infinito». El nodo o nodos de respaldo lo verán y de inmediato asumirán el papel del nodo maestro.

# ifconfig carp1 down

Una alternativa consiste en incrementar advskew a un valor superior que advskew en el nodo o nodos de respaldo. Esto causará una conmutación pero aún permite participar al nodo maestro en el grupo CARP.

Otro método de conmutación es ajustar el contador de degradación de CARP. El contador de degradación es una medida de lo «preparado» que está un nodo para convertirse en maestro del grupo CARP. Por ejemplo, mientras un nodo está en medio del proceso de arranque, es una mala idea convertirse en maestro CARP hasta que todas las interfaces hayan sido configuradas, todos los servicios de red se hayan iniciado, etc. Los nodos que anuncian un valor alto de degradación tendrán menos preferencia para pasar a nodo maestro.

Un contador de degradación se almacena en cada grupo de interfaces al que la interfaz CARP pertenece. Por omisión, todas las interfaces CARP son miembros del grupo de interfaces «carp». Puede verse el valor actual de un contador de degradación mediante ifconfig(8):

# ifconfig -g carp
carp: carp demote count 0

En este ejemplo, se muestra el contador asociado con el grupo de interfaces «carp». Cuando un nodo CARP se anuncia en la red, toma la suma de los contadores de degradación para cada grupo de interfaces al que pertenece la interfaz carp(4) y anuncia ese valor como su valor de degradación.

Considere ahora el siguiente ejemplo. Dos cortafuegos que utilizan CARP con las siguientes interfaces:

El objetivo consiste únicamente en conmutar los grupos carp1 y carp2 al cortafuegos secundario.

En primer lugar, asigne cada interfaz a un nuevo grupo, en este caso denominado «internal»:

# ifconfig carp1 group internal
# ifconfig carp2 group internal
# ifconfig internal
carp1: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
     carp: MASTER carpdev em0 vhid 1 advbase 1 advskew 100
     groups: carp internal
     inet 10.0.0.1 netmask 0xffffff00 broadcast 10.0.0.255
carp2: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
     carp: MASTER carpdev em1 vhid 2 advbase 1 advskew 100
     groups: carp internal
     inet 10.0.1.1 netmask 0xffffff00 broadcast 10.0.1.255

Ahora incremente el contador de degradación para el grupo «internal» por medio de ifconfig(8):

# ifconfig -g internal
internal: carp demote count 0
# ifconfig -g internal carpdemote 50
# ifconfig -g internal
internal: carp demote count 50

El cortafuegos ahora conmutará de forma elegante los grupos carp1 y carp2 hacia el otro cortafuegos del clúster, mientras todavía permanece como maestro de carp3 y carp4. Si el otro cortafuegos comienza a anunciarse con un valor de degradación superior a 50, o si deja de dar avisos, a continuación este cortafuegos tomará de nuevo el papel de maestro para carp1 carp2.

Para restablecer (fail back) el cortafuegos primario, revierta los cambios:

# ifconfig -g internal -carpdemote 50
# ifconfig -g internal
internal: carp demote count 0

Servicios de red como OpenBGPD y sasyncd(8) hacen uso del contador de degradación para garantizar que el cortafuegos no se convierta en maestro hasta que las sesiones BGP lleguen a establecerse y las SAs IPsec estén sincronizadas.

Consejos para el conjunto de reglas

Filtre la interfaz física. En lo que se refiere a PF, el tráfico de red proviene de la interfaz física, no de la interfaz virtual CARP (o sea, carp0). Por tanto, escriba las reglas en consecuencia. No hay que olvidar que un nombre de interfaz en una regla de PF puede ser o bien el nombre de una interfaz física o bien una dirección asociada con esa interfaz. Por ejemplo, esta regla podría ser correcta:
pass in on fxp0 inet proto tcp from any to carp0 port 22
pero sustituir fxp0 por carp0 no funcionará como desea.

¡NO se olvide de autorizar proto carp y proto pfsync!

Otras referencias

Por favor, consulte las siguientes fuentes para obtener más información:

[Anterior: authpf: shell de usuario para pasarelas de autenticación] [Contenido] [Siguiente: Cortafuegos para una red doméstica o una oficina]


[back] www@openbsd.org
$OpenBSD: carp.html,v 1.1 2011/03/18 16:33:11 ajacoutot Exp $