1 votos

Resolución de IPv6 dns en MacOS High Sierra

Mi proveedor de servicios de Internet sólo me proporciona una dirección IPv4.

Después de establecer una conexión con el servidor OpenVPN de mi universidad, obtengo una dirección IPv6. Con una dirección IPv6 de ejemplo www6.fit.vutbr.cz

Sí que puedo:

PERO, no puedo:

  • abrir www6.fit.vutbr.cz en un navegador web

es decir, el navegador web no resuelve una dirección dns ipv6.

Si añado la siguiente asignación a /etc/hosts

2001:67c:1220:809::93e5:916 www6.fit.vutbr.cz

el navegador web por fin funciona.

Creo que tiene que ver con que aparezca scutil --dns:

DNS configuration

resolver #1
  search domain[0] : lan
  nameserver[0] : 192.168.1.1
  nameserver[1] : 8.8.8.8
  nameserver[2] : 8.8.4.4
  flags    : Request A records
  reach    : 0x00020002 (Reachable,Directly Reachable Address)

Creo que debería ver los registros AAAA de solicitud. ¿Por qué host y traceroute6 y ping6 resuelven el DNS, pero los navegadores web no? ¿Alguna sugerencia? Gracias

8voto

smammy Puntos 116

Este fue un enorme Es difícil de entender, así que escribí una pequeña guía con la esperanza de que otros la encuentren útil:

Cómo convencer a MacOS de que haga búsquedas de DNS IPv6 cuando su única dirección IPv6 es a través de una VPN o un túnel de algún tipo

El problema

El resolvedor de nombres de dominio de MacOS sólo devolverá direcciones IPv6 (a partir de registros AAAA) cuando piense que tiene una dirección IPv6 válida y enrutable. Para las interfaces físicas como Ethernet o Wi-Fi es suficiente con establecer o que se le asigne una dirección IPv6, pero para los túneles (como los que utilizan utun interfaces) hay algunos molestos pasos adicionales que hay que dar para convencer al sistema de que sí, efectivamente tienes una dirección IPv6, y sí, te gustaría recuperar las direcciones IPv6 para las búsquedas de DNS.

Yo uso wg-quick para establecer un túnel WireGuard entre mi portátil y un servidor virtual Linode. WireGuard utiliza un utun dispositivo de túnel del espacio de usuario para realizar la conexión. Así es como se configura ese dispositivo:

utun1: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1420
    inet 10.75.131.2 --> 10.75.131.2 netmask 0xffffff00
    inet6 fe80::a65e:60ff:fee1:b1bf%utun1 prefixlen 64 scopeid 0xc
    inet6 2600:3c03::de:d002 prefixlen 116
    nd6 options=201<PERFORMNUD,DAD>

Y aquí hay algunas líneas relevantes de mi tabla de enrutamiento:

Internet:
Destination        Gateway            Flags        Refs      Use   Netif Expire
0/1                utun1              USc             0        0   utun1
default            10.20.4.4          UGSc            0        0     en3
10.20.4/24         link#14            UCS             3        0     en3      !
10.75.131.2        10.75.131.2        UH              0        0   utun1
50.116.51.30       10.20.4.4          UGHS            7  2629464     en3
128.0/1            utun1              USc             5        0   utun1

Internet6:
Destination                             Gateway                         Flags         Netif Expire
::/1                                    utun1                           USc           utun1
2600:3c03::de:d000/116                  fe80::a65e:60ff:fee1:b1bf%utun1 Uc            utun1
8000::/1                                utun1                           USc           utun1
  • 10.20.4/24 es mi red ethernet local.
  • 10.20.4.5 es la dirección IP de la LAN de mi portátil.
  • 10.20.4.4 es la dirección IP de la LAN de mi puerta de enlace.
  • 10.75.131.2 es la dirección IPv4 de mi extremo del túnel punto a punto de WireGuard.
  • 2600:3c03::de:d002 es la dirección IPv6 de mi extremo del túnel punto a punto de WireGuard.
  • 50.116.51.30 es la dirección pública de mi servidor Linode.

Esto debería ser suficiente para tener conectividad IPv6, ¿verdad? Bueno, la resolución de nombres funciona cuando host habla directamente con mi servidor de nombres:

