What's new

Custom DDNS failing

  • SNBForums Code of Conduct

    SNBForums is a community for everyone, no matter what their level of experience.

    Please be tolerant and patient of others, especially newcomers. We are all here to share and learn!

    The rules are simple: Be patient, be nice, be helpful or be gone!

D34DC3N73R

Occasional Visitor
I've used the DDNS sample script for cloudflare, but it doesn't seem to be working and I'm not seeing enough detail to figure out why it's not working. I have an RT-AC88U on 380.69

/jffs/scripts/ddns-start
Code:
#!/bin/sh

EMAIL="admin@domain.tld"
ZONEID="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
RECORDID="xxxxxxxxxx"
RECORDNAME="domain.tld"
API="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
IP=${1}

curl -fs -o /dev/null -X PUT "https://api.cloudflare.com/client/v4/zones/$ZONEID/dns_records/$RECORDID" \
  -H "X-Auth-Email: $EMAIL" \
  -H "X-Auth-Key: $API" \
  -H "Content-Type: application/json" \
  --data "{\"type\":\"A\",\"name\":\"$RECORDNAME\",\"content\":\"$IP\",\"ttl\":120,\"proxied\":false}"

if [ $? -eq 0 ]; then
  /sbin/ddns_custom_updated 1
else
  /sbin/ddns_custom_updated 0
fi

When running the script or saving the DDNS section, I get a warning prompt "Request error! Please try again."

The system log shows:

Mar 17 18:56:31 rc_service: watchdog 617:notify_rc start_ddns
Mar 17 18:56:31 custom_script: Running /jffs/scripts/ddns-start (args: xxx.xxx.xxx.xxx)
Mar 17 18:56:33 ddns: Custom ddns update failed
 
Last edited:
If you try running the curl command with the values entered from the command line does it succeed?
 
The command appears to run successfully. However, when I enter a different ip address than my current ip, and log into CF no change has been made. All the A records still point to my current/original ip.
 
Appreciate the effort. I'm also new to cloudflare, but it seems straightforward enough (with the exception of debugging this api call). I've whitelisted all of CFs ip ranges and still haven't come up with anything.
 
modified the curl command to output the response from cloudflare.
Code:
{
  "success": false,
  "errors": [
    {
      "code": 7003,
      "message": "Could not route to \/zones\/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\/dns_records\/xxxxxxxxxx, perhaps your object identifier is invalid?"
    },
    {
      "code": 7000,
      "message": "No route for that URI"
    }
  ],
  "messages": [
  
  ],
  "result": null
}

I double checked the zone and reran the following to check my record id was correct (it was)
Code:
curl https://www.cloudflare.com/api_json.html \
  -d a=rec_load_all \
  -d tkn=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \
  -d email=admin@domain.tld \
  -d z=domain.tld

Not really sure what the problem is since I just double checked the zone and record id. I wouldn't be able to attain the record id if my email or api key were incorrect. Certainly would appreciate any other ideas or advice.
 
I made some progress and can manually update ip via command line. However, after replacing the curl command in the script and then running the script I get the error "Record content cannot be empty." It did not seem like the ip variable was being set.

So, I modified the script which relies on a third party site ifconfig.co to get wan ip.

Code:
#!/bin/sh

EMAIL="admin@domain.tld"
RECORDID="xxxxxxxxxx"
RECORDNAME="domain.tld"
API="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
IP="$(curl -s v4.ifconfig.co)"

curl -fs -o /dev/null https://www.cloudflare.com/api_json.html \
  -d a=rec_edit \
  -d tkn=$API \
  -d id=$RECORDID \
  -d email=$EMAIL \
  -d z=$RECORDNAME \
  -d type=A \
  -d name=$RECORDNAME \
  -d ttl=120 \
  -d content=$IP

if [ $? -eq 0 ]; then
  /sbin/ddns_custom_updated 1
else
  /sbin/ddns_custom_updated 0
fi

