LINUX, FOSS AND LIBRARY TECHNOLOGY ENTHUSIAST

Monday, April 7, 2025

Dynamic DNS for IPv6-Only Connections Using Cloudflare and Wildcard Domains

0 comments
As internet service providers (ISPs) begin rolling out IPv6-only connections, many tech-savvy users—especially those trying to self-host services—are facing new challenges. One such example is JioFiber in India, which offers native IPv6 but no public IPv4. If you're trying to run a home server, access a NAS remotely, or manage your smart home dashboard from anywhere, Dynamic DNS (DDNS) becomes essential.

In this post, I’ll guide you through setting up a Dynamic DNS solution for IPv6 using Cloudflare and wildcard domains, ideal for scenarios like these.

The Problem

  • With ISPs like JioFiber:
  • No public IPv4 address
  • Dynamic and often-changing IPv6 addresses
  • Traditional DDNS providers (like No-IP or DynDNS) don't support IPv6-only use cases well
  • Difficult to host or expose services to the public internet

The Solution: Cloudflare DDNS for IPv6

Using Cloudflare’s API and a simple Bash script, we can automatically update a wildcard AAAA (IPv6) DNS record whenever your IPv6 address changes.

This method supports:

  • IPv6-only networks (like JioFiber)
  • Custom domains hosted on Cloudflare
  • Wildcard subdomains (*.yourdomain.com)
  • Linux servers or Raspberry Pi as update clients

Requirements

To implement this, you’ll need:

  • A domain name (e.g., opensio.co.in)
  • Cloudflare DNS for your domain
  • Cloudflare API Token, Zone ID, and Record ID
  • A Linux system with: curl, jq, cron (for automation)

Create a Cloudflare API Token

Log in to your Cloudflare dashboard.

Go to My Profile > API Tokens.

  • Click Create Token.
  • Use the "Edit zone DNS" template.
  • Limit the token’s access to the relevant zone (your domain).
  • Click Continue to Summary and Create Token.
  • Copy and securely store your API token.

Get Your Zone ID and Record ID

Zone ID

Go to your domain’s Overview page in Cloudflare.
Look under API > Zone ID.

DNS Record ID

Use the following command to list DNS records:

curl -X GET "https://api.cloudflare.com/client/v4/zones/YOUR_ZONE_ID/dns_records" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json"

Locate your AAAA record and note its ID.

The Script

Create the script at /usr/local/bin/cloudflare_ddns.sh:

sudo nano /usr/local/bin/cloudflare_ddns.sh

#!/bin/bash
set -euo pipefail
IFS=$'\n\t'

# Cloudflare API details
CLOUDFLARE_API_TOKEN="your_api_token_here"
CLOUDFLARE_ZONE_ID="your_zone_id_here"
CLOUDFLARE_AAAA_RECORD_ID="your_record_id_here"
DOMAIN_NAME="*.opensio.co.in"

# Optional: pass "dry" as the first argument to do a dry run
DRY_RUN=${1:-false}

# Logging function
log() {
  echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"
}

# Get current IPv6 address
CURRENT_IPV6=$(curl -s http://ipv6.icanhazip.com | tr -d '\n')
if [[ -z "$CURRENT_IPV6" ]]; then
  log "No IPv6 address found"
  exit 1
fi

# Fetch current DNS IPv6 from Cloudflare
DNS_IPV6=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$CLOUDFLARE_ZONE_ID/dns_records/$CLOUDFLARE_AAAA_RECORD_ID" \
  -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
  -H "Content-Type: application/json" | jq -r '.result.content // empty')

if [[ -z "$DNS_IPV6" ]]; then
  log "Failed to fetch current DNS IPv6 from Cloudflare"
  exit 1
fi

log "Current DNS IPv6: $DNS_IPV6"
log "Detected system IPv6: $CURRENT_IPV6"

# Update record if IPv6 has changed
if [[ "$CURRENT_IPV6" != "$DNS_IPV6" ]]; then
  if [[ "$DRY_RUN" == "true" ]]; then
    log "[Dry Run] Would update wildcard AAAA record to $CURRENT_IPV6"
    exit 0
  fi

  log "Updating wildcard AAAA record to $CURRENT_IPV6"

  RESPONSE=$(curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$CLOUDFLARE_ZONE_ID/dns_records/$CLOUDFLARE_AAAA_RECORD_ID" \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
    -H "Content-Type: application/json" \
    --data "{\"type\":\"AAAA\",\"name\":\"$DOMAIN_NAME\",\"content\":\"$CURRENT_IPV6\",\"ttl\":1,\"proxied\":false}")

  if echo "$RESPONSE" | jq -e '.success' | grep -q true; then
    log "Update successful!"
  else
    log "Update failed:"
    echo "$RESPONSE"
    exit 1
  fi
else
  log "No change in IPv6. DNS is up to date."
fi

Make the script executable:

sudo chmod +x /usr/local/bin/cloudflare_ddns.sh

Automate with Cron

crontab -e

Add this line to run the script every 5 minutes:

*/1 * * * * /usr/local/bin/cloudflare_ddns.sh >> /var/log/cloudflare_ddns.log 2>&1

Allow Inbound Traffic on JioFiber Router

  • Log in to your JioFiber router admin panel.
  • Navigate to Security > Firewall > IPv6 Firewall Rules.
  • Allow inbound HTTP (port 80), HTTPS (port 443) and SSH (port 22) traffic to your device’s IPv6 address.

You now have a fully functional Dynamic DNS setup for an IPv6-only network using Cloudflare, supporting wildcard subdomains. You can use *.opensio.co.in to access any service you’re hosting at home.

No comments:

Post a Comment