sam@shiny ~> host ipv6.whatismyv6.com
ipv6.whatismyv6.com has IPv6 address 2607:f0d0:3802:84::128

El ping por dirección IPv6 funciona:

sam@shiny ~> ping6 -c1 2607:f0d0:3802:84::128
PING6(56=40+8+8 bytes) 2600:3c03::de:d002 --> 2607:f0d0:3802:84::128
16 bytes from 2607:f0d0:3802:84::128, icmp_seq=0 hlim=55 time=80.991 ms

--- 2607:f0d0:3802:84::128 ping6 statistics ---
1 packets transmitted, 1 packets received, 0.0% packet loss
round-trip min/avg/max/std-dev = 80.991/80.991/80.991/0.000 ms

Y las conexiones HTTP por dirección IPv6 funcionan:

sam@shiny ~> curl -s 'http://[2607:f0d0:3802:84::128]' -H 'Host: ipv6.whatismyv6.com' | html2text | head -3
                 This page shows your IPv6 and/or IPv4 address
                          You are connecting with an IPv6 Address of:
                                             2600:3c03::de:d002

Sin embargo, las conexiones HTTP por nombre de host sólo IPv6 no funcionan:

sam@shiny ~> curl 'http://ipv6.whatismyv6.com'
curl: (6) Could not resolve host: ipv6.whatismyv6.com

El resultado es el mismo en wget así como en aplicaciones GUI como Firefox: la conexión mediante una dirección IPv6 literal funciona bien, pero la conexión mediante un nombre de host que sólo tiene un registro AAAA (y ningún registro A) asociado no.

Es interesante, ping6 es capaz de hacer una búsqueda de DNS y obtener una dirección IPv6 de vuelta:

sam@shiny ~ [6]> ping6 -c1 ipv6.whatismyv6.com
PING6(56=40+8+8 bytes) 2600:3c03::de:d002 --> 2607:f0d0:3802:84::128
16 bytes from 2607:f0d0:3802:84::128, icmp_seq=0 hlim=55 time=49.513 ms

--- ipv6.whatismyv6.com ping6 statistics ---
1 packets transmitted, 1 packets received, 0.0% packet loss
round-trip min/avg/max/std-dev = 49.513/49.513/49.513/0.000 ms

¿Por qué puede ping6 ¿hacer esto cuando nada más puede hacerlo? Resulta que cuando ping6 llama a getaddrinfo sobrescribe las banderas por defecto. Una de las banderas por defecto es AI_ADDRCONFIG , que indica al resolvedor que sólo devuelva las direcciones de las familias de direcciones para las que el sistema tiene una dirección IP. (Es decir, que no devuelva direcciones IPv6 a menos que el sistema tenga una dirección IPv6 (no link-local)). La mayoría de los otros programas añadir a las banderas por defecto en lugar de machacarlas, lo que supongo que es sensato.

Si se ejecuta scutil --dns te dirá cómo está configurado el resolver. Aquí está la salida en mi sistema (menos un montón de cosas mdns que no importa):

DNS configuration

resolver #1
  search domain[0] : home.munkynet.org
  nameserver[0] : 10.20.4.4
  if_index : 14 (en3)
  flags    : Request A records
  reach    : 0x00020002 (Reachable,Directly Reachable Address)

DNS configuration (for scoped queries)

resolver #1
  search domain[0] : home.munkynet.org
  nameserver[0] : 10.20.4.4
  if_index : 14 (en3)
  flags    : Scoped, Request A records
  reach    : 0x00020002 (Reachable,Directly Reachable Address)

Tenga en cuenta que bajo flags dice Request A records pero no Request AAAA records . Así que nos queda tratar de convencer al resolvedor de MacOS de que, de hecho, tenemos una dirección IPv6 válida, aunque esté en una interfaz de túnel.

SystemConfiguration

La forma "correcta" de que esto ocurra es que cualquier programa que configure el túnel utilice el extraño y en gran medida indocumentado SystemConfiguration API para registrar el "servicio" de red y sus propiedades IPv6. La aplicación Viscosity hace esto. Tunnelblick no lo hace, el cliente oficial de OpenVPN no lo hace, y wg-quick seguro que no.

