[OpenBSD]

[Anterior: Shell de Usuário para Autenticação em Gateways] [Conteúdo] [Próximo: Firewall para Casa ou Pequeno Escritório]

PF: Redundância de Firewall com CARP e pfsync


Conteúdo


Introdução ao CARP

CARP é o Protocolo de Redundância de Endereço Comum (Common Address Redundancy Protocol). Seu objetivo principal é permitir que múltiplos hosts no mesmo segmento de rede compartilhem um endereço IP. CARP é uma alternativa livre e segura ao Virtual Router Redundancy Protocol (VRRP) e ao Hot Standby Router Protocol (HSRP).

CARP funciona permitindo a um grupo de hosts no mesmo segmento de rede compartilhar um endereço IP. Esse grupo de hosts é referido como um "grupo de redundância". Ao grupo de redundância é atribuído um endereço IP que é compartilhado entre os membros do grupo. Dentro do grupo, um host é designado o "master" e o resto como "backups". O host "master" é o que atualmente "segura" o IP compartilhado; ele responde a qualquer tráfego ou requisições ARP direcionadas a ele. Cada host pode pertencer a mais que um grupo de redundância por vez.

Um uso comum para o CARP é criar um grupo de firewalls redundantes. O IP virtual que é atribuído ao grupo de redundância é configurado nas máquinas clientes como o gateway padrão (default). Caso o firewall master sofra uma falha ou seja desligado, o IP se moverá para um dos firewalls backup e o serviço vai continuar sem ser afetado.

CARP suporta IPv4 e IPv6.

Funcionamento do CARP

O host master no grupo envia regularmente anúncios à rede local, assim os hosts backup sabem que ele ainda está ativo. Se os hosts backup não ouvirem um anúncio do master por um período de tempo, então um deles tomará conta dos deveres do master (qualquer host backup que tenha configurado os valores para advbase e advskew baixos).

É possível que múltiplos grupos CARP existam no mesmo segmento de rede. Anúncios CARP contém o Virtual Host ID que permite aos membros do grupo identificar que grupo de redundância pertencem.

Para prevenir que um usuário malicioso no segmento de rede falsifique (spoofing) anúncios CARP, cada grupo pode ser configurado com uma senha. Cada pacote CARP enviado ao grupo é então protegido por um HMAC SHA1.

Como o CARP é seu próprio protocolo, ele deve ter uma regra de permissão explícita no conjunto de regras de filtragem:

pass out on $carp_dev proto carp keep state

$carp_dev deve ser a interface física que o CARP está se comunicando.

Configurando o CARP

Cada grupo de redundância é representado por uma interface de rede virtual carp(4). Assim, o CARP é configurado usando o ifconfig(8).
ifconfig carpN create

ifconfig carpN vhid vhid [pass senha] [carpdev carpdev] \
   [advbase advbase] [advskew advskew] [state estado] endereço-ip \
   netmask máscara
carpN
O nome da interface virtual carp(4) onde N é um inteiro que representa o número da interface (por exemplo, carp10).
vhid
O Virtual Host ID. Esse é um número único que é usado para identificar o grupo de redundância de outros nós na rede. Valores aceitos são de 1 a 255.
senha
A senha de autenticação para usar quando estiver conversando com outros hosts CARP nesse grupo de redundância. Deve ser a mesma para todos os membros do grupo.
carpdev
Esse parâmetro opcional especifica a interface de rede física que pertence a esse grupo de redundância. Por padrão, o CARP tentará determinar qual interface usar procurando pela interface física que está na mesma subrede da combinação endereço-ip e máscara dada à interface carp(4).
advbase
Esse parâmetro opcional especifica com que frequência, em segundos, anunciar que somos um membro do grupo de redundância. O padrão é 1 segundo. Valores aceitos são de 1 a 255.
advskew
Esse parâmetro opcional especifica quanto desviar o advbase quando estiver enviando anúncios CARP. Manipulando o advskew, o host CARP master pode ser escolhido. Quanto mais alto o número, menos preferido será o host quando estiver escolhendo um master. O padrão é 0. Valores aceitos são de 0 a 254.
estado
Força uma interface carp(4) em um certo estado. Estados válidos são init, backup e master.
endereço-ip
Esse é o endereço IP atribuído ao grupo de redundância. Esse endereço não tem que estar na mesma subrede que o endereço IP na interface física (se presente). Esse endereço, contudo, precisa ser o mesmo em todos os hosts no grupo.
máscara
A máscara de subrede do IP compartilhado.

Além disso, comportamentos CARP podem ser controlados via sysctl(8).

