[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