macOS High SierraでのIPv6 DNS解決


5

ISPはIPv4アドレスのみを提供します。

大学のOpenVPNサーバーへの接続を設定した後、IPv6アドレスを取得します。IPv6アドレスの例www6.fit.vutbr.cz

私は出来ます:

でもできないんです:

  • Webブラウザでwww6.fit.vutbr.czを開きます

つまり、Webブラウザーはipv6 dnsアドレスを解決しません。

次のマッピングを/ etc / hostsに追加した場合

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

Webブラウザが最終的に機能します。

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)

Request AAAAレコードが表示されるはずです。hostとtraceroute6とping6がDNSを解決するのにWebブラウザーが解決しないのはなぜですか?助言がありますか?ありがとう


簡単なコメント-OpenVPNとTunnelblickを使用して問題を解決することはできませんでしたが、Viscosityを使用すると解決します。つまり、ViscosityはVPNを介してIPv6 DNSを処理します。
オンドレイグ

回答:


2

少なくとも1つのネットワークインターフェイスに、IPv6アドレス指定DNSサーバーを含める必要があります。

これによりAAAAフラグが設定され、Mac OSがIPv6アドレスを解決します。


0

この問題は、イーサネットインターフェイスでIPv6が無効になっているために生じているようです(少なくとも私にはそうでした)。

tunnelbroker.netを介してIPv6インターネットにアクセスしています。ネットワークページの[システム設定]-[ネットワーク]ページにTunnelbrokerのローカルアドレスとゲートウェイアドレスを追加しました。

よりクリーンな解決策は、AAAAレコードをリクエストするようにフラグを調整することですが、その方法はわかりません。


0

これは理解するのが非常に面倒だったので、他の人が役に立つと期待して少しガイドを書きました。

唯一のIPv6アドレスがVPNまたはある種のトンネル経由である場合に、macOSにIPv6 DNSルックアップを実行させる方法

問題

macOSのドメイン名リゾルバーは、有効なルーティング可能なIPv6アドレスがあると判断した場合にのみ(AAAAレコードから)IPv6アドレスを返します。イーサネットやWi-Fiのような物理インターフェースの場合、IPv6アドレスを設定または割り当てるだけで十分ですが、トンネル(utunインターフェースを使用するものなど)の場合、システムに「はい、本当に」 IPv6アドレスがあり、はい、DNSルックアップのためにIPv6アドレスを取得したいです。

wg-quickラップトップとLinode仮想サーバーの間にWireGuardトンネルを確立するために使用します。WireGuardは、utunユーザー空間トンネルデバイスを使用して接続を確立します。そのデバイスの設定方法は次のとおりです。

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>

そして、ここに私のルーティングテーブルからのいくつかの関連する行があります:

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 私のローカルイーサネットネットワークです。
  • 10.20.4.5 私のラップトップのLAN IPアドレスです。
  • 10.20.4.4 ゲートウェイのLAN IPアドレスです。
  • 10.75.131.2 WireGuardポイントツーポイントトンネルの終端のIPv4アドレスです。
  • 2600:3c03::de:d002 WireGuardポイントツーポイントトンネルの終端のIPv6アドレスです。
  • 50.116.51.30 Linodeサーバーのパブリックアドレスです。

これで、IPv6接続が可能になりますか?さて、名前解決は、host私のネームサーバーと直接対話するときに機能します。

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

IPv6アドレスによるPingは機能します。

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

また、IPv6アドレスによるHTTP接続は機能します。

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

ただし、IPv6のみのホスト名によるHTTP接続は機能しません。

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

結果は、wgetFirefoxのようなGUIアプリでも同じです。リテラルIPv6アドレスによる接続は正常に機能しますが、AAAAレコードのみが関連付けられている(Aレコードがない)ホスト名による接続はうまくいきません。

興味深いことに、DNSルックアップを実行してIPv6アドレスを取得することping6 できます。

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

ping6他に何もできないのになぜこれができるのでしょうか?それは時にあることが判明ping6呼び出し、getaddrinfoそれがデフォルトのフラグを上書きします。デフォルトフラグの1つは、AI_ADDRCONFIGシステムにIPアドレスがあるアドレスファミリのアドレスのみを返すようにリゾルバに指示します。(つまり、システムに(リンクローカルではない)IPv6アドレスがない限り、IPv6アドレスを返さないでください。)他のほとんどのプログラム、デフォルトのフラグを上書きするのではなく追加します。

実行scutil --dnsすると、リゾルバの設定方法が表示されます。これが私のシステムの出力です(重要なことはありませんが、mdnsのものはたくさんありません):

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)

その下に注意してくださいflags、それが言うRequest A recordsはありませんRequest AAAA records。そのため、トンネルインターフェイス上であっても、実際には有効なIPv6アドレスを持っていることをmacOSのリゾルバーに納得させることは私たちに任されています。

システム構成

これが起こる「正しい」方法は、トンネルをセットアップするプログラムが、奇妙で大部分が文書化されていないSystemConfigurationAPIを使用してネットワークの「サービス」とそのIPv6プロパティを登録することです。Viscosityアプリがこれを行います。Tunnelblickはサポートしていませんが、公式のOpenVPNクライアントはサポートしていwg-quickません。

scutilその場しのぎ

scutil次のコマンドを使用して、同じSystemConfiguration "サービス"構造を手動で作成できます。

最初に、サービスのIPv4部分を作成します。

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

次に、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

これが完了すると、scutil --dns(再びmdnsを法として)出力が変わります:

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)

Request AAAA recordsフラグに表示されます!「スコープクエリ」とは何か、またはそれらのDNS構成が変更されなかった理由はよくわかりませんが、今はうまくいくようです。

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

トンネルから切断するときは、追加したSystemConfigurationキーを削除するだけです。

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

注意点がいくつかあります:

  • 名前my_ipv6_tunnel_serviceは完全に任意です。
  • Mullvad .ovpnプロファイルのアップ/ダウンスクリプトから収集した情報によるSetup:と、State:キーとキーの両方を作成する必要があります。私は怠け者なので、これを確認しませんでした。
  • IPv6 DestAddressesがどこから来たのかはわかりません。そこから機能しているように見えたので、これらをViscosityからコピーしました。::ffff:ffff:ffff:ffff:0:0リンクローカルアドレスおよび::一般向け
  • 私は本当に何をDestAddresses意味するのか、それが何のために使われるのかさえ知りません。

素敵なスクリプト

ifconfig出力からアドレスとプレフィックス長を収集するPythonスクリプトを作成しました。Python 3.6以降が必要なので、パスにそれがあることを確認してください。それは呼ばれていますwg-updownし、そのSystemConfigurationサービスを呼び出しwg-updown-utun#、それは本当にWireGuard固有ではありません。古いVPNトンネルのポストアップ/プレダウンスクリプトとして呼び出すことも、手動で実行することもできます。次のように呼び出します。

# After tunnel comes up
wg-updown up IFACE

# Before tunnel goes down
wg-updown down IFACE

IFACEトンネル/ VPNクライアントが使用しているインターフェイスの名前、たとえばに置き換えますutun1。送信先のコマンドを出力するscutilので、何をしているのかを詳細に確認できます。

#!/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()
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.