El scutil Kludge

Podemos crear las mismas estructuras de "servicio" de SystemConfiguration manualmente utilizando la función scutil comando:

Primero creamos la parte IPv4 del servicio:

sam@shiny ~> sudo scutil
> d.init
> d.add Addresses * 10.75.131.2
> d.add DestAddresses * 10.75.131.2
> d.add InterfaceName utun1
> set State:/Network/Service/my_ipv6_tunnel_service/IPv4
> set Setup:/Network/Service/my_ipv6_tunnel_service/IPv4

Y luego creamos la parte de IPv6:

> d.init
> d.add Addresses * fe80::a65e:60ff:fee1:b1bf 2600:3c03::de:d002
> d.add DestAddresses * ::ffff:ffff:ffff:ffff:0:0 ::
> d.add Flags * 0 0
> d.add InterfaceName utun1
> d.add PrefixLength * 64 116
> set State:/Network/Service/my_ipv6_tunnel_service/IPv6
> set Setup:/Network/Service/my_ipv6_tunnel_service/IPv6
> quit

Una vez hecho esto, la salida de scutil --dns (de nuevo modulando las cosas de mdns) cambia:

DNS configuration

resolver #1
  search domain[0] : home.munkynet.org
  nameserver[0] : 10.20.4.4
  if_index : 14 (en3)
  flags    : Request A records, Request AAAA records
  reach    : 0x00020002 (Reachable,Directly Reachable Address)

DNS configuration (for scoped queries)

resolver #1
  search domain[0] : home.munkynet.org
  nameserver[0] : 10.20.4.4
  if_index : 14 (en3)
  flags    : Scoped, Request A records
  reach    : 0x00020002 (Reachable,Directly Reachable Address)

Ahora vemos Request AAAA records ¡en las banderas! No estoy muy seguro de lo que son las "scoped queries" o por qué la configuración de DNS para ellas no cambió, pero las cosas parecen funcionar ahora, así que da igual:

sam@shiny ~> curl -s 'http://ipv6.whatismyv6.com' | html2text | head -3
                 This page shows your IPv6 and/or IPv4 address
                          You are connecting with an IPv6 Address of:
                                             2600:3c03::de:d002

Al desconectarse del túnel, lo único que tiene que hacer es eliminar las claves de SystemConfiguration que ha añadido:

sam@shiny ~> sudo scutil
> remove State:/Network/Service/my_ipv6_tunnel_service/IPv4
> remove Setup:/Network/Service/my_ipv6_tunnel_service/IPv4
> remove State:/Network/Service/my_ipv6_tunnel_service/IPv6
> remove Setup:/Network/Service/my_ipv6_tunnel_service/IPv6
> quit

Un par de cosas a tener en cuenta:

  • El nombre my_ipv6_tunnel_service es totalmente arbitraria.
  • Según la información que he obtenido de las secuencias de comandos scripts en el Mullvad .ovpn tiene que crear tanto el perfil Setup: y State: llaves. No he verificado esto porque soy perezoso.
  • No tengo ni idea de dónde está el IPv6 DestAddresses de la que viene. Los copié de Viscosity porque parecían funcionar allí. ::ffff:ffff:ffff:ffff:0:0 para la dirección local de enlace y :: para el público
  • Ni siquiera sé realmente qué DestAddresses significa o para qué se utiliza.

Un bonito script

Escribí un script de Python que obtiene direcciones y longitudes de prefijos de ifconfig de salida. Requiere Python 3.6 o posterior, así que asegúrate de tenerlo en tu ruta. Se llama wg-updown y llama a su servicio SystemConfiguration wg-updown-utun# pero no es realmente específico de WireGuard. Puedes llamarlo como un post-up/pre-down script para cualquier túnel VPN antiguo o ejecutarlo manualmente. Llámalo así:

# After tunnel comes up
wg-updown up IFACE

# Before tunnel goes down
wg-updown down IFACE

sustituir IFACE con el nombre de la interfaz que su cliente de túnel/VPN está utilizando, por ejemplo utun1 . Imprimirá los comandos que está enviando a scutil para que puedas ver lo que está haciendo en detalle.

#!/usr/bin/env python3

import re
import subprocess
import sys

def service_name_for_interface(interface):
    return 'wg-updown-' + interface

v4pat = re.compile(r'^\s*inet\s+(\S+)\s+-->\s+(\S+)\s+netmask\s+\S+')
v6pat = re.compile(r'^\s*inet6\s+(\S+?)(?:%\S+)?\s+prefixlen\s+(\S+)')
def get_tunnel_info(interface):
    ipv4s = dict(Addresses=[], DestAddresses=[])
    ipv6s = dict(Addresses=[], DestAddresses=[], Flags=[], PrefixLength=[])
    ifconfig = subprocess.run(["ifconfig", interface], capture_output=True,
                              check=True, text=True)
    for line in ifconfig.stdout.splitlines():
        v6match = v6pat.match(line)
        if v6match:
            ipv6s['Addresses'].append(v6match[1])
            # This is cribbed from Viscosity and probably wrong.
            if v6match[1].startswith('fe80'):
                ipv6s['DestAddresses'].append('::ffff:ffff:ffff:ffff:0:0')
            else:
                ipv6s['DestAddresses'].append('::')
            ipv6s['Flags'].append('0')
            ipv6s['PrefixLength'].append(v6match[2])
            continue
        v4match = v4pat.match(line)
        if v4match:
            ipv4s['Addresses'].append(v4match[1])
            ipv4s['DestAddresses'].append(v4match[2])
            continue
    return (ipv4s, ipv6s)

def run_scutil(commands):
    print(commands)
    subprocess.run(['scutil'], input=commands, check=True, text=True)

def up(interface):
    service_name = service_name_for_interface(interface)
    (ipv4s, ipv6s) = get_tunnel_info(interface)
    run_scutil('\n'.join([
        f"d.init",
        f"d.add Addresses * {' '.join(ipv4s['Addresses'])}",
        f"d.add DestAddresses * {' '.join(ipv4s['DestAddresses'])}",
        f"d.add InterfaceName {interface}",
        f"set State:/Network/Service/{service_name}/IPv4",
        f"set Setup:/Network/Service/{service_name}/IPv4",
        f"d.init",
        f"d.add Addresses * {' '.join(ipv6s['Addresses'])}",
        f"d.add DestAddresses * {' '.join(ipv6s['DestAddresses'])}",
        f"d.add Flags * {' '.join(ipv6s['Flags'])}",
        f"d.add InterfaceName {interface}",
        f"d.add PrefixLength * {' '.join(ipv6s['PrefixLength'])}",
        f"set State:/Network/Service/{service_name}/IPv6",
        f"set Setup:/Network/Service/{service_name}/IPv6",
    ]))

def down(interface):
    service_name = service_name_for_interface(interface)
    run_scutil('\n'.join([
        f"remove State:/Network/Service/{service_name}/IPv4",
        f"remove Setup:/Network/Service/{service_name}/IPv4",
        f"remove State:/Network/Service/{service_name}/IPv6",
        f"remove Setup:/Network/Service/{service_name}/IPv6",
    ]))

def main():
    operation = sys.argv[1]
    interface = sys.argv[2]
    if operation == 'up':
        up(interface)
    elif operation == 'down':
        down(interface)
    else:
        raise NotImplementedError()

if __name__ == "__main__":
    main()

2voto

William Blew Puntos 21

Al menos una interfaz de red tiene que incluir un servidor DNS con dirección IPv6.

Eso establece la bandera AAAA, y entonces el Mac OS resolverá las direcciones IPv6.

0voto

Marc Runkel Puntos 1

El problema parece deberse a que IPv6 está deshabilitado en la interfaz Ethernet (al menos lo estaba en mi caso).

Estoy accediendo a Internet IPv6 a través de tunnelbroker.net. Acabo de añadir mis direcciones locales y de puerta de enlace de Tunnelbroker en la página Preferencias del sistema - Red en la página de red.

Una solución más limpia sería ajustar las banderas para solicitar registros AAAA, pero no tengo ni idea de cómo hacerlo.

AppleAyuda.com

AppleAyuda es una comunidad de usuarios de los productos de Apple en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X