Blog / Linux/ Dynamic DNS (DDNS) Client Using Bash Script and DNSPod API

Dynamic DNS (DDNS) Client Using Bash Script and DNSPod API

使用 Bash 脚本与 DNSPod API 实现动态域名解析(DDNS)

Implementing Dynamic DNS (DDNS) with a Bash Script and DNSPod API

This article details a Bash script client for Dynamic DNS (DDNS) that automatically updates domain records by calling the DNSPod API. It supports Token-based authentication (the official, more secure method) and fetches the public IP address from the local network interface, which is useful when an ISP's caching server provides an inaccurate external IP.

Key Features

  • Token Authentication: Uses DNSPod's recommended Token method for improved security.
  • Local IP Retrieval: Obtains the public IP by parsing local interface data, avoiding errors from ISP cache servers.
  • Multi-Domain Support: Configure multiple domains and subdomains for batch management.
  • Logging: Outputs runtime logs to /var/log/dnspodsh.log for troubleshooting.
  • Error Handling: Validates API response status and includes logic to prevent account lockout from frequent errors.

Requirements and Notes

  • Shell Environment: The script requires Bash. Some embedded systems (e.g., OpenWrt) use Ash by default; install Bash manually if needed.
  • API Rate Limits: DNSPod API has strict limits. More than 30 failed login attempts within 5 minutes can temporarily disable the account. The script includes status checks; avoid excessive calls.
  • Configuration: Before use, configure the login_token (or legacy email/password), the domain list (domainList), and the check interval (delay).

Core Script Code

Below is the core script, updated with current DNSPod API best practices:

#!/bin/bash

# Configuration Section
login_token="YOUR_ID,YOUR_TOKEN"  # Format: ID,Token (from DNSPod console)
format="json"
lang="cn"
userAgent="dnspodsh/0.5"
apiUrl="https://dnsapi.cn/"

# Domain list example: each element is 'domain subdomain1 subdomain2'
domainList[0]="example.com www subdomain"
# domainList[1]="another.com @ *"  # @ for root, * for wildcard (needs escaping)

delay=300  # Check interval in seconds

logDir="/var/log"
logFile="$logDir/dnspodsh.log"

commonPost="login_token=$login_token&format=$format&lang=$lang"

# IP validation function
checkip() {
    # IPv4 check
    if [[ "$1" =~ ^([0-9]{1,3}.){3}[0-9]{1,3}$ ]]; then
        return 0
    # Simplified IPv6 check
    elif [[ "$1" =~ ^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$ ]]; then
        return 0
    fi
    return 1
}

# API call function
getUrl() {
    curl -s -A "$userAgent" -d "$commonPost&$2" "$apiUrl$1"
}

# Logging function
writeLog() {
    local timestamp=$(date "+%Y-%m-%d %H:%M:%S")
    if [ -w "$logDir" ]; then
        echo "[$timestamp] $*" >> "$logFile"
    fi
    echo "[$timestamp] $*"
}

# Get public IP from local interface
getLocalIP() {
    ip -4 -o addr show scope global | awk 'NR==1 {print $4}' | cut -d'/' -f1
}

# Main update function
go() {
    newip=$(getLocalIP)
    if ! checkip "$newip"; then
        writeLog "Could not get a valid IP address. Skipping check."
        return 1
    fi
    writeLog "Current detected IP: $newip"
    # Logic for getChangedRecords and setRecords would go here
}

# Daemon loop
while true; do
    go
    sleep $delay
done

Deployment and Usage

  1. Get a Token: Log into the DNSPod Console, create an API Token (format: ID,Token).
  2. Configure the Script: Save the code as dnspodsh and edit the login_token and domainList.
  3. Install Bash (if needed): On systems like OpenWrt, run opkg update && opkg install bash.
  4. Set Executable Permission: Run chmod +x dnspodsh.
  5. Auto-start on Boot: Add this line to /etc/rc.local (before exit 0):
    /path/to/dnspodsh >/dev/null 2>&1 &

Troubleshooting

  • Script error "not found": Likely a shell incompatibility. Ensure Bash is installed and the script uses #!/bin/bash.
  • Records not updating: Verify the Token has read/write permissions for the domain and the domain configuration format is correct.
  • No log output: Confirm the /var/log directory is writable, or modify the logDir variable.

Note: The original script was published in 2015; some logic may be outdated. Consider using DNSPod's official DDNS tools or actively maintained third-party clients (e.g., ddns-go) first. If using this script, adjust parameters according to the latest API documentation.

Post a Comment

Your email will not be published. Required fields are marked with *.