# irv-ml1: let tailscaled add its own IPv6 mesh address. # # THE FAULT. `tailscale status` has been reporting, continuously: # 2 add route failures; first was: permission denied # adding address fd7a:115c:a1e0::6/128 from tunnel interface: permission denied # and `tailscale0` carries only 100.64.0.6/32 — no IPv6 — while headscale has # assigned it fd7a:115c:a1e0::6. # # It is NOT a capability problem: tailscaled runs as root with the full # bounding set including cap_net_admin. It is the kernel returning EPERM # because /etc/sysctl.conf:59 sets # net.ipv6.conf.default.disable_ipv6=1 # and `default` is inherited by NEWLY CREATED interfaces. tailscale0 is created # at daemon start, inherits disable_ipv6=1, and every attempt to add the # address is refused. # # WHY NOT JUST FLIP THE DEFAULT. That line carries no comment, but the shape of # it — IPv6 off for new interfaces on a Docker host with many bridges — reads as # deliberate. Changing it would hand IPv6 to every future docker bridge as a # side effect of fixing Tailscale. Scope the exception instead. # # WHY A DROP-IN AND NOT /etc/sysctl.d. A sysctl.d entry for a per-interface key # is applied at boot, BEFORE tailscale0 exists, and is silently ignored — the # setting would look present and do nothing. ExecStartPost runs after the # interface is created, which is the only moment the key can be set. steps: - name: Install the tailscaled drop-in that re-enables IPv6 on tailscale0 sudo: true upload: src: services/irv-ml1/tailscaled-ipv6.conf dest: /etc/systemd/system/tailscaled.service.d/10-tailscale0-ipv6.conf mode: '0644' - name: Reload systemd so the drop-in is live for the next start sudo: true shell: systemctl daemon-reload - name: Apply it to the RUNNING interface too, so no restart is needed sudo: true shell: sysctl -qw net.ipv6.conf.tailscale0.disable_ipv6=0 changed_when: 'true' verify: - name: tailscale0 has its IPv6 mesh address and the health error is gone shell: >- for i in $(seq 1 20); do ip -6 addr show tailscale0 2>/dev/null | grep -q "fd7a:115c:a1e0" && break || sleep 3; done; ip -6 addr show tailscale0 | grep -q "fd7a:115c:a1e0" && echo "IPv6 present:" && ip -brief addr show tailscale0 changed_when: 'false'