I would like to find out why IP doesn't return anything on the default script so I don't have to rely on ifconfig.co. I'm not sure why the original script wasn't working for me in the first place. Also, I basically have no idea what I'm doing so I'm not sure what the benefits/drawbacks are to this approach over the default script.
 
Anyone else out there using custom DDNS? Any ideas why ${1} isn't returning the wan ip? Any insight as to where that code is located would be appreciated too. FWIW, the correct WAN ip is displayed upon logging in.
 
I have used custom DDNS before, but currently not using it with 384.4, but it should be the same.

This is a script that I used for DuckDNS, with ipv6, and ${1} definitely has the WAN ip.
I would suggest, using logger, to print the string so you see what is going on.

Code:
#!/bin/sh

I4=${1}
IPRE=$(nvram get ipv6_prefix)
I6=${IPRE/::/:215:5dff:fe01:be2e}


# register a subdomain at https://www.duckdns.org/ to get your token
SUBDOMAIN="xxxxx"
TOKEN="yyyyyyyyyyy"


if [ -n "$I6" ]; then
        curl --silent "https://www.duckdns.org/update?domains=$SUBDOMAIN&token=$TOKEN&ip=$I4&ipv6=$I6" >/dev/null 2>&1
        if [ $? -eq 0 ]; then
                logger "DDNS updated: $I4 $I6"
                    /sbin/ddns_custom_updated 1
            else
                logger "DDNS Error: $I4 $I6"
                    /sbin/ddns_custom_updated 0
            fi
    else
        logger "DDNS: IP Address for $I6 needed"
        /sbin/ddns_custom_updated 0
    fi
 
Thanks! I was able to get the wan ip using `nvram get wan0_ipaddr`. I've since upgraded to 384.4_2 but still couldn't get the ${1} variable to work. However, I'm pretty happy with this solution so it's probably going to stay this way.
 
If you are talking about the $1 argument passed to the script which contains WAN IP address as known by the router - it is passed to the script only when the router calls it after eg. a boot

Code:
Aug  1 02:00:31 custom script: Running /jffs/scripts/ddns-start (args: 192.168.10.10)

Plus, in the above situation, NTP was not yet done so https will fail at this point, too. OK, in my case, this is a DoubleNAT situation, but is irrelevant here.

If you run this script manually you would have to call it with the WAN IP adddress which you entered as an argument to the script. Or use external info. Or read it from the router (NVRAM).
 
If you are talking about the $1 argument passed to the script which contains WAN IP address as known by the router - it is passed to the script only when the router calls it after eg. a boot

Code:
Aug  1 02:00:31 custom script: Running /jffs/scripts/ddns-start (args: 192.168.10.10)

Plus, in the above situation, NTP was not yet done so https will fail at this point, too. OK, in my case, this is a DoubleNAT situation, but is irrelevant here.

If you run this script manually you would have to call it with the WAN IP adddress which you entered as an argument to the script. Or use external info. Or read it from the router (NVRAM).

Thanks for the insight. When trying to get the $1 variable I was also trying regular boots in addition to running the script manually, so I'm not sure what the issue was but I'm happy getting the IP from NVRAM.
 
FYI for anyone who stumbles across this, that API is now depreciated. I was able to update my script to the V4 API. (Which is essentially the same as the sample script). The issue I had earlier is I was pulling the record ID using the old API, and apparently, that record ID is not the same as the V4 record ID. Here is the curl command to pull your A records. (More info here to parse pages/ results per page etc)

Code:
curl -X GET "https://api.cloudflare.com/client/v4/zones/$ZONEID/dns_records?type=A" \
     -H "X-Auth-Email: $EMAIL" \
     -H "X-Auth-Key: $API" \
     -H "Content-Type: application/json"

The ID of each record is listed in the response. I still use NVRAM to pull WAN IP.
 

Sign Up For SNBForums Daily Digest

Get an update of what's new every day delivered to your mailbox. Sign up here!
Top