
Temos uma configuração onde temos um contêiner docker que precisa se comunicar com dispositivos em uma VPN (openvpn) via ipv6. Isso é feito construindo uma ponte entre as redes docker e a interface tap0 no host.
Os dispositivos finais enviam uma mensagem para o contêiner do docker e esperam receber de volta uma mensagem de confirmação. No entanto, eles estão em sub-redes diferentes, com o contêiner e o host na bbbb::/64
sub-rede e os dispositivos na abcd::/64
(para fins de ilustração). Há um gateway no bbbb::abcd:2
qual roteia o tráfego de uma sub-rede para outra, e o host docker tem uma configuração de gateway para isso.
Para ser claro:
bbbb::4001 <--> bbbb::2105 <--> bbbb::abcd:2 <--> abcd::/64
Onde bbbb::4001
está o endereço do container; bbbb::2105
é o endereço do host; bbbb::abcd2
é o endereço do dispositivo gateway; abcd::/64
é a sub-rede na qual os dispositivos finais ficam.
Usando tshark
no host e no gateway, observamos o seguinte:
- O host pode se comunicar diretamente com dispositivos finais na sub-rede abcd (verificado com traceroute, pode ver pacotes no host e no gateway);
- O contêiner docker pode se comunicar com o gateway (verificado com ping, pode ver pacotes no host e no gateway);
- o contêiner do dockernão conseguiafale diretamente com os dispositivos finais na sub-rede abcd: pudemos ver os pacotes no host, da mesma forma que os vimos para a comunicação do host, mas não vimos nada chegando no gateway.
Tentamos modificar iptables
as regras para permitir pacotes encaminhados (por exemplo, definindo a política padrão da FORWARD
cadeia como ACCEPT
), mas sem sucesso.
Não sabemos onde procurar com esse problema, porque parece que os pacotes do contêiner do docker destinados à sub-rede na qual ele não está são descartadosem algum lugarno host, OU talvez sejam enviados para o lugar errado, mas os vemos na br0
interface do host, eles nunca chegam ao gateway. Quando o contêiner do docker tenta se comunicar com coisas na mesma sub-rede, ele funciona.
Por onde começo a procurar isso?
Responder1
O problema estava relacionado à rede do docker. Tínhamos uma configuração de rede docker para usar uma ponte de rede para conectar-se à VPN. Essa ponte foi configurada (via /etc/network/interfaces.d/br0.cfg
) com um endereço de gateway bbbb::2105
e a rede docker foi criada após a interface da ponte. Quando a rede docker foi criada, o endereço do gateway não foi especificado e o docker usou bbbb::1
como padrão o endereço do gateway, que foi forçado br0
a usar. Esse endereço é o mesmo endereço do servidor VPN. O resultado foi que os pacotes não estavam realmente sendo descartados no host, mas sim encaminhados para a tap
interface do servidor VPN, e o servidor VPN não tinha as tabelas de roteamento configuradas de forma que soubesse o que fazer com esses pacotes, então eles efetivamente ficaram bloqueados quando chegaram ao servidor VPN.
Isso ficou claro usando o tshark para monitorar a tap
interface do servidor VPN, bem como as tap
interfaces nos gateways e na máquina host do docker. Em seguida, tentamos executar ping em um dispositivo final de dentro do contêiner do docker e vimos pacotes no host do docker e no servidor VPN, mas não nos gateways. Se tentarmos a mesma coisa no host docker, veremos pacotes no host docker e nos gateways, mas não no servidor VPN, demonstrando assim que os contêineres do docker foram configurados para enviar tráfego para o servidor VPN em vez de para as interfaces de rede do host .
O problema foi resolvido com a introdução da --gateway
opção de criação da rede docker.
A parte não resolvida disto épor quede repente começou a se comportar dessa forma, visto que a configuração funcionava desde 2016 e parou de funcionar aleatoriamente em um dia de junho de 2022.