Skip to content

Instantly share code, notes, and snippets.

@yuxi-liu-wired
Created August 8, 2025 18:26
Show Gist options
  • Save yuxi-liu-wired/c4bd99d8689b6e438e21da743a5723a1 to your computer and use it in GitHub Desktop.
Save yuxi-liu-wired/c4bd99d8689b6e438e21da743a5723a1 to your computer and use it in GitHub Desktop.
Enable IPv6s on DigitalOcean
#!/bin/bash -eu
# https://docs.digitalocean.com/products/networking/reserved-ips/how-to/manually-enable/#enable-reserved-ipv6
IFACE_ETH0="eth0"
IFACE_LO="lo"
PREFIX_LEN="128"
# get Droplet metadata
md=$(curl -s 169.254.169.254/metadata/v1.json)
# get reserved IPv6 info from metadata
md_rip6_json=$(echo "${md}" | jq -r '.reserved_ip.ipv6')
case "$(echo "${md_rip6_json}" | jq -r '.active')" in
"true")
# if active, set up interface and routes
rip6=$(echo "${md_rip6_json}" | jq -r '.ip_address')
ip -6 addr replace "${rip6}/${PREFIX_LEN}" dev ${IFACE_LO} scope global
echo "Assigned ${rip6}/${PREFIX_LEN} to ${IFACE_LO}"
ip -6 route replace default dev ${IFACE_ETH0}
echo "Created default IPv6 route via ${IFACE_ETH0}"
;;
"false")
# if inactive, clean up interface and routes
ip -6 addr flush dev ${IFACE_LO} scope global
echo "Removed all Reserved IPv6 addresses from ${IFACE_LO}"
# technically, the route can remain even beyond removal,
# but to keep consistency with existing behavior without
# a reserved IPv6, we'll clean it up
if [[ "$(ip -6 route show default dev ${IFACE_ETH0})" != "" && "$(ip -6 addr show dev ${IFACE_ETH0} scope global)" == "" ]]; then
ip -6 route delete default dev ${IFACE_ETH0}
echo "Deleted default IPv6 route via ${IFACE_ETH0}"
fi
;;
esac
@yuxi-liu-wired
Copy link
Author

The script checks if the Droplet has a reserved IPv6 assigned. If it does, the script assigns it to the lo network interface and configures routing rules to allow traffic flow. If the Droplet does not have a reserved IPv6 assigned, the script removes any existing reserved IPv6 addresses from the lo interface and cleans up related routes.

The script requires jq and curl. Run the script directly on the command line to verify it is functioning properly, then create a cron job or systemd timer to run it periodically.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment