{"id":347,"date":"2022-11-03T20:25:18","date_gmt":"2022-11-03T19:25:18","guid":{"rendered":"https:\/\/blog.forestraven.net\/?p=347"},"modified":"2022-11-03T20:31:04","modified_gmt":"2022-11-03T19:31:04","slug":"tunnelblick-ipv6-dns-get-it-working","status":"publish","type":"post","link":"https:\/\/blog.forestraven.net\/index.php\/tunnelblick-ipv6-dns-get-it-working\/","title":{"rendered":"Tunnelblick IPv6 DNS &#8211; get it working"},"content":{"rendered":"\n<p>Basically &#8211; If you are using OpenVPN with IPv6 support, MacOS will not recognize it and only allow IPv4 DNS resolution.<\/p>\n\n\n\n<p>References:<br><a href=\"https:\/\/openvpn.net\/vpn-server-resources\/limited-ipv6-support-built-into-the-access-server\/\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/openvpn.net\/vpn-server-resources\/limited-ipv6-support-built-into-the-access-server\/<br><\/a><a href=\"https:\/\/apple.stackexchange.com\/questions\/304215\/how-to-add-aaaa-flag-ipv6-to-dns-resolver-configuration-on-sierra\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/apple.stackexchange.com\/questions\/304215\/how-to-add-aaaa-flag-ipv6-to-dns-resolver-configuration-on-sierra<br><\/a><a href=\"https:\/\/www.tunnelblick.net\/cUsingScripts.html\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/www.tunnelblick.net\/cUsingScripts.html<br><\/a><a href=\"https:\/\/tunnelblick.net\/cConfigT.html#creating-and-installing-a-tunnelblick-vpn-configuration\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/tunnelblick.net\/cConfigT.html#creating-and-installing-a-tunnelblick-vpn-configuration<\/a><\/p>\n\n\n\n<p>First, you have to configure IPv6 in your OpenVPN Server. For OpenVPN AS, there is a guide linked above.<\/p>\n\n\n\n<p>Once IPv6 is working in the tunnel, you will probably recognize that some services are working, but in some applications (like Safari), IPv6 only sites won&#8217;t work. This is because they use the systems DNS resolver, which doesn&#8217;t allow AAAA requests, if it thinks that it has no IPv6 internet access.<\/p>\n\n\n\n<p>You can check this using:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">scutil --dns                                                     \nDNS configuration\n\nresolver #1\n  search domain[0] : openvpn\n  nameserver[0] : 8.8.8.8\n  nameserver[1] : 8.8.4.4\n  flags    : Request A records\n  reach    : 0x00000002 (Reachable)<\/pre>\n\n\n\n<p>As you can see above, the resolver is only used for A records.<\/p>\n\n\n\n<p>On Stackexchange,  user <a href=\"https:\/\/apple.stackexchange.com\/users\/43036\/smammy\">smammy<\/a> created a nice writeup for Wireguard, that utilizes a script to convince the MacOS resolver to resolve AAAA records using the given DNS servers. This can easily be adapted for Tunnelblick.<\/p>\n\n\n\n<p>You need to create a Tunnelblick configuration package by creating a folder, adding the necessary files to it and adding the .tblk ending to it. MacOS will recognize it as a Tunnelblick package then and allow you to install the configuration including the necessary scripts.<\/p>\n\n\n\n<p>The folder should contain 4 files:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>profile.ovpn<\/li>\n\n\n\n<li>up-suffix.sh<\/li>\n\n\n\n<li>down-suffix.sh<\/li>\n\n\n\n<li>wg-updown.sh<\/li>\n<\/ul>\n\n\n\n<p><strong>profile.ovpn<br><\/strong>This is your OpenVPN profile, in my case the auto login profile exported from OpenvpnAS.<\/p>\n\n\n\n<p><strong>up-suffix.sh<\/strong><br>This is executed when establishing the connection.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">.\/wg-updown.sh up utun3<\/pre>\n\n\n\n<p><strong>down-suffix.sh<\/strong><br>This is executed when terminating the connection.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">.\/wg-updown.sh down utun3<\/pre>\n\n\n\n<p><strong>wg-updown.sh<\/strong><br>This is the script from stack exchange<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">#!\/usr\/bin\/env python3\n\nimport re\nimport subprocess\nimport sys\n\ndef service_name_for_interface(interface):\n    return 'wg-updown-' + interface\n\nv4pat = re.compile(r'^\\s*inet\\s+(\\S+)\\s+-->\\s+(\\S+)\\s+netmask\\s+\\S+')\nv6pat = re.compile(r'^\\s*inet6\\s+(\\S+?)(?:%\\S+)?\\s+prefixlen\\s+(\\S+)')\ndef get_tunnel_info(interface):\n    ipv4s = dict(Addresses=[], DestAddresses=[])\n    ipv6s = dict(Addresses=[], DestAddresses=[], Flags=[], PrefixLength=[])\n    ifconfig = subprocess.run([\"ifconfig\", interface], capture_output=True,\n                              check=True, text=True)\n    for line in ifconfig.stdout.splitlines():\n        v6match = v6pat.match(line)\n        if v6match:\n            ipv6s['Addresses'].append(v6match[1])\n            # This is cribbed from Viscosity and probably wrong.\n            if v6match[1].startswith('fe80'):\n                ipv6s['DestAddresses'].append('::ffff:ffff:ffff:ffff:0:0')\n            else:\n                ipv6s['DestAddresses'].append('::')\n            ipv6s['Flags'].append('0')\n            ipv6s['PrefixLength'].append(v6match[2])\n            continue\n        v4match = v4pat.match(line)\n        if v4match:\n            ipv4s['Addresses'].append(v4match[1])\n            ipv4s['DestAddresses'].append(v4match[2])\n            continue\n    return (ipv4s, ipv6s)\n\ndef run_scutil(commands):\n    print(commands)\n    subprocess.run(['scutil'], input=commands, check=True, text=True)\n\ndef up(interface):\n    service_name = service_name_for_interface(interface)\n    (ipv4s, ipv6s) = get_tunnel_info(interface)\n    run_scutil('\\n'.join([\n        f\"d.init\",\n        f\"d.add Addresses * {' '.join(ipv4s['Addresses'])}\",\n        f\"d.add DestAddresses * {' '.join(ipv4s['DestAddresses'])}\",\n        f\"d.add InterfaceName {interface}\",\n        f\"set State:\/Network\/Service\/{service_name}\/IPv4\",\n        f\"set Setup:\/Network\/Service\/{service_name}\/IPv4\",\n        f\"d.init\",\n        f\"d.add Addresses * {' '.join(ipv6s['Addresses'])}\",\n        f\"d.add DestAddresses * {' '.join(ipv6s['DestAddresses'])}\",\n        f\"d.add Flags * {' '.join(ipv6s['Flags'])}\",\n        f\"d.add InterfaceName {interface}\",\n        f\"d.add PrefixLength * {' '.join(ipv6s['PrefixLength'])}\",\n        f\"set State:\/Network\/Service\/{service_name}\/IPv6\",\n        f\"set Setup:\/Network\/Service\/{service_name}\/IPv6\",\n    ]))\n\ndef down(interface):\n    service_name = service_name_for_interface(interface)\n    run_scutil('\\n'.join([\n        f\"remove State:\/Network\/Service\/{service_name}\/IPv4\",\n        f\"remove Setup:\/Network\/Service\/{service_name}\/IPv4\",\n        f\"remove State:\/Network\/Service\/{service_name}\/IPv6\",\n        f\"remove Setup:\/Network\/Service\/{service_name}\/IPv6\",\n    ]))\n\ndef main():\n    operation = sys.argv[1]\n    interface = sys.argv[2]\n    if operation == 'up':\n        up(interface)\n    elif operation == 'down':\n        down(interface)\n    else:\n        raise NotImplementedError()\n\nif __name__ == \"__main__\":\n    main() <\/pre>\n\n\n\n<p>When the folder\/package is complete, it can be imported to Tunnelblick. You will get a lot of warnings.<\/p>\n\n\n\n<p>After importing, the connection can be started. After it is established, the output of scutils should look something like this:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">scutil --dns\nDNS configuration\n\nresolver #1\n  search domain[0] : openvpn\n  nameserver[0] : 8.8.8.8\n  nameserver[1] : 8.8.4.4\n  flags    : Request A records, Request AAAA records\n  reach    : 0x00000002 (Reachable)<\/pre>\n\n\n\n<p>Success! AAAA DNS resolution should now work in all applications.<\/p>\n\n\n\n<p>What I haven&#8217;t gotten to work yet, is that MacOS recognizes IPv6 DNS servers pushed trough the VPN config. I could only get it to resolve IPv6 addresses trough IPv4 DNS servers. If you have any success with this, please let me know.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Basically &#8211; If you are using OpenVPN with IPv6 support, MacOS will not recognize it and only allow IPv4 DNS resolution. References:https:\/\/openvpn.net\/vpn-server-resources\/limited-ipv6-support-built-into-the-access-server\/https:\/\/apple.stackexchange.com\/questions\/304215\/how-to-add-aaaa-flag-ipv6-to-dns-resolver-configuration-on-sierrahttps:\/\/www.tunnelblick.net\/cUsingScripts.htmlhttps:\/\/tunnelblick.net\/cConfigT.html#creating-and-installing-a-tunnelblick-vpn-configuration First, you have to configure IPv6 in your OpenVPN Server. For OpenVPN AS, there is a guide linked above. Once IPv6 is working in the tunnel, you will probably recognize that some services &hellip; <a href=\"https:\/\/blog.forestraven.net\/index.php\/tunnelblick-ipv6-dns-get-it-working\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Tunnelblick IPv6 DNS &#8211; get it working<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[39],"tags":[],"class_list":["post-347","post","type-post","status-publish","format-standard","hentry","category-it-hacking"],"_links":{"self":[{"href":"https:\/\/blog.forestraven.net\/index.php\/wp-json\/wp\/v2\/posts\/347","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.forestraven.net\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.forestraven.net\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.forestraven.net\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.forestraven.net\/index.php\/wp-json\/wp\/v2\/comments?post=347"}],"version-history":[{"count":1,"href":"https:\/\/blog.forestraven.net\/index.php\/wp-json\/wp\/v2\/posts\/347\/revisions"}],"predecessor-version":[{"id":350,"href":"https:\/\/blog.forestraven.net\/index.php\/wp-json\/wp\/v2\/posts\/347\/revisions\/350"}],"wp:attachment":[{"href":"https:\/\/blog.forestraven.net\/index.php\/wp-json\/wp\/v2\/media?parent=347"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.forestraven.net\/index.php\/wp-json\/wp\/v2\/categories?post=347"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.forestraven.net\/index.php\/wp-json\/wp\/v2\/tags?post=347"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}