Puxen net.ipv6.conf.all.forwarding=1 nunha porta de enlace Debian para que puidese reenviar o tráfico dos clientes VPN, e uns tres cuartos de hora despois a máquina xa non tiña ningunha ruta predeterminada IPv6. O router ascendente funcionaba, o veciño link-local aínda respondía e a ligazón ascendente conservaba a súa dirección global. O que parara era a disposición do núcleo a seguir aceptando router advertisements nesa interface. A ruta non desapareceu cando escribín o sysctl; desapareceu cando caducou a vida da ruta predeterminada aprendida do RA e nada a renovou.

Nada parecía roto á primeira vista. O reenvío funcionaba, os clientes seguían pasando mentres a ruta vella estaba na caché, e o fallo chegou máis tarde que o cambio que o provocou. Ese atraso é a razón pola que se lle bota a culpa á ligazón ascendente ou a unha regra de devasado que nunca estivo implicada.

Lede a táboa de rutas antes de tocar calquera sysctl

Comezade con ip -6 route show default e lede os atributos, non só a porta de enlace. Unha ruta predeterminada aprendida do RA está marcada con proto ra, leva unha preferencia e amosa unha conta atrás expires. Unha ruta engadida a man non ten ningunha das dúas, e esa diferenza díxovos que mecanismo posúe a ruta.

$ ip -6 route show default
default via fe80::1 dev eth0 proto ra metric 1024 expires 1432sec hoplimit 64 pref medium

Despois mirade o enderezo: ip -6 addr show dev eth0. Un enderezo global con vidas preferida e válida medidas en horas sobrevivirá a unha ruta predeterminada cuxa vida de router se mide en minutos. Enderezo presente e ruta predeterminada ausente é a sinatura dun problema de anuncios. Se tamén falta o enderezo, primeiro hai que perseguir a ligazón, a información de prefixo ou a detección de enderezos duplicados.

Por que o reenvío desactiva o procesamento de RA

Un RA é un paquete ICMPv6 de tipo 134, enviado desde unha orixe link-local cun límite de salto 255. Antes de usalo, o núcleo consulta o accept_ra da interface. O valor predeterminado é 1, e 1 non quere dicir si. Quere dicir: acepta só mentres este hóspede non reenvíe. Poned forwarding=1 e esa condición falla, así que o anuncio descártase antes de que se considere calquera prefixo ou router predeterminado nel.

Existen tres valores, e só o terceiro sobrevive ao reenvío:

accept_raforwarding=0forwarding=1
0ignoredignored
1 (default)acceptedignored
2acceptedaccepted

Outras dúas bandeiras deciden que se instala realmente. accept_ra_defrtr controla se o router predeterminado do anuncio se converte en ruta, e accept_ra_pinfo controla se a información de prefixo se usa para a configuración de enderezos. Desactivar accept_ra_defrtr é a forma habitual de manter enderezos SLAAC nun hóspede que reenvía sen aprender unha ruta predeterminada. É unha panca distinta de accept_ra, e é a que se usa cando se queren enderezos pero non unha ruta. A referencia do núcleo sobre IP sysctl lista as tres.

Confirmádeo con tres ordes

Primeiro, lede os valores en vivo en lugar do ficheiro que credes cargado:

sysctl net.ipv6.conf.eth0.forwarding net.ipv6.conf.all.forwarding \
       net.ipv6.conf.eth0.accept_ra net.ipv6.conf.eth0.accept_ra_defrtr

Segundo, demostrade que os anuncios aínda chegan. Filtrar polo byte de tipo ICMPv6 abonda e aforra ler unha parede de tráfico de descuberta de veciños:

tcpdump -ni eth0 'icmp6 and ip6[40] == 134'

Se non aparece nada durante varios minutos, accept_ra non é o voso problema. A ligazón ascendente deixou de anunciar, algo no camiño filtra ICMPv6, ou esa interface non está realmente no segmento que pensades. Terceiro, solicitade un anuncio vós mesmos e lede os seus campos:

