Skip to content

microwave: make the reserved IPv6 live in the guest OS and DNS - #25

Merged
shenanigansd merged 1 commit into
mainfrom
claude/reserved-ipv6-digitalocean-vkpeam
Aug 30, 2026
Merged

microwave: make the reserved IPv6 live in the guest OS and DNS#25
shenanigansd merged 1 commit into
mainfrom
claude/reserved-ipv6-digitalocean-vkpeam

Conversation

@shenanigansd

Copy link
Copy Markdown
Member

DigitalOcean only routes a reserved IPv6 to the Droplet — it doesn't touch the network config inside it. #23 pointed microwave.box's AAAA at the reserved address, but nothing configured the guest OS, so the address was dead inbound and outbound still originated from the Droplet-native IPv6. This PR finishes the job.

Ansible: new reserved_ipv6 role

  • Installs DO's official outbound-traffic script verbatim (docs) to /usr/local/sbin/reserved-ipv6.sh: reads the metadata endpoint with curl+jq, puts the reserved IPv6 on lo as a /128, and sets the default + on-link IPv6 routes via eth0 with src set to it. The outbound variant is the right one of DO's two scripts because the Droplet has a native IPv6 and outbound connections should originate from the address the AAAA records name. The script is idempotent (replace semantics) and self-cleans if the reserved IP is ever unassigned.
  • Wraps it in a systemd oneshot unit (Wants=/After=network-online.target, RemainAfterExit=yes) since the ip commands don't survive a reboot. No periodic timer: the assignment never expires on DO's side and we don't plan to reassign the address between Droplets.
  • Installs curl and jq; a handler restarts the unit whenever the script or unit file changes (an already-active oneshot unit would otherwise never re-execute).
  • Registered in playbook.yaml between common setup and Docker, so network plumbing lands before anything that generates traffic.

DNS: flip smp-py's AAAA to the reserved address

#23 moved only microwave.box, leaving smp-py on the Droplet-native …e490:a001 — exactly the renumbering cost 33cb842 predicted. The dry-run comment on this PR should show exactly one change: that AAAA update. (This supersedes 0d1dcd3's note that reserved IPs are IPv4-only; DO ships reserved IPv6 now.)

Merge order matters

DNS deploys itself on merge, but Ansible is manual. Run the playbook from this branch before merging (uv run --group ansible ansible-playbook playbook.yaml from ansible/), then verify on the box:

  • systemctl status reserved-ipv6active (exited)
  • curl https://ipv6.icanhazip.com/2604:a880:400:d1:0:4:e4cf:6001
  • reboot and repeat the curl to confirm persistence

Inbound on the native IPv6 keeps working (the address stays on eth0); only unbound outbound sockets move to the reserved address. Clean revert if ever needed: disable the unit, delete the two files, reboot.

Validation

  • prek run --all-files passes (yamlfix no-ops on the new YAML; zizmor verified offline — no workflow changes here)
  • ansible-playbook --syntax-check clean
  • ansible-lint: 0 failures at the production profile

🤖 Generated with Claude Code

https://claude.ai/code/session_011bV3e5JKekeyPVS2e2RzLw


Generated by Claude Code

DigitalOcean only routes a reserved IPv6 to the Droplet; it does not
touch the network config inside it. The new reserved_ipv6 role installs
DO's official outbound-traffic script verbatim (it reads the metadata
endpoint, puts the reserved address on lo as a /128, and sets the
default and on-link IPv6 routes with src set to it) plus a systemd
oneshot unit ordered after network-online.target, since the ip commands
do not survive a reboot. The outbound variant is the right one of DO's
two scripts because the Droplet has a native IPv6 and outbound
connections should originate from the address the AAAA records name.
No periodic timer: the assignment never expires on DO's side and we do
not plan to reassign the address between Droplets.

Also flip the smp-py AAAA to the reserved address. f3b0ab0 moved only
microwave.box, leaving smp-py on the Droplet-native IPv6 -- exactly the
renumbering cost 33cb842 predicted. This supersedes 0d1dcd3's note that
reserved IPs are IPv4-only; DO ships reserved IPv6 now.

Run the playbook before merging: DNS deploys itself on merge, and the
reserved address only answers once the unit has run on the box. Verify
with `curl https://ipv6.icanhazip.com/`.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011bV3e5JKekeyPVS2e2RzLw
@shenanigansd
shenanigansd requested a review from a team as a code owner August 30, 2026 04:10
@github-actions

Copy link
Copy Markdown

OctoDNS Plan for claude/reserved-ipv6-digitalocean-vkpeam

letsbuilda.dev.

cloudflare

Operation Name Type TTL Value Source
Update smp-py AAAA 300 2604:a880:400:d1:0:4:e490:a001
300 2604:a880:400:d1:0:4:e4cf:6001 zone_config

Summary: Creates=0, Updates=1, Deletes=0, Existing=13, Meta=False

@shenanigansd
shenanigansd merged commit 14ce20c into main Aug 30, 2026
5 checks passed
@shenanigansd
shenanigansd deleted the claude/reserved-ipv6-digitalocean-vkpeam branch August 30, 2026 04:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants