[Anterior: Shell de Usuário para
Gateways de Autenticação]
[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últiplas máquinas no mesmo
segmento de rede compartilhem um endereço IP.
CARP é uma alternativa livre e segura ao
Protocolo de Redundância de Roteador Virtual
(VRRP - "Virtual Router Redundancy Protocol")
e ao
Protocolo de Roteador de Espera a Quente
(HSRP - "Hot Standby Router Protocol").
CARP funciona permitindo a um grupo de máquinas no mesmo
segmento de rede compartilhar um endereço IP.
Esse grupo de máquinas é 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, uma máquina é designada como "mestre" e o resto como
"backups".
A máquina mestre é a que atualmente "segura" o IP compartilhado; ela
responde a qualquer tráfego ou requisições ARP direcionadas a ele.
Cada máquina pode pertencer a mais de 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.
Caso o firewall mestre 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
A máquina mestre no grupo envia regularmente anúncios à rede local,
assim as máquinas backup sabem que ela ainda está ativa.
Se as máquinas backup não ouvirem um anúncio do mestre por um período de
tempo, então uma delas tomará conta dos deveres do mestre (qualquer
máquina backup com os valores mais baixos definidos para
advbase e advskew).
É possível que múltiplos grupos CARP existam no mesmo segmento de rede.
Anúncios CARP contêm o ID de Máquina Virtual (VHID - "Virtual Host ID")
que permite aos membros do grupo identificar a que grupo de redundância
pertencem.
Para prevenir que um usuário malicioso no segmento de rede falsifique
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 por onde o CARP se
comunica.
Configuração do 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] [group|-group grupo] \
endereço_ip netmask máscara
- carpN
- O nome da interface virtual carp(4), onde N é um número
inteiro que representa o número da interface (por exemplo, carp10).
- vhid
- O ID de Host Virtual. Esse é um número único que é usado para
identificar o grupo de redundância aos outros nós no grupo e
distingui-lo entre grupos numa mesma rede.
Valores aceitos são de 1 a 255.
Este valor deve ser o mesmo para todos os hosts percentes ao grupo.
- senha
- A senha de autenticação a usar quando estiver conversando com
outras máquinas 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 tenta determinar qual interface usar procurando
pela interface física que está na mesma sub-rede 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 o quanto desviar o
advbase ao enviar anúncios CARP.
Ao manipular o advskew, a máquina CARP mestre pode ser
escolhida. Quanto mais alto o número, menos preferida
será a máquina durante a escolha do mestre.
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.
- grupo
- Adiciona ou remove uma interface carp(4) a um determinado grupo.
Por padrão, todas as interfaces carp(4) são adicionadas ao grupo
carp. Cada grupo tem um contador carpdemote
englobando todas as interfaces daquele grupo. Como descrito
abaixo, isso pode ser útil para agrupar
determinadas interfaces juntas com propósito de utilizar failover.
- endereço_ip
- Esse é o endereço IP compartilhado atribuído ao
grupo de redundância.
Esse endereço não tem que estar na mesma sub-rede que o endereço IP na
interface física (se presente).
Esse endereço, contudo, precisa ser o mesmo em todas as máquinas no
grupo.
- máscara
- A máscara de sub-rede do IP compartilhado.
Além disso, o comportamento do CARP pode ser controlado via
sysctl(8).
- net.inet.carp.allow
- Aceita ou não a entrada de pacotes CARP. O padrão é 1 (sim).
- net.inet.carp.preempt
- Permite à máquinas dentro de um grupo de redundância que tenham
melhores advbase e advskew tomarem o lugar do mestre.
Adicionalmente, essa opção habilita "failing over" em um grupo de
interfaces caso uma das interfaces venha a entrar em estado de shutdown.
Se uma interface física CARP cair, o CARP incrementa o contador
(carpdemote) nos grupos cuja interface física faz parte em 1,
fazendo com que todas as outras interfaces possam assumir o failover juntas.
Por padrão, net.inet.carp.preempt é 0 (desabilitada).
- net.inet.carp.log
- Registra mudanças de estado, pacotes mal formados e outros erros.
O valor pode variar de 0 até 7, de acordo com propriedades do syslog(3).
Por padrão, o valor usado é 2 (registra apenas mudanças de estado).
Exemplo de configuração do CARP
Este é 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:
- Habilita a recepção de pacotes CARP (essa é a configuração
padrão).
- Cria uma interface carp(4), carp1.
- Configura carp1 para a máquina virtual número 1, habilita
uma senha, define em0 como a interface pertencente ao
grupo, e faz dessa máquina uma máquina backup devido ao
advskew de 100
(assumindo, é claro, que a máquina mestre seja configurada com um
advskew menor do que 100).
O IP compartilhado atribuído a esse grupo é 10.0.0.1/255.255.255.0.
Executar 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).
Ao monitorar esse dispositivo usando o
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 estados para a rede, de modo que outros nós executando o
PF possam mesclar as alterações em suas próprias tabelas de estados.
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.
A prática mais comum é:
- Conectar os dois nós que trocarão atualizações com um
cabo cruzado e usar a interface como o syncdev
(veja abaixo).
- Usar a opção syncpeer do ifconfig(8) (veja
abaixo), assim as atualizações são
direcionadas com "unicast" para o nó, e então configurar o
ipsec(4) entre as máquinas 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 no conjunto de regras de filtragem.
pass on $sync_if proto pfsync
$sync_if deve ser a interface física por onde o pfsync(4) se
comunica.
Configuração do pfsync
Visto que pfsync(4) é uma interface de rede virtual, ela é configurada
usando o
ifconfig(8).
ifconfig pfsyncN syncdev syncdev [syncpeer
syncpeer] [defer|-defer]
- 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 uma máquina 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.
- defer
- Se a flag de defer for usada, o pacote inicial de uma nova
conexão que passe através da firewall não será transmitido
até que outro sistema com pfsync(4) reconheça sua adição na
tabela de estados ou o tempo limite expire.
Isto adiciona pequenos atrasos, mas permite ao tráfego fluir quando mais de
um firewall pode estar, ativamente, manipulando pacotes ("ativo/ativo").
Por exemplo, em certos cenários e configurações com ospfd(8), bgpd(8) ou carp(4).
Exemplo de configuração do pfsync
Este é um exemplo de configuração do pfsync.
# ifconfig pfsync0 syncdev em1 up
Isso habilita o pfsync na interface em1.
As atualizações enviadas serão "multicast" na rede, permitindo que
qualquer outra máquina executando o pfsync possa recebê-las.
Combinando CARP e pfsync Para Failover
Ao combinar os recursos do CARP e do pfsync, um grupo de dois ou
mais firewalls pode ser usado para criar um cluster de firewalls
completamente redundante e de 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 mestre.
Um cenário de exemplo.
Dois firewalls, fw1 e fw2.
+----| WAN/Internet |----+
| |
em2| |em2
+-----+ +-----+
| fw1 |-em1----------em1-| fw2 |
+-----+ +-----+
em0| |em0
| |
---+----LAN Compartilhada---+---
Os firewalls estão conectados diretamente com um cabo cruzado
em em1.
Ambos estão conectados à LAN em em0 e a uma conexão
WAN/Internet em em2.
Os endereços IP são os seguintes:
- fw1 em0: 172.16.0.1
- fw1 em1: 10.10.10.1
- fw1 em2: 192.0.2.1
- fw2 em0: 172.16.0.2
- fw2 em1: 10.10.10.2
- fw2 em2: 192.0.2.2
- IP compartilhado da LAN: 172.16.0.100
- IP compartilhado da WAN/Internet: 192.0.2.100
A política de rede é que fw1 será o mestre preferido.
Configuração do fw1:
! Habilita a função de tomar o lugar e o failover de interface de grupo
# sysctl -w net.inet.carp.preempt=1
! Configura o pfsync
# ifconfig em1 10.10.10.1 netmask 255.255.255.0
# ifconfig pfsync0 syncdev em1
# ifconfig pfsync0 up
! Configura o 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 o 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 a função de tomar o lugar e o failover de interface de grupo
# sysctl -w net.inet.carp.preempt=1
! Configura o pfsync
# ifconfig em1 10.10.10.2 netmask 255.255.255.0
# ifconfig pfsync0 syncdev em1
# ifconfig pfsync0 up
! Configura o 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 o 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.
Configuração do CARP e pfsync Durante a Inicialização
Visto que carp(4) e pfsync(4) são ambos tipos de interfaces de rede,
elas podem ser configuradas 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 Mestre
De tempos em tempos é necessário fazer o "failover" ou derrubar o nó
mestre de propósito.
Exemplos incluem derrubar o nó mestre para manutenção ou quando estiver
resolvendo um problema.
O objetivo aqui é elegantemente passar ("fail over") o tráfego para uma
das máquinas 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ó mestre.
Isso faz com que o mestre anuncie a si mesmo com um
advbase e advskew "infinito".
A(s) máquina(s) backup vê(eem) isso e imediatamente toma(m) o
lugar da máquina mestre.
# ifconfig carp1 down
Uma alternativa é aumentar o advskew para um valor mais alto
que o advskew na(s) máquina(s) backup.
Isso causa um failover, mas ainda permite ao mestre participar
no grupo CARP.
Um outro método para failover é ajustar o contador demotion do CARP.
O contador demotion é uma medida de como "pronta" uma máquina
está para se tornar o mestre do grupo CARP.
Por exemplo, enquanto uma máquina está no meio do processo de
inicialização é uma má ideia para ela tornar-se um mestre CARP até que
todas as interfaces estejam configuradas, todos os serviços de rede
estejam iniciados, etc.
Máquinas anunciando um valor demotion alto terão menos preferência como
mestre.
Um contador demotion é armazenado em cada grupo de interfaces que a
interface CARP pertence.
Por padrão, todas as interfaces CARP são membros do grupo de interfaces
"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 uma máquina CARP anuncia a si mesma na rede, ela pega a soma dos
contadores demotion para cada grupo de interfaces que a interface
carp(4) pertence e anuncia esse valor como seu valor demotion.
Agora assuma o seguinte exemplo.
Dois firewalls executando CARP com as seguintes interfaces CARP:
- carp1 -- Departamento de Contabilidade
- carp2 -- Empregados Comuns
- carp3 -- Internet
- carp4 -- DMZ
O objetivo é apenas fazer failover dos grupos carp1 e carp2 para
o firewall secundário.
Primeiro, associe cada grupo a um novo grupo de interfaces, neste caso
nomeado como "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 agora faz elegantemente o failover nos grupos carp1 e carp2
para o outro firewall no cluster, enquanto ainda se mantém como mestre
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
tomaria novamente a liderança do mestre 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
Daemons de rede como
OpenBGPD e
sasyncd(8)
fazem uso do contador demotion para garantir que o firewall não
se torne mestre até que as sessões BGP estejam estabelecidas e SAs
IPsec estejam sincronizados.
Dicas de Conjunto 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 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 pode estar correta:
pass in on fxp0 inet proto tcp from any to carp0 port 22
mas substituir o fxp0 por carp0 não
funcionaria como você deseja.
NÃO se esqueça de uma regra de permissão de tráfego para
proto carp e proto pfsync!
Outras Referências
Por favor veja estas outras fontes para obter mais informações:
[Anterior: Shell de Usuário para
Gateways de Autenticação]
[Conteúdo]
[Próximo: Firewall para Casa ou Pequeno Escritório]
www@openbsd.org
$OpenBSD: carp.html,v 1.15 2013/01/18 07:15:55 ajacoutot Exp $