net.inet.carp.allow
Aceita entrada de pacotes CARP ou não. Padrão é 1 (sim).
net.inet.carp.preempt
Permite a hosts dentro de um grupo de redundância que tenham um melhor advbase e advskew tomar o lugar (preempt) do master. Adicionalmente, essa opção habilita "failing over" em todas as interfaces caso uma interface caia (down). Se uma interface física CARP cair, o CARP trocará o advskew para 240 em todas as outras interfaces CARP, em essência o "failing" termina por si mesmo. Essa opção é 0 (desabilitada) por padrão.
net.inet.carp.log
Loga pacotes CARP. O padrão é 0 (desabilitado).
net.inet.carp.arpbalance
Carrega balanceamento de tráfego entre múltiplos hosts no grupo de redundância. O padrão é 0 (desabilitado). Veja carp(4) para mais informações.

Exemplo de configuração CARP

Aqui tem um exemplo de configuração do 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

Isso configura o seguinte:

Rodar o ifconfig na carp1 mostra o status da interface.

# 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

Introdução ao pfsync

A interface de rede pfsync(4) expõe certas alterações feitas na tabela de estados do pf(4). Monitorando esse dispositivo usando tcpdump(8), alterações na tabela de estados podem ser observadas em tempo real. Além disso, a interface pfsync(4) pode enviar essas mensagens de alterações de estado para a rede de modo que outros nós rodando PF possam unir as alterações em suas próprias tabelas de estado. Da mesma forma, o pfsync(4) também pode ouvir a rede por mensagens que chegam.

Funcionamento do pfsync

Por padrão, o pfsync(4) não envia ou recebe atualizações da tabela de estados na rede; entretanto, atualizações ainda podem ser monitoradas usando o tcpdump(8) ou outras ferramentas na máquina local.

Quando o pfsync(4) está configurado para enviar e receber atualizações na rede, o comportamento padrão é enviar atualizações multicast na rede local. Todas as atualizações são enviadas sem autenticação. Prática mais comum é:

  1. Conectar os dois nós que estarão trocando atualizações usando um cabo crossover e usar a interface como syncdev (veja abaixo).
  2. Usar a opção syncpeer do ifconfig(8) (veja abaixo), assim atualizações são direcionadas com unicast para o nó, então configure o ipsec(4) entre os hosts para proteger o tráfego pfsync(4).

Quando as atualizações estão sendo enviadas e recebidas na rede, os pacotes pfsync devem ser aceitos nas regras de filtragem.

pass on $sync_if proto pfsync

$sync_if deve ser a interface física que o pfsync(4) está se comunicando.

Configurando o pfsync

Visto que o pfsync(4) é uma interface de rede virtual, é configurado usando o ifconfig(8).
ifconfig pfsyncN syncdev syncdev [syncpeer syncpeer]
pfsyncN
O nome da interface pfsync(4). A pfsync0 existe por padrão quando estiver usando o kernel GENERIC.
syncdev
O nome da interface física usada para enviar atualizações pfsync.
syncpeer
Esse parâmetro opcional especifica o endereço IP de um host para trocar atualizações pfsync. Por padrão as atualizações pfsync são multicast na rede local. Essa opção cancela esse comportamento e em vez disso envia atualizações unicasts para o syncpeer especificado.

Exemplo de configuração pfsync

Aqui tem um exemplo de configuração do pfsync.
# ifconfig pfsync0 syncdev em1
Isso habilita o pfsync na interface em1. As atualizações enviadas serão multicast na rede, permitindo que qualquer outro host rodando pfsync possa recebê-las.

Combinando CARP e pfsync Para Failover

Combinando as características do CARP e pfsync, um grupo de dois ou mais firewalls pode ser usado para criar um cluster de firewalls completamente redundante e com alta disponibilidade.
CARP:
Trata o failover automático de um firewall para outro.
pfsync:
Sincroniza a tabela de estados entre todos os firewalls. Caso aconteça um failover, o tráfego pode fluir ininterrupto através do novo firewall master.

Um cenário de exemplo. Dois firewalls, fw1 e fw2.

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

Os firewalls estão conectados diretamente usando um cabo crossover em em1. Ambos estão conectados a LAN em em0 e a uma conexão WAN/Internet em em2. Os endereços IP são como seguem:

A política de rede é que fw1 será o master preferido.

Configuração do fw1:
! Habilita preemption e o grupo de interfaces failover
# sysctl -w net.inet.carp.preempt=1

! Configura pfsync
# ifconfig em1 10.10.10.1 netmask 255.255.255.0
# ifconfig pfsync0 syncdev em1
# ifconfig pfsync0 up

! Configura CARP no lado LAN
# ifconfig carp1 create
# ifconfig carp1 vhid 1 carpdev em0 pass lanpasswd \
     172.16.0.100 netmask 255.255.255.0

! Configura CARP no lado WAN/Internet
# ifconfig carp2 create
# ifconfig carp2 vhid 2 carpdev em2 pass netpasswd \
    192.0.2.100 netmask 255.255.255.0

