Conectividade IPv6 perdida no convidado KVM após 20 minutos

1

Eu tenho uma configuração de servidor de virtualização KVM no Hetzner. O Hetzner me fornece um IP mestre (95.xxx.xxx.235) e uma sub-rede IPv4 / 29 (95.xxx.xxx.184 / 29) e uma rede / 64 IPv6 (2a01: xxxx: xxxx: xxxx :: / 64).

O KVM Guest (Debian Stretch) perde a conectividade IPv6 exatamente após 20 minutos de reinicialização nos serviços de rede. Mesmo que a conexão seja perdida, posso fazer ping no gateway padrão (fe80 :: 1). A conectividade IPv4 permanece ativa o tempo todo e não tem problemas.

Atualmente, a interface é definida como um modo macvlan em bridge, e eu também tentei modos VEPA e privados sem sorte. Além disso, o tipo de NIC é definido como e1000, mas também tentei o virtio sem sorte.

Após a perda de conexão, fiz um despejo TCP da NIC física no host e ele mostra que há solicitações de eco que saem e respostas de eco que chegam à interface, mas um tcpdump tirado do NIC de convidados. solicita a saída da NIC.

/ etc / network / interfaces no Host:

auto lo
iface lo inet loopback
iface lo inet6 loopback

auto enp2s0
iface enp2s0 inet static
  address 95.xxx.xxx.235
  netmask 255.255.255.192
  gateway 95.xxx.xxx.193
  up route add -net 95.xxx.xxx.192 netmask 255.255.255.192 gw 95.xxx.xxx.193 dev enp2s0

iface enp2s0 inet6 static
  address 2a01:xxx:xxx:xxx::2
  netmask 64
  gateway fe80::1

/ etc / network / interfaces no Guest:

auto lo
iface lo inet loopback
iface lo inet6 loopback

auto ens3
iface ens3 inet static
    address 95.xxx.xxx.187
    netmask 255.255.255.248
    gateway 95.xxx.xxx.185

iface ens3 inet6 static
    address 2a01:xxx:xxx:xxx::20
    netmask 64
    gateway fe80::1

# route -6 -n no host:

Kernel IPv6 routing table
Destination                    Next Hop                   Flag Met Ref Use If
2a01:xxxx:xxxx:xxxx::/64          ::                         U    256 8  1162 enp2s0
fe80::/64                      ::                         U    256 0     0 macvtap0
fe80::/64                      ::                         U    256 0     0 enp2s0
::/0                           fe80::1                    UG   1024 8  4534 enp2s0
::/0                           ::                         !n   -1  1 11069 lo
::1/128                        ::                         Un   0   9    81 lo
2a01:xxxx:xxxx:xxxx::/128         ::                         Un   0   1     0 lo
2a01:xxxx:xxxx:xxxx::2/128        ::                         Un   0   9    82 lo
fe80::/128                     ::                         Un   0   1     0 lo
fe80::/128                     ::                         Un   0   1     0 lo
fe80::/128                     ::                         Un   0   1     0 lo
fe80::xxxx:xxxx:xxxx:1069/128   ::                         Un   0   1     0 lo
fe80::xxxx:xxxx:xxxx:22e1/128   ::                         Un   0   1     0 lo
fe80::xxxx:xxxx:xxxx:201/128   ::                         Un   0   2    79 lo
ff00::/8                       ::                         U    256 0     0 macvtap0
ff00::/8                       ::                         U    256 0     0 enp2s0
::/0                           ::                         !n   -1  1 11069 lo

# route -6 -n no Guest:

Kernel IPv6 routing table
Destination                    Next Hop                   Flag Met Ref Use If
2a01:xxxx:xxxx:1414::/64          ::                         U    256 0     0 ens3
fe80::/64                      ::                         U    256 0     0 ens3
::/0                           fe80::1                    UG   1024 2    77 ens3
::/0                           ::                         !n   -1  1  6846 lo
::1/128                        ::                         Un   0   5   525 lo
2a01:xxxx:xxxx:xxx::20/128       ::                         Un   0   3    70 lo
fe80::xxxx:xxxx:xxx:22e1/128   ::                         Un   0   2     6 lo
ff00::/8                       ::                         U    256 0     0 ens3
::/0                           ::                         !n   -1  1  6846 lo

# ip -6 neigh no host:

2a01:xxxx:xxxx:xxxx::20 dev enp2s0  FAILED
fe80::1 dev enp2s0 lladdr xx:xx:xx:8d:22:06 router STALE

# ip -6 neigh no Guest:

fe80::1 dev enp2s0 lladdr xx:xx:xx:8d:22:06 router REACHABLE

Provavelmente coisas relevantes do /etc/sysctl.conf no Host:

net.ipv4.ip_forward=1
net.ipv4.conf.enp2s0.send_redirects=0
net.ipv6.conf.all.forwarding=1

Coisas provavelmente relevantes do /etc/sysctl.conf no Guest:

net.ipv6.conf.default.accept_ra=2
net.ipv6.conf.default.autoconf=1
net.ipv6.conf.all.accept_ra=2
net.ipv6.conf.all.autoconf=1
net.ipv6.conf.ens3.accept_ra=2
net.ipv6.conf.ens3.autoconf=1

