[FUG-BR] CARP - Era: TESTEMUNHO do BSDDAY
Luiz Otávio Souza
luiz em visualconnect.com.br
Seg Ago 15 15:45:05 BRT 2005
loles...
"shut up and hack..." aprendi no bsdday :-D
ei hacker,
me explica ai...
Tenho o balanceamento:
fw1# ifconfig fxp0 192.168.0.1/24 # rede interna
fw1# ifconfig xl0 200.200.200.200/24 # inet
fw1# ifconfig xl1 192.168.1.1 # pfsync
fw1# ifconfig pfsync up syncdev xl1
fw1# router add default 200.200.200.201 # router
fw1# ifconfig carp0 create
fw1# ifconfig carp1 create
fw1# ifconfig carp2 create
fw1# ifconfig carp3 create
fw1# ifconfig carp0 192.168.0.5 255.255.255.0 vhid 1 pass 1
fw1# ifconfig carp1 192.168.0.5 255.255.255.0 vhid 2 advskew 100 pass 2
fw1# ifconfig carp2 200.200.200.205 255.255.255.0 vhid 3 pass 3
fw1# ifconfig carp3 200.200.200.205 255.255.255.0 vhid 4 advskew 100 pass 3
fw1# sysctl net.inet.carp.arpbalance=1
fw1# sysctl net.inet.carp.preempt=1
fw1# pfctl -f /etc/pf.conf # natd
fw2# ifconfig fxp0 192.168.0.2/24 # rede interna
fw2# ifconfig xl0 200.200.200.202/24 # inet
fw2# ifconfig xl1 192.168.1.2 # pfsync
fw2# ifconfig pfsync up syncdev xl1
fw2# router add default 200.200.200.201 # router
fw2# ifconfig carp0 create
fw2# ifconfig carp1 create
fw2# ifconfig carp2 create
fw2# ifconfig carp3 create
fw2# ifconfig carp0 192.168.0.5 255.255.255.0 vhid 1 advskew 100 pass 1
fw2# ifconfig carp1 192.168.0.5 255.255.255.0 vhid 2 pass 2
fw2# ifconfig carp2 200.200.200.205 255.255.255.0 vhid 3 advskew 100 pass 3
fw2# ifconfig carp3 200.200.200.205 255.255.255.0 vhid 4 pass 3
fw2# sysctl net.inet.carp.arpbalance=1
fw2# sysctl net.inet.carp.preempt=1
fw2# pfctl -f /etc/pf.conf # natd
Agora minha maquina "A" na rede interna abre uma conexao http para um site
na inet.
O pacote será enviado para o default gateway, que sera meu IP redundante
"192.168.0.5".
Antes do primeiro pacote de dado ser transferido a camada ethernet dispara
uma requisição ARP para saber qual é o endereço da placa (MAC ADDRESS) que
esta com esse IP na rede.
É aqui que caso existam duas interfaces CARP no sistema com o mesmo IP
(carp0 e carp1) entra o _suposto_ algoritmo buguento que falaram, que deve
ignorar o pedido baseado num mal implementado hash do endereço de origem:
/* Count the elegible carp interfaces with this address */
if (*count == 0)
*count = carp_addrcount(
(struct carp_if
*)ia->ia_ifp->if_carpdev->if_carp,
ia, CARP_COUNT_RUNNING);
/* This should never happen, but... */
if (*count == 0)
return (0);
/* this should be a hash, like pf_hash() */
if (ia->ia_addr.sin_addr.s_addr % *count == index - 1 &&
sc->sc_state == MASTER) {
return (1);
Aqui o hash devia retornar 1 para ignorar o ARP request e nao responder.
Esse hash utiliza o modolo do endereco de origem
(ia->ia_addr.sin_addr.s_addr) contra o número de interfaces aptas a fazer o
loadbalance (detentoras do IP e estado == MASTER).
Bom supostamente esse codigo funciona e só um dos meus firewalls responde a
essa chamada ARP e a conexão da A pode seguir tranquilamente.
Com a conexão da maquina A em andamento a mquina B tenta estabelecer uma
conexão com outro site na inet (na verdade não importa, mas...) e as
requisiçoes ARP serão novamente enviadas.
Dessa vez meu fw2 responde, só que a interface apta a responder isso no
firewall 2 é a carp1 e não a carp0 que atendeu a maquina A no fw1.
Nesse caso o fw2 devolvera um pacote ARP contendo um MAC ADDRESS diferente
do fw1. Isso acontece pq cada interface CARP tem seu proprio MAC ADDRESS.
Até tudo normal, mas vamos ver o que acontence com os pacotes saindo dos
firewalls e indo até o (unico) roteador.
O fw1 e o fw2 utilizão o IP redundate "200.200.200.205" para saida do
gateway (nat da rede interna).
Assim o roteador ao fazer a primeira resposta a primeira requisição do fw1
para a maquina A pergunta na camada ARP quem tem o mac address para a o IP
"200.200.200.205" e o firewall que utilizando o algoritmo acima descrito
responder a essa requição, receberá os pacotes do roteador.
Nesse caso dado o suposto _hash_ da função o escolhido fosse o fw2.
Quando o fw2 fosse transmitir os pacotes da conexão da maquina B o router
não precisaria saber para quem devolver os pacotes, uma vez que sua tabela
arp estava atualizada.
Então nos temos duas estações mandando dados atraves de dois firewalls
distintos, mas apenas um firewall recendo os dados das duas conexões.
Tudo parece funcionar, pois os estados do pfsync mantem os firewalls
_atualizados_ e estes não percebem a diferença das conexões que foram ou não
estabelecidas ali.
E o load balance não funciona neste ambiente.
Poxa o OpenBSD tem um BUG !!!
Corre e manda ele pra misc em openbsd.org
RTFM !!!
>From carp(4) -
http://www.openbsd.org/cgi-bin/man.cgi?query=carp&apropos=0&sektion=0&manpath=OpenBSD+Current&arch=i386&format=html
When the hosts receive an ARP request for 192.168.1.10, the source IP
ad-
dress of the request is used to compute which virtual host should
answer
the request. The host which is master of the selected virtual host
will
reply to the request, the other(s) will ignore it.
This way, locally connected systems will receive different ARP replies
and subsequent IP traffic will be balanced among the hosts. If one of
the hosts fails, the other will take over the virtual MAC address, and
begin answering ARP requests on its behalf.
Note: ARP balancing only works on the local network segment. It cannot
balance traffic that crosses a router, because the router itself will
al-
ways be balanced to the same virtual host.
Leu o ultimo paragrafo ?
Quem sabe o OpenBSD muda de NOTA para BUGS.
luiz
_______________________________________________
Freebsd mailing list
Freebsd em fug.com.br
http://mail.fug.com.br/mailman/listinfo/freebsd_fug.com.br
Mais detalhes sobre a lista de discussão freebsd