Configuração do fw2:
! Habilita preemption e o grupo de interfaces failover
# sysctl -w net.inet.carp.preempt=1

! Configura pfsync
# ifconfig em1 10.10.10.2 netmask 255.255.255.0
# ifconfig pfsync0 syncdev em1
# ifconfig pfsync0 up

! Configura CARP no lado LAN
# ifconfig carp1 create
# ifconfig carp1 vhid 1 carpdev em0 pass lanpasswd \
     advskew 128 172.16.0.100 netmask 255.255.255.0

! Configura CARP no lado 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 Operacionais

Alguns problemas operacionais comuns encontrados com CARP/pfsync.

Configurando o CARP e pfsync Durante o Boot

Visto que carp(4) e pfsync(4) são ambos tipos de interfaces de rede, eles podem ser configurados durante a inicialização criando-se um arquivo hostname.if(5). O script de inicialização netstart cuidará de criar as interfaces e configurá-las.

Exemplos:

/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

Forçando Failover do Master

De tempos em tempos, é necessário failover ou derrubar o nó master de propósito. Exemplos incluem derrubar o nó master para manutenção ou quando estiver resolvendo um problema. O objetivo aqui é elegantemente passar (fail over) o tráfego para um dos hosts backups de modo que os usuários não observem nenhum impacto.

Para failover de um grupo CARP em particular, derrube a interface carp(4) no nó master. Isso fará o master anunciar a si mesmo com um advbase e advskew "infinito". O(s) host(s) backup verá(ão) isso e imediatamente tomará(ão) o lugar do master.

# ifconfig carp1 down

Uma alternativa é aumentar o advskew para um valor mais alto que o advskew no(s) host(s) backup. Isso causará failover, mas ainda permite ao master participar no grupo CARP.

Um outro método para failover é ajustar o contador CARP demotion. O contador demotion é uma medida de como "pronto" um host está para se tornar o master do grupo CARP. Por exemplo, enquanto um host está no meio do processo de boot é uma má idéia para ele se tornar um master CARP até que todas as interfaces estejam configuradas, todos os serviços de rede estejam iniciados, etc. Hosts anunciando um valor demotion alto terão menos preferência como master.

Um contador demotion é armazenado em cada grupo de interface que a interface CARP pertence. Por padrão, todas as interfaces CARP são membros do grupo de interface "carp". O valor atual de um contador demotion pode ser visto usando o ifconfig(8):

# ifconfig -g carp
carp: carp demote count 0

Nesse exemplo o contador associado com o grupo de interface "carp" é mostrado. Quando um host CARP anuncia a si mesmo na rede, ele pega a soma dos contadores demotion para cada grupo de interface que a interface carp(4) pertence e anuncia esse valor como seu valor demotion.

Agora assuma o seguinte exemplo. Dois firewalls rodando CARP com as seguintes interfaces CARP:

O objetivo é apenas fazer failover dos grupos carp1 e carp2 para o firewall secundário.

Primeiro, associe cada grupo a um novo grupo de interface, neste caso chamado "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

Agora aumente o contador demotion para o grupo "internal" usando o ifconfig(8):

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

O firewall fará elegantemente o failover nos grupos carp1 e carp2 para o outro firewall no cluster, enquanto ainda se mantém como master nos grupos carp3 e carp4. Se o outro firewall começar a anunciar um valor demotion maior do que 50 ou se parar de anunciar completamente, então esse firewall fará novamente o takeover do master nos grupos carp1 e carp2.

Para voltar (fail back) para o firewall primário, reverta as mudanças:

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

Serviços de rede como OpenBGPD e sasyncd(8) fazem uso do contador demotion para garantir que o firewall não se torne master até que as sessões BGP estejam estabelecidas e SAs IPsec estejam sincronizados.

Dicas de Regras

Filtre a interface física. Até o ponto que o PF está preocupado, o tráfego da rede vem da interface física, não da interface virtual CARP (ou seja, carp0). Assim, escreva seu conjunto de regras de acordo. Não se esqueça de que um nome de uma interface em uma regra do PF pode ser tanto o nome da interface física ou um endereço associado a essa interface. Por exemplo, esta regra poderia estar correta:
pass in on fxp0 inet proto tcp from any to carp0 port 22
mas substituindo o fxp0 por carp0 não funcionaria como você deseja.

NÃO se esqueça de uma regra pass para proto carp e proto pfsync!

Outras Referências

Por favor veja estas outras fontes para mais informação:

[Anterior: Shell de Usuário para Autenticação em Gateways] [Conteúdo] [Próximo: Firewall para Casa ou Pequeno Escritório]


[voltar] www@openbsd.org
$OpenBSD: carp.html,v 1.12 2009/05/16 08:59:12 ajacoutot Exp $