Seção provavelmente relevante do Guest libvirt-config:

<interface type='direct' trustGuestRxFilters='yes'>
  <mac address='xx:xx:xx:xx:xx:xx'/>
  <source dev='enp2s0' mode='bridge'/>
  <model type='e1000'/>
  <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</interface>

Como eu tenho lutado com isso por cerca de duas semanas e li quase todos os posts relevantes com problemas semelhantes, eu vi que Hetzner aparentemente faz algum tipo de implementação IPv6 suspeita. Eu já os contatei, mas eles se perguntaram se eu teria um problema de roteamento. Isso pode ser verdade, já que depois de 20 minutos ainda recebo as respostas de eco no NIC físico, mesmo que elas não sejam encaminhadas para o Guest.

Então, alguma idéia de colegas do IPv6?

Atualização:

Então, o Hetzner me confirmou que a rede 2a01: xxxx: xxxx: xxxx :: / 64 é roteada para o endereço local do link da interface física. Ao reiniciar a rede, a entrada do NDP permanece por 20 minutos, mas é removida depois, já que a VM não responde com o endereço local do link correto, pois tem um endereço MAC diferente.

Está começando a parecer que não posso usar interfaces macvtap aqui, mas tenho que criar uma ponte para isso. No entanto, eu me pergunto por que o host não pode ver o convidado (e vice-versa) com o IPv6, quando o IPv4 ainda funciona. Acho que me permitiria direcionar o tráfego diretamente do endereço principal do link local.

    
por Uitto 12.06.2018 / 19:43

1 resposta

2

Eu tive o mesmo problema com o servidor Hetzner, mas usando o VirtualBox em vez do KVM.

Problema:

O Hetzner roteia todos os pacotes IPv6 com qualquer IP de destino dentro de sua sub-rede / 64 para o endereço MAC de seu host físico. Isso significa que, se você enviar um ping de algum lugar da Internet para sua VM que tenha um endereço IPv6 com o mesmo prefixo do host, o gateway do Hetzer não fará uma solicitação ao vizinho para procurar o endereço MAC de sua VM, mas simplesmente encaminhará os pacotes ICMP para o MAC do seu host. Essa é a razão pela qual você pode ver respostas de eco em seu host físico, mas não em sua VM: ele é direcionado ao MAC do host, não ao MAC da VM.

No entanto, parece haver um bug na implementação do IPv6 de Hetzner (ou pode ser feito de propósito, não sei): Se a VM enviar uma solicitação de vizinho para procurar o endereço MAC do gateway (fe80 :: 1) e usar seu IP IPv6 global como o endereço de origem da solicitação, de alguma forma o gateway da Hetzner parece atualizar seu IPv6 interno para o MAC tabela de endereços. Nos 20 minutos seguintes, o gateway de Hetzner enviará qualquer pacote direcionado ao endereço IPv6 das VMs para o endereço MAC das VMs. Se em 20 minutos não for enviada nenhuma solicitação adicional do MAC da VM e do IP global da VM ao gateway, ele retornará para enviar pacotes IPv6 para o MAC do host.

Agora sua VM - logo após a inicialização da rede, talvez porque o endereço local do link não está atribuído neste momento - ONCE envia uma solicitação usando seu endereço IPv6 global como a fonte e "acidentalmente" atualiza a tabela de endereços MAC da Hetzner por uma vez . Durante o tempo de execução, a VM ainda envia continuamente solicitações para procurar o endereço MAC do gateway para manter sua tabela de endereços MAC atualizada, mas usa seu endereço IPv6 de link local para fazê-lo (o que é totalmente aceitável da perspectiva IPv6), mas que não atualizará a tabela de endereços MAC do gatet de Hetzner. Essa é a razão pela qual o IPv6 parece estar funcionando totalmente após a inicialização da VM, mas apenas por 20 minutos.

Soluções:

Existe uma solução suja e uma solução limpa:

  • Solução suja: sua VM precisa enviar uma solicitação para o endereço MAC do gateway usando seu endereço IPv6 global de tempos em tempos (digamos a cada 5 minutos). Isso é complicado: sua VM enviará solicitações, mas usando o IPv6 de link local. Então eu usei um truque barato aqui: eu removo o IP local do link da interface, envio uma solicitação (que é então forçada a usar o IP global) e reconecto o IP local do link:

    ip -6 addr del fe80::a00:27ff:fecf:e270/64 dev enp0s3
    ndisc6 fe80::1 enp0s3
    ip -6 addr add fe80::a00:27ff:fecf:e270/64 dev enp0s3
    
  • Solução limpa: não use ponte. Eu agora uso somente rede de host. Isso significa que a VM está conectada a uma NIC separada (vboxnet0). Eu adicionei uma rota IPv6 que encaminha todo o tráfego do host para o endereço IPv6 da VM:

    ip -6 route add <my IPv6 pefix>::20 dev vboxnet0
    

Na VM, uso o endereço IPv6 local do link do host, já que é o GW padrão. Para permitir que o host conecte a VM em seu IP IPv6 global, eu atribuí outro IP da mesma sub-rede / 64 ao vboxnet0. Para mim, isso funciona perfeitamente.

    
por 12.07.2018 / 11:05