Visitar URL original
GitHub - a0s/ipv6-install: Automatic IPv6 for macOS: a WireGuard tunnel that comes up on networks without IPv6 and goes away on networks with it · GitHub
Skip to content

About

Automatic IPv6 for macOS: a WireGuard tunnel that comes up on networks without IPv6 and goes away on networks with it

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

8 Commits

Folders and files

Repository files navigation

ipv6-install

Lint

A bash script that gives a Mac IPv6 on networks that don't have it.

When your Mac joins Wi-Fi without IPv6 (a café, a hotel, most offices), a small daemon brings up a WireGuard tunnel to an IPv6 tunnel broker. When you join a network with native IPv6, the tunnel goes down and you use the native one. You never have to touch it.

Inspired by openvpn-install, wireguard-install and 3proxy-install: one script, a few questions, and it works.

Requirements

  • macOS 13 or later (tested on macOS 26 Tahoe, Apple Silicon)
  • Homebrew. The installer adds bash and wireguard-tools if they are missing
  • A WireGuard config that gives you IPv6. Route64 hands them out for free: Tunnel Management > Add tunnel > IPv6 Tunnelbroker > pick the closest PoP > WireGuard, then Raw Config > Download .conf. Your own VPS with IPv6 works too.

Usage

curl -O https://raw.githubusercontent.com/a0s/ipv6-install/master/ipv6-install.sh
sudo bash ipv6-install.sh

It asks where the config is and how you want IPv6 used, installs the ipv6-auto LaunchDaemon and runs a self-test at the end. Run it again to see status, run the self-test, swap the config or remove everything. --update installs a newer daemon and keeps your config, --uninstall removes it without the menu.

With Homebrew:

brew install a0s/ipv6-install/ipv6-install
sudo ipv6-install

After that:

sudo ipv6-auto status
sudo ipv6-auto selftest
tail -f /var/log/ipv6-auto.log

How it behaves

The daemon sleeps until macOS reports a network change, plus one sanity check every five minutes, so it costs nothing on battery. It waits a few seconds after you connect, because routers often announce IPv6 a moment after IPv4. An IPv6 address and route are not enough to trust a network, because plenty of routers hand out IPv6 that goes nowhere. So the daemon pings a real IPv6 host through the Wi-Fi interface itself, which works even while the tunnel is up. If that fails, the tunnel stays. Every 30 minutes it quietly checks again, and a network that failed once has to pass twice in a row before the tunnel goes away. While another system VPN is connected (a WireGuard.app tunnel, say), the tunnel steps aside. During dark wake (Power Nap) and while the network is still coming up, it changes nothing.

WireGuard runs over UDP, so it works behind NAT and CGNAT. 6in4 from Hurricane Electric needs protocol 41 and a pingable public IP, which you won't get in a café.

The macOS part

A plain wg-quick tunnel with ::/0 isn't enough. macOS only asks DNS for AAAA records when there is a primary IPv6 service, and a utun interface isn't one, so apps never see IPv6 addresses. If you make the tunnel primary, macOS hands it IPv4 and DNS as well and your IPv4 default route disappears. WireGuard.app with ::/0 does the same thing.

The daemon publishes its own service in SystemConfiguration. The IPv6 part points at the tunnel and the IPv4, DNS and proxy parts are copies of your real network, refreshed on every change. macOS sees one service with IPv4 through your router and IPv6 through the tunnel.

This relies on undocumented behavior, so there is a fuse. Every time the service is published, the daemon checks that IPv4 still goes through the real interface. If it doesn't, it rolls back within two seconds, stops trying on that macOS build and shows a notification. After each macOS update the self-test runs on its own and tells you the result.

On metered networks (an iPhone hotspot, cellular) macOS insists that IPv4 and IPv6 go through the same interface, so the daemon does not publish the service there. The tunnel stays up and serves explicit IPv6 addresses, and the full setup comes back as soon as you switch to a normal network. Updating with --update also resets the fuse.

If you'd rather not touch SystemConfiguration, pick mode 2 in the installer. The tunnel still comes up, but apps only use it for IPv6-only hosts.

Caveats

Sites that have both IPv4 and IPv6 will go through the tunnel PoP, so pick one close to where you usually are. Networks that block all UDP except 53 and 443 block WireGuard too.

The tunnel runs with MTU 1280, the IPv6 minimum: a bigger or missing MTU in the config is replaced, a smaller one is kept. The wg-quick default (1380–1420) and what providers ship (Route64: 1380) are too big for phone hotspots and some cellular links: oversized packets vanish silently, TCP copes, but QUIC (HTTP/3, most of Google) hangs.

Contributing

git config core.hooksPath .githooks

The hook runs shellcheck and shfmt on staged scripts. CI runs the same checks. Please open an issue first if you want to discuss a larger change.

Credits & Licence

This project is under the MIT Licence

About

Automatic IPv6 for macOS: a WireGuard tunnel that comes up on networks without IPv6 and goes away on networks with it

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages