ulygit / asus_rt_ac68u Goto Github PK
View Code? Open in Web Editor NEWConfiguration and script for Cloudflare DDNS on Asuswrt-Merlin
License: MIT License
Configuration and script for Cloudflare DDNS on Asuswrt-Merlin
License: MIT License
is this correct in your docs to leave it blank or should i input a hostname here? also i ran your find / -name ddns-start.log 2>&1
command and it just returned new line. is that correct or should it have returned something?
I can confirm it works on RT-AX58U (firmware version 388.1). Thanks a lot!
Thanks for this! Works flawlessly on my AC66U.
But how can I configure this for multiple subdomains (sub1.domain.com, sub2.domain.com)?
Can I just setup 'domain.com' and the scripts gets the records automatically from the subdomains as I add them in the Cloudflare GUI?
Also, thanks for your very detailed instructions, you made it possible for a noob to set it up! :)
Hello,
The title pretty much covers the question I have, I see no way within the script to determine the router's WAN IP so I was wondering if there's a wrapper script I need to create, or if the router provides its WAN IP as input when it executes the script.
Thank you.
If the throttle value is set below 60 seconds it appears that the last_run_time comparison to current_time will be inaccurate because the last_run_time is recorded in the log only in minutes and thus any call to compare them within the same minute will cause the update to succeed instead of be throttled.
This isn't normally an issue except in testing. However if the value was set to below 60 and a script were to call it frequently, it would execute continuously making calls to cloudflare possibly several times per second.
ive moved some of my stuffs to a vps, what is the best way to disable the script? just delete everything?
.cloudflare
cloudflare_ddns
cloudflare_ddns.log
ddns-start -> cloudflare_ddns
ive left it alone but notice that it kicks my vps ip off and sets the A name to my local ip so i need to do something with it. if i run something locally again i will point it to a subaddress i think.
i think the symbolic link will need to go because i tried to see if i could just switch the DDNS setting back to the free no-ip one i was using before but i think that triggered it to kick my A name back again.
Hey - haven't been here in a while! Script has for the most part been running fine so not much need to revisit.
Are you still using it?
I noticed a problem on my RT-AC68U that I'm wondering if you've seen anything like it?
My ISP is apparently sending me a lease time of only 1 hour on my IPv6 lease which causes a refresh every 30 minutes.
Even though I don't update IPv6 via ddns, this still triggers a custom ddns event on the router.
Normally, this wouldn't be an issue as running the script once every 30 minutes shouldn't be a problem at all (i.e. still well under any limits to update the record with an API call once every 30 minutes).
But if you take a look at my logs you will see something like this:
2023-04-06 12:13:19 UPDATE_SUCCESS {"result":{"id":REDACTED} 2023-04-06 12:43:19 UPDATE_SUCCESS {"result":{"id":REDACTED} 2023-04-06 13:13:19 UPDATE_SUCCESS {"result":{"id":REDACTED} 2023-04-06 13:43:19 UPDATE_SUCCESS {"result":{"id":REDACTED} 2023-04-06 14:13:19 UPDATE_SUCCESS {"result":{"id":REDACTED} 2023-04-06 14:43:20 UPDATE_SUCCESS {"result":{"id":REDACTED} 2023-04-06 15:13:20 UPDATE_SUCCESS {"result":{"id":REDACTED} 2023-04-06 15:43:20 UPDATE_SUCCESS {"result":{"id":REDACTED} 2023-04-06 15:43:22 UPDATE_THROTTLED 2023-04-06 15:43:52 UPDATE_THROTTLED 2023-04-06 15:44:22 UPDATE_THROTTLED 2023-04-06 15:44:52 UPDATE_THROTTLED 2023-04-06 15:45:22 UPDATE_THROTTLED 2023-04-06 15:45:52 UPDATE_THROTTLED 2023-04-06 15:46:22 UPDATE_THROTTLED 2023-04-06 15:46:52 UPDATE_THROTTLED 2023-04-06 15:47:22 UPDATE_THROTTLED 2023-04-06 15:47:52 UPDATE_THROTTLED 2023-04-06 15:48:23 UPDATE_SUCCESS {"result":{"id":REDACTED} 2023-04-06 16:13:20 UPDATE_SUCCESS {"result":{"id":REDACTED} 2023-04-06 16:43:21 UPDATE_SUCCESS {"result":{"id":REDACTED}
So what you are seeing is that most of the time everything is going fine every 30 mins. But occasionally you get what you see at the 15:43:20 timestamp. Namely that the update succeeds, but then the script is run again multiple times and keeps failing due to the throttling (since it was just properly updated). This continues for the 300 seconds of throttle until what you get at the 15:48:23 timestamp when it finally succeeds again.
Then you see it continues on normally working every 30 minutes.
This isn't a failure of the script, but rather something funky happening on the merlin. This is what the normal syslog entries look like when it updates properly just the once:
Apr 6 15:13:18 rc_service: dhcp6c 23328:notify_rc restart_ddns Apr 6 15:13:18 custom_script: Running /jffs/scripts/service-event (args: restart ddns) Apr 6 15:13:18 start_ddns: update CUSTOM , wan_unit 0 Apr 6 15:13:18 custom_script: Running /jffs/scripts/ddns-start (args: XX.XX.XX.XX) Apr 6 15:13:20 ddns: Completed custom ddns update Apr 6 15:13:20 custom_script: Running /jffs/scripts/service-event-end (args: restart ddns)
But when it fails it looks like this:
Apr 6 15:43:18 rc_service: dhcp6c 28346:notify_rc restart_ddns Apr 6 15:43:18 custom_script: Running /jffs/scripts/service-event (args: restart ddns) Apr 6 15:43:19 start_ddns: update CUSTOM , wan_unit 0 Apr 6 15:43:19 custom_script: Running /jffs/scripts/ddns-start (args: XX.XX.XX.XX) Apr 6 15:43:20 watchdog: start ddns. Apr 6 15:43:20 rc_service: watchdog 396:notify_rc start_ddns Apr 6 15:43:20 rc_service: waitting "restart_ddns" via ... Apr 6 15:43:20 ddns: Completed custom ddns update Apr 6 15:43:20 custom_script: Running /jffs/scripts/service-event-end (args: restart ddns) Apr 6 15:43:21 custom_script: Running /jffs/scripts/service-event (args: start ddns) Apr 6 15:43:22 start_ddns: update CUSTOM , wan_unit 0 Apr 6 15:43:22 custom_script: Running /jffs/scripts/ddns-start (args: XX.XX.XX.XX) Apr 6 15:43:22 ddns: Custom ddns update failed Apr 6 15:43:22 custom_script: Running /jffs/scripts/service-event-end (args: start ddns) Apr 6 15:43:51 watchdog: start ddns. Apr 6 15:43:51 rc_service: watchdog 396:notify_rc start_ddns Apr 6 15:43:51 custom_script: Running /jffs/scripts/service-event (args: start ddns) Apr 6 15:43:52 start_ddns: update CUSTOM , wan_unit 0 Apr 6 15:43:52 custom_script: Running /jffs/scripts/ddns-start (args: XX.XX.XX.XX) Apr 6 15:43:52 ddns: Custom ddns update failed Apr 6 15:43:52 custom_script: Running /jffs/scripts/service-event-end (args: start ddns) Apr 6 15:44:21 watchdog: start ddns. Apr 6 15:44:21 rc_service: watchdog 396:notify_rc start_ddns Apr 6 15:44:21 custom_script: Running /jffs/scripts/service-event (args: start ddns) Apr 6 15:44:22 start_ddns: update CUSTOM , wan_unit 0 Apr 6 15:44:22 custom_script: Running /jffs/scripts/ddns-start (args: XX.XX.XX.XX) Apr 6 15:44:22 ddns: Custom ddns update failed Apr 6 15:44:22 custom_script: Running /jffs/scripts/service-event-end (args: start ddns) Apr 6 15:44:51 watchdog: start ddns. Apr 6 15:44:51 rc_service: watchdog 396:notify_rc start_ddns Apr 6 15:44:51 custom_script: Running /jffs/scripts/service-event (args: start ddns) Apr 6 15:44:52 start_ddns: update CUSTOM , wan_unit 0 Apr 6 15:44:52 custom_script: Running /jffs/scripts/ddns-start (args: XX.XX.XX.XX) Apr 6 15:44:52 ddns: Custom ddns update failed Apr 6 15:44:52 custom_script: Running /jffs/scripts/service-event-end (args: start ddns) Apr 6 15:45:21 watchdog: start ddns. Apr 6 15:45:21 rc_service: watchdog 396:notify_rc start_ddns Apr 6 15:45:21 custom_script: Running /jffs/scripts/service-event (args: start ddns) Apr 6 15:45:22 start_ddns: update CUSTOM , wan_unit 0 Apr 6 15:45:22 custom_script: Running /jffs/scripts/ddns-start (args: XX.XX.XX.XX) Apr 6 15:45:22 ddns: Custom ddns update failed Apr 6 15:45:22 custom_script: Running /jffs/scripts/service-event-end (args: start ddns) Apr 6 15:45:51 watchdog: start ddns. Apr 6 15:45:51 rc_service: watchdog 396:notify_rc start_ddns Apr 6 15:45:51 custom_script: Running /jffs/scripts/service-event (args: start ddns) Apr 6 15:45:52 start_ddns: update CUSTOM , wan_unit 0 Apr 6 15:45:52 custom_script: Running /jffs/scripts/ddns-start (args: XX.XX.XX.XX) Apr 6 15:45:52 ddns: Custom ddns update failed Apr 6 15:45:52 custom_script: Running /jffs/scripts/service-event-end (args: start ddns) Apr 6 15:46:21 watchdog: start ddns. Apr 6 15:46:21 rc_service: watchdog 396:notify_rc start_ddns Apr 6 15:46:21 custom_script: Running /jffs/scripts/service-event (args: start ddns) Apr 6 15:46:22 start_ddns: update CUSTOM , wan_unit 0 Apr 6 15:46:22 custom_script: Running /jffs/scripts/ddns-start (args: XX.XX.XX.XX) Apr 6 15:46:22 ddns: Custom ddns update failed Apr 6 15:46:22 custom_script: Running /jffs/scripts/service-event-end (args: start ddns) Apr 6 15:46:51 watchdog: start ddns. Apr 6 15:46:51 rc_service: watchdog 396:notify_rc start_ddns Apr 6 15:46:51 custom_script: Running /jffs/scripts/service-event (args: start ddns) Apr 6 15:46:52 start_ddns: update CUSTOM , wan_unit 0 Apr 6 15:46:52 custom_script: Running /jffs/scripts/ddns-start (args: XX.XX.XX.XX) Apr 6 15:46:52 ddns: Custom ddns update failed Apr 6 15:46:52 custom_script: Running /jffs/scripts/service-event-end (args: start ddns) Apr 6 15:47:21 watchdog: start ddns. Apr 6 15:47:21 rc_service: watchdog 396:notify_rc start_ddns Apr 6 15:47:21 custom_script: Running /jffs/scripts/service-event (args: start ddns) Apr 6 15:47:22 start_ddns: update CUSTOM , wan_unit 0 Apr 6 15:47:22 custom_script: Running /jffs/scripts/ddns-start (args: XX.XX.XX.XX) Apr 6 15:47:22 ddns: Custom ddns update failed Apr 6 15:47:22 custom_script: Running /jffs/scripts/service-event-end (args: start ddns) Apr 6 15:47:51 watchdog: start ddns. Apr 6 15:47:51 rc_service: watchdog 396:notify_rc start_ddns Apr 6 15:47:51 custom_script: Running /jffs/scripts/service-event (args: start ddns) Apr 6 15:47:52 start_ddns: update CUSTOM , wan_unit 0 Apr 6 15:47:52 custom_script: Running /jffs/scripts/ddns-start (args: XX.XX.XX.XX) Apr 6 15:47:52 ddns: Custom ddns update failed Apr 6 15:47:52 custom_script: Running /jffs/scripts/service-event-end (args: start ddns) Apr 6 15:48:21 watchdog: start ddns. Apr 6 15:48:21 rc_service: watchdog 396:notify_rc start_ddns Apr 6 15:48:21 custom_script: Running /jffs/scripts/service-event (args: start ddns) Apr 6 15:48:22 start_ddns: update CUSTOM , wan_unit 0 Apr 6 15:48:22 custom_script: Running /jffs/scripts/ddns-start (args: XX.XX.XX.XX) Apr 6 15:48:23 ddns: Completed custom ddns update Apr 6 15:48:23 custom_script: Running /jffs/scripts/service-event-end (args: start ddns)
There is that "watchdog" line near the top of the problematic set. I'm not exactly sure what is happening but it is like this watchdog is jumping in and doing another restart right after the normal update is triggered causing this throttle loop.
I know this isn't a direct script issue, but I'm thinking about ways to mitigate this. Maybe there is something malfunctioning on my device, but I can't see what that is. I posted over in the merlin forums (no good feedback yet), but because those using this script are more likely to be paying attention to these matters I wanted to bring it up here to see if there were any ideas?
I'm not sure what is going on here with CF API.
Seems like they made a few changes.
I can't update my records anymore because I get the above error. Log looks more like:
"errors": [ { "code": 9021, "message": "Invalid TTL. Must be between 120 and 2,147,483,647 seconds, or 1 for automatic" } ], "messages": []
Seems they are insisting the TTL is actually sent as part of the request now as opposed to just assuming the default (Auto). To set to auto you need to send integer 1.
Existing code can be fixed by changing:
Lines 51 to 52 in 116e522
to:
curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$DNS_ZONE_ID/dns_records/$DNS_RECORD_ID" \ --data "{\"type\":\"$DNS_RECORD_TYPE\",\"name\":\"$DNS_RECORD_NAME\",\"content\":\"$NEW_IP\",\"TTL\":1}"
After that I was able to successfully update.
Tried it on Asus GT-AX11000 and it worked flawlessly, merlin 386.2_6.
Thanks for your script and keep up the great work. :)
Cheers
So again, I'm going to assume that CF API is returning data differently as we now get the following error on all runs after initial run where log file is created:
# ./cloudflare_ddns 6.6.6.7
date: invalid date '}'
expr: syntax error
[: 1579631234: unknown operand
Issue appears to be from the following:
Line 84 in 116e522
When we sort and grep on the log file we get entries like the following:
s# sort -r cloudflare_ddns.log | grep -vm1 THROTTLED
}
Head of sorted log:
s# sort -r cloudflare_ddns.log | head -n7
}
}
}
}
2020-01-21 12:27 UPDATE_SUCCESS {
2020-01-21 12:26 UPDATE_THROTTLED
2020-01-21 12:26 UPDATE_SUCCESS {
So the operand is failing because it isn't matching a date on the "}" entries.
As I don't recall this being a problem before I can only assume that the return output from CF is now different and it appends this extra bracket on.
Seems like we can fix this by skipping those entries, like:
last_run_time=$(date -d "$(sort -r $LOGFILE | grep -v '}' | grep -vm1 THROTTLED | cut -f 1)" +%s)
I've got a unique need to update multiple records, one set to proxy and the other not proxied but both updated from the same router.
Hey - So I know I mentioned that I had moved off the script to the inadyn services, but it turns out I actually needed to use the script again for another purpose. I had an older Asus RT-N66 router that only supports up to FW 380.70 and therefore doesn't have inadyn support. I was setting this device up as a VPN Server box for my folks and needed the ability to keep the ddns functionality.
Anyway, I could not get the script to function at all on the box, even after a fresh install or porting it directly over from my other config. After messing around for a while, it seems to me that something about this RT-N66/FW 380.70 combination does not properly support the HEREDOC format used in the script.
Specifically, I'm talking about these lines:
Line 92 in 37c6e6c
update_record()
{
debug "update_record"
curl --silent --show-error --request PUT "https://api.cloudflare.com/client/v4/zones/$DNS_ZONE_ID/dns_records/$DNS_RECORD_ID" \
--data "{\"type\":\"$DNS_RECORD_TYPE\",\"name\":\"$DNS_RECORD_NAME\",\"content\":\"$NEW_IP\",\"ttl\":1,\"proxied\":$DNS_RECORD_PROXIED}" \
-H @- <<- HEADERS
$CLOUDFLARE_AUTH_HEADERS
Content-Type: application/json
HEADERS
}
I attempted to execute similar command entirely outside of the script using the following:
admin@RT-N66W-19D8:/jffs/scripts/cloudflare-ddns# CLOUDFLARE_AUTH_HEADERS="Authorization: Bearer XXXXXXXXXXXXXXXXXXXXX"
admin@RT-N66W-19D8:/jffs/scripts/cloudflare-ddns# curl --show-error --request PUT https://api.cloudflare.com/client/v4/zones/XXX/dns_records/XXX --data {\"type\":\"A\",\"name\":\"access.mydomain.com\",\"content\":\"75.X.X.X\",\"ttl\":1,\"proxied\":false} -H @- <<- HEADERS
> $CLOUDFLARE_AUTH_HEADERS
> Content-Type: application/json
> HEADERS
{"success":false,"errors":[{"code":9106,"message":"Missing X-Auth-Key, X-Auth-Email or Authorization headers"}]}
You can see this command fails saying that there are no Authorization headers because somehow the HEREDOC syntax isn't working on this box. These exact same commands function properly on my AC68U which is where I have previously used the script for years.
If instead of using the HEREDOC format I simply append the headers as normal variables as such, the operation succeeds:
admin@RT-N66W-19D8:/jffs/scripts/cloudflare-ddns# curl --show-error --request PUT https://api.cloudflare.com/client/v4/zones/XXX/dns_records/XXX
73460b95896bf --data {\"type\":\"A\",\"name\":\"access.mydomain.com\",\"content\":\"75.X.X.X\",\"ttl\":1,\"proxied\":false} -H "$CLOUDFLARE_AUTH_HEADERS" -H "Content-Type: application/js
on"
{"result":{"id":"XXXXXX","zone_id":"XXXXXXX","zone_name":"mydomain.com","name":"access.mydomain.com","type":"A","content":"75.X.X.X","proxiable":true,"proxied":false,"ttl":1,"locked":false,"meta":{"auto_added":false,"managed_by_apps":false,"managed_by_argo_tunnel":false},"comment":null,"tags":[],"created_on":"2020-10-11T22:35:14.994266Z","modified_on":"2023-04-25T16:22:25.756244Z"},"success":true,"errors":[],"messages":[]}
I can't explain this. The "sh" shell on the router doesn't support a --version
command, but using the following script I determined that both systems report as:
SVR4 Bourne shell (SunOS 5 schily variant, since 2016-08-08, in posix mode)
So the shells report exactly the same and as such I would expect them to support the same syntax. The version of curl on my N66 is a bit older, but I don't think that would account for the issue using this syntax.
Finally, my AC68U does have entware installed whereas the N66 did not. But, just like the curl version above, I don't think updated versions of grep, etc would make the difference here for this syntax.
I don't recall (if I knew) why the original script preferred the HEREDOC format here instead of simply appending the variables as per my workaround. If anything, the HEREDOC format would probably have made the --data
string more readable instead of using for headers.
In any event, I don't know if the script needs updating due to its deprecation, but I did want to log this issue here in case anyone else might happen to come across it and face a similar issue. Again, this seems to be an inability of some shell versions to not support HEREDOC.
EDIT: Upon some more testing I'm not sure if HEREDOC is the issue or the way that the shell is accepting standard in (@-)
weird.
Just wanted to give you a heads up, I tested the script on my ASUS RT-AX88U, merlin 384.11_2.
Works great :)
Thank you
I can confirm it works on RT-AC3200 (firmware version 384.13_10).
Thanks a lot!
it works on RT-AC88U tested!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.