Obtendo IPs reais do cliente sobre IPv6 com HAProxy dentro do Docker

3

Atualmente, tenho o HAProxy em execução em um contêiner do Docker. O Docker está sendo executado em um host com IPv4 e IPv6 ativados. O HAProxy é o único contêiner com portas do host compartilhadas e apenas o 80/443 passa pelo firewall na interface externa / pública.

Atualmente, o tráfego da web está correto. Eu tenho forwardfor definido no HAProxy e meus backends obtêm o real ClientIP para log e análise .. exceto para IPv6. Embora a porta 80/443 seja mapeada / convertida de tal forma pelo docker, de modo que o HAProxy obtenha o IP do cliente real no IPv4, qualquer coisa sobre o IPv6 é traduzida para o IPv4! O HAProxy obtém um endereço 172.17.0.1 privado como o IP do cliente para todas as conexões IPv6.

Meu daemon.json do Docker é semelhante ao seguinte:

{
    "tls": true,
    "tlsverify": true,
    "tlscacert": "/etc/docker/ca.pem",
    "tlscert": "/etc/docker/server.crt",
    "tlskey": "/etc/docker/server-key.pem",
    "ipv6": true,
    "fixed-cidr-v6": "2001:19f0:6001:1c12::/80",
    "hosts": ["127.0.0.1:2376", "10.10.6.10:2376", "fd://"]
}

Eu atribuí o Docker a /80 da minha sub-rede IPv6. Estou usando o Vultr como provedor e eles me atribuem 2001:19f0:6001:1c12:: para minha sub-rede IPv6 e 2001:19f0:6001:1c12:5400:01ff:fe49:876e para o endereço IP do meu host (a máquina que está executando a janela de encaixe). Eu também meu DEFAULT_FORWARD policy como ACCEPT in ufw e tenho o ndppd configurado com a seguinte configuração:

proxy ens3 {
  timeout 500
  ttl 30000
  rule 2001:19f0:6001:1c12::/80 {
    static
  }
}

Assim, com o IPv6 ativado, percebo que todos os meus contêineres recebem seus próprios endereços IPv6. Portanto, para que minha instância HAProxy obtenha um IP do Cliente real, preciso apontar o DNS para o endereço IPv6 do contêiner e abrir uma regra de firewall para ele. Mas o problema é que preciso que esse endereço seja estático. Claro que isso significa que não posso usar a rede bridge padrão e preciso ter uma rede definida pelo usuário.

Eu percebi que deveria ter feito isso para estar com, e então me lembrei de qual era o meu problema. Eu continuo recebendo o seguinte:

.gem/ruby/2.2.0/gems/docker-api-1.33.6/lib/docker/connection.rb:50:in 'rescue in request': could not find an available, non-overlapping IPv6 address pool among the defaults to assign to the network (Docker::Error::ServerError)

Isso é da biblioteca Ruby Docker-API, mas eu recebo exatamente o mesmo erro com a ferramenta de linha de comando. Eu tentei várias fatias de sub-redes IPv6, mas nenhuma parece funcionar e as pessoas me disseram que vou ter problemas se eu usar menos de um / 64.

Lembre-se, o problema original é que não consigo obter o client-ip em meus registros do servidor web para conexões IPv6. Se houver uma maneira mais simples de resolver isso, estou aberto a isto. Se não, quais configurações eu preciso usar para minha rede definida pelo usuário? Gostaria de poder excluir a ponte padrão e usar seus intervalos, mas isso não parece ser uma opção. Posso impedir que a ponte padrão obtenha essa sub-rede IPv6 definida em daemon.json e usar esse intervalo para minha rede definida pelo usuário (e, em seguida, atribuir estaticamente apenas o contêiner HAProxy para poder usar o IP desse contêiner no registro DNS / AAAA? ?) Ou existe uma maneira mais simples de obter as portas do host IPv6 para se conectarem diretamente ao contêiner sem tradução da mesma maneira que o IPv4 é feito?

    
por djsumdog 14.02.2018 / 08:16

1 resposta

1

Acabei tendo que criar uma rede definida pelo usuário. Depois de refatorar tudo, descobri um contêiner NAT do IPv6 que poderia ter feito a mesma coisa, mas estou feliz por ter fez certo em vez de tentar usar NAT IPv6 para hacká-lo.

Primeiro, divido meu intervalo de IPv6 para que meu daemon.json tenha o seguinte:

"fixed-cidr-v6": "2001:19f0:6001:1c12::1:0:0/96",

e minha rede definida pelo usuário recebeu 2001:19f0:6001:1c12::2:0:0/96 . Eu defini um endereço IPv6 estático na sub-rede ::2:0:0/96 e usei esse IP quando criei meu contêiner usando a API do Docker Engine:

 ...
 "NetworkingConfig"=>
  {"EndpointsConfig"=>
    {"my-custom-network"=>
      {"IPAMConfig"=>{"IPv6Address"=>"2001:19f0:6001:1c12::2:0:1000"}}}},
 ...

Em seguida, defino meus AAAA records no DNS para esse endereço IPv6 personalizado. Finalmente, certifiquei-me de que o HAProxy estivesse escutando em IPv4 e IPv6 usando as opções de configuração bind :::80 v4v6 e bind :::443 v4v6 <insert cert stuff> .

    
por 15.02.2018 / 06:00