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@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@fug.com.br
http://mail.fug.com.br/mailman/listinfo/freebsd_fug.com.br

Responder a