rdisc6 eth0

rdisc6 vén no paquete ndisc6 en Debian e Ubuntu. Na saída, mirade a vida do router e a preferencia antes de cambiar calquera outra cousa. Un anuncio cunha vida de router 0 é unha orde de eliminar o router predeterminado, e ningún valor de accept_ra o converte nunha ruta utilizábel. Tamén así se atopa un CPE ascendente en modo ponte que reparte prefixos pero nunca se ofrece como router.

Facede da ligazón ascendente a única interface permisiva

Se a ligazón ascendente debe ser o router predeterminado, aceptade alí anuncios malia o reenvío, e en ningún outro sitio:

# /etc/sysctl.d/60-ipv6-router.conf
net.ipv6.conf.all.forwarding = 1
net.ipv6.conf.eth0.accept_ra = 2
net.ipv6.conf.eth0.accept_ra_defrtr = 1

O alcance importa porque o reenvío IPv6 en Linux é un só conmutador global, non un por ligazón. Escribide 1 en net.ipv6.conf.wg0.forwarding e despois lede net.ipv6.conf.all.forwarding: o valor global vira e cada interface comeza a reenviar. Non podedes ser router no túnel e un hóspede normal na LAN. O que si podedes limitar é a aceptación. Mantede accept_ra=2 na ligazón ascendente e deixade as interfaces do túnel e da LAN en 1 ou 0, para que un anuncio perdido que chegue polo túnel non poida instalar unha ruta predeterminada que apunte cara a el.

Un sysctl -w temporal non sobrevivirá ao seguinte arranque, e tanto systemd-networkd como NetworkManager escriben estes valores desde a súa propia configuración. En networkd, poñede IPv6Forwarding=yes e IPv6AcceptRA=yes no ficheiro .network da ligazón ascendente; networkd documenta IPv6Forwarding como global polo mesmo motivo do núcleo. Con NetworkManager, ipv6.method=auto na ligazón ascendente é o que goberna o valor de accept_ra, así que volvede ler o sysctl despois de nmcli connection up en lugar de confiar na primeira comprobación.

A alternativa estática, ip -6 route add default via fe80::1 dev eth0, si funciona, e é unha resposta razoábel cando o router ascendente ten un enderezo link-local estábel. Tede claro que cededes. Unha ruta predeterminada estática nunca se renova nin se retira, así que segue apuntando a un veciño morto despois de cambiar a ligazón ascendente. A ruta por RA falla de forma segura; a estática falla en silencio.

Probade un paquete reenviado, non o da propia porta de enlace

Os ping propios da porta de enlace poden ter éxito nunha ruta que ningún cliente pode usar, e tamén poden ter éxito porque a porta de enlace é a orixe. Probade desde un cliente conectado e despois preguntade á porta de enlace que faría para o enderezo dese cliente:

# on the VPN client
ping -6 -c 3 2001:4860:4860::8888

# on the gateway, using a client address
ip -6 route get 2001:4860:4860::8888 from fd42:20::2

Despois agardade unha vida de router e mirade de novo. O estado estábel que queredes é unha ruta predeterminada marcada con proto ra cuxo valor expires se reinicia constantemente, máis all.forwarding=1. Se expires só conta atrás, os anuncios aínda se descartan nalgún sitio, e o culpábel habitual é un xestor de rede que reescribe accept_ra despois de que o sysctl de arranque xa se executase.

Antes de pechar isto, confirmade catro cousas: a ruta predeterminada é proto ra e renovase, accept_ra=2 só se aplica á ligazón ascendente, o reenvío segue a ser 1 despois dun reinicio e de reiniciar o xestor, e é un cliente, non a porta de enlace, quen completa un ping IPv6. Se o cliente aínda falla cunha ruta sa, o seguinte sospeitoso é o camiño de volta ou un devasado ascendente, non o anuncio.

Artigos relacionados