Compare commits

...

23 Commits

Author SHA1 Message Date
M_Viper af4070c54e „README.md“ ändern 2023-08-15 09:33:30 +02:00
Jason K 88c73e30f8
Merge pull request #36 from AgingOrange/main
Add Discord notification. Rename slacksitename to sitename as they wi…
2022-04-06 22:07:56 +08:00
AgingOrange 6af3585c79 Add Discord notification. Rename slacksitename to sitename as they will probably be the same. 2022-03-31 07:15:08 +02:00
Jason K d9ad375827
Merge pull request #34 from 9cco/alternative-ip-resolver
Added cloudflare.com as default ip lookup
2022-03-23 18:03:45 +08:00
9cco 00db8af28f Stricter regex, should now catch all false positives 2022-03-12 12:45:16 +01:00
9cco 08ef1d559d Add cloudflare ip lookup. Remove unnecessary feats
Added https:/cloudflare.com/cd-cgi/trace as default ip lookup method.
Removed possibility of MiTM attack through dig. Cleaned script of
unnecessary check for command existance.
2022-02-27 13:44:48 +01:00
9cco 46ea8de30c Added cloudflare.com as a way of finding the ip 2022-02-26 12:09:26 +01:00
9cco 6a50f940cb Incorporating feedback
Changed the way we generate the api data back to the original. Clarified
comments. Added more logic to how we obtain the public IPv4 address,
such that input is sanitized.

If curl is not found, then the rest of the script can't run so we exit
with an error code. We try to use DNS if HTTPS fails to obtain
a valid IP. Added log messages for these events.
2022-02-26 11:10:26 +01:00
Jason K 27e396cccc
Update README.md 2022-02-26 10:37:01 +08:00
9cco ebcc60faa3 Improved regex as pr timetoexpire comment 2022-02-26 02:46:48 +01:00
9cco 9d2e7fcc8a Taking feedback from timetoexpire
Changed back so that curl is used by default, however dig can be used
as a backup if curl is not installed on the system. Additionally took
my fear of code injection into account by sanitizing the remote input
through a regex.
2022-02-25 12:24:17 +01:00
9cco ff6a8df63c Fixed problem with dig not always giving correct output 2022-02-19 12:35:53 +01:00
9cco e8873cc328 Added dig as possible ip resolver
Used shell built-in command -v to determine if dig is installed and if
it is, use it as default for getting the ip-address. Also made the use
of brackets consistent and updated the the way the data variable is
created before it is sent with curl to make it more readable in the
code.
2022-02-13 17:11:22 +01:00
Jason K 901fdb403c
Update README.md 2021-12-07 23:00:47 +08:00
Jason K f556d0e5dd
Merge pull request #25 from clementnuss/optional-slack
fix: make slack integration optional when uri not specified
2021-11-06 17:59:28 +08:00
Clément Nussbaumer d13ba926f3 fix: make slack integration optional when uri not specified 2021-11-06 10:41:41 +01:00
Jason K fba6204554
Merge pull request #24 from northportio/main
Added Slack Integration
2021-11-05 21:27:03 +08:00
Northport IO 6ae5bd5c44
Added Slack Integration 2021-10-25 16:43:20 -04:00
Jason K d151789229
Merge pull request #20 from Sailboat265/main
Fix duplicate record and record being mysteriously deleted
2021-10-23 15:35:39 +08:00
Sailboat265 7f1e80e000 Update cloudflare-template.sh 2021-10-21 01:38:10 +08:00
Jason K ca4d5fd535
Update cloudflare-template.sh 2021-08-21 14:42:18 +08:00
Jason K d8ceb1ba4b
Merge pull request #8 from clementnuss/main
replace PCRE regexp with standard regexp
2021-08-19 13:18:52 +08:00
Clément Nussbaumer ea68158b97 replace PCRE regexp with standard regexp
Permits to run the script on simpler/lighter Linux distributions,
e.g. OpenWRT, where the grep utility available does not permit to use
Perl extended regexp (the `grep -P` option)
2021-08-12 14:26:15 +02:00
2 changed files with 62 additions and 49 deletions

View File

@ -1,34 +1,4 @@
# Cloudflare Dynamic DNS IP Updater # Cloudflare Dynamic DNS IP Updater
<img alt="GitHub" src="https://img.shields.io/github/license/K0p1-Git/cloudflare-ddns-updater?color=black"> <img alt="GitHub last commit (branch)" src="https://img.shields.io/github/last-commit/K0p1-Git/cloudflare-ddns-updater/main"> <img alt="GitHub contributors" src="https://img.shields.io/github/contributors/K0p1-Git/cloudflare-ddns-updater">
This script is used to update dynamic DNS entries for accounts on Cloudflare.
## Installation This script is used to update Dynamic DNS (DDNS) service based on Cloudflare! Access your home network remotely via a custom domain name without a static IP! Written in pure BASH.
```bash
git clone https://github.com/K0p1-Git/cloudflare-ddns-updater.git
```
## Usage
This script is used with crontab. Specify the frequency of execution through crontab.
```bash
# ┌───────────── minute (0 - 59)
# │ ┌───────────── hour (0 - 23)
# │ │ ┌───────────── day of the month (1 - 31)
# │ │ │ ┌───────────── month (1 - 12)
# │ │ │ │ ┌───────────── day of the week (0 - 6) (Sunday to Saturday 7 is also Sunday on some systems)
# │ │ │ │ │ ┌───────────── command to issue
# │ │ │ │ │ │
# │ │ │ │ │ │
# * * * * * /bin/bash {Location of the script}
```
## Contributing
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
## Reference
This script was made with reference from [Keld Norman](https://www.youtube.com/watch?v=vSIBkH7sxos) video.
## License
[MIT](https://github.com/K0p1-Git/cloudflare-ddns-updater/blob/main/LICENSE)

View File

@ -1,28 +1,42 @@
#!/bin/bash #!/bin/bash
## change to "bin/sh" when necessary
auth_email="" # The email used to login 'https://dash.cloudflare.com' auth_email="" # The email used to login 'https://dash.cloudflare.com'
auth_method="token" # Set to "global" for Global API Key or "token" for Scoped API Token auth_method="token" # Set to "global" for Global API Key or "token" for Scoped API Token
auth_key="" # Your API Token or Global API Key auth_key="" # Your API Token or Global API Key
zone_identifier="" # Can be found in the "Overview" tab of your domain zone_identifier="" # Can be found in the "Overview" tab of your domain
record_name="" # Which record you want to be synced record_name="" # Which record you want to be synced
proxy=false # Set the proxy to true or false ttl="3600" # Set the DNS TTL (seconds)
proxy="false" # Set the proxy to true or false
sitename="" # Title of site "Example Site"
slackchannel="" # Slack Channel #example
slackuri="" # URI for Slack WebHook "https://hooks.slack.com/services/xxxxx"
discorduri="" # URI for Discord WebHook "https://discordapp.com/api/webhooks/xxxxx"
########################################### ###########################################
## Check if we have a public IP ## Check if we have a public IP
########################################### ###########################################
ip=$(curl -s https://api.ipify.org || curl -s https://ipv4.icanhazip.com/) ipv4_regex='([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\.([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\.([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\.([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])'
ip=$(curl -s -4 https://cloudflare.com/cdn-cgi/trace | grep -E '^ip'); ret=$?
if [[ ! $ret == 0 ]]; then # In the case that cloudflare failed to return an ip.
# Attempt to get the ip from other websites.
ip=$(curl -s https://api.ipify.org || curl -s https://ipv4.icanhazip.com)
else
# Extract just the ip from the ip line from cloudflare.
ip=$(echo $ip | sed -E "s/^ip=($ipv4_regex)$/\1/")
fi
if [ "${ip}" == "" ]; then # Use regex to check for proper IPv4 format.
logger -s "DDNS Updater: No public IP found" if [[ ! $ip =~ ^$ipv4_regex$ ]]; then
exit 1 logger -s "DDNS Updater: Failed to find a valid IP."
exit 2
fi fi
########################################### ###########################################
## Check and set the proper auth header ## Check and set the proper auth header
########################################### ###########################################
if [ "${auth_method}" == "global" ]; then if [[ "${auth_method}" == "global" ]]; then
auth_header="X-Auth-Key:" auth_header="X-Auth-Key:"
else else
auth_header="Authorization: Bearer" auth_header="Authorization: Bearer"
@ -33,7 +47,10 @@ fi
########################################### ###########################################
logger "DDNS Updater: Check Initiated" logger "DDNS Updater: Check Initiated"
record=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$zone_identifier/dns_records?name=$record_name" -H "X-Auth-Email: $auth_email" -H "$auth_header $auth_key" -H "Content-Type: application/json") record=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$zone_identifier/dns_records?type=A&name=$record_name" \
-H "X-Auth-Email: $auth_email" \
-H "$auth_header $auth_key" \
-H "Content-Type: application/json")
########################################### ###########################################
## Check if the domain has an A record ## Check if the domain has an A record
@ -46,7 +63,7 @@ fi
########################################### ###########################################
## Get existing IP ## Get existing IP
########################################### ###########################################
old_ip=$(echo "$record" | grep -Po '(?<="content":")[^"]*' | head -1) old_ip=$(echo "$record" | sed -E 's/.*"content":"(([0-9]{1,3}\.){3}[0-9]{1,3})".*/\1/')
# Compare if they're the same # Compare if they're the same
if [[ $ip == $old_ip ]]; then if [[ $ip == $old_ip ]]; then
logger "DDNS Updater: IP ($ip) for ${record_name} has not changed." logger "DDNS Updater: IP ($ip) for ${record_name} has not changed."
@ -56,25 +73,51 @@ fi
########################################### ###########################################
## Set the record identifier from result ## Set the record identifier from result
########################################### ###########################################
record_identifier=$(echo "$record" | grep -Po '(?<="id":")[^"]*' | head -1) record_identifier=$(echo "$record" | sed -E 's/.*"id":"(\w+)".*/\1/')
########################################### ###########################################
## Change the IP@Cloudflare using the API ## Change the IP@Cloudflare using the API
########################################### ###########################################
update=$(curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$zone_identifier/dns_records/$record_identifier" \ update=$(curl -s -X PATCH "https://api.cloudflare.com/client/v4/zones/$zone_identifier/dns_records/$record_identifier" \
-H "X-Auth-Email: $auth_email" \ -H "X-Auth-Email: $auth_email" \
-H "$auth_header $auth_key" \ -H "$auth_header $auth_key" \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
--data "{\"id\":\"$zone_identifier\",\"type\":\"A\",\"proxied\":${proxy},\"name\":\"$record_name\",\"content\":\"$ip\"}") --data "{\"type\":\"A\",\"name\":\"$record_name\",\"content\":\"$ip\",\"ttl\":\"$ttl\",\"proxied\":${proxy}}")
########################################### ###########################################
## Report the status ## Report the status
########################################### ###########################################
case "$update" in case "$update" in
*"\"success\":false"*) *"\"success\":false"*)
logger -s "DDNS Updater: $ip $record_name DDNS failed for $record_identifier ($ip). DUMPING RESULTS:\n$update" echo -e "DDNS Updater: $ip $record_name DDNS failed for $record_identifier ($ip). DUMPING RESULTS:\n$update" | logger -s
if [[ $slackuri != "" ]]; then
curl -L -X POST $slackuri \
--data-raw '{
"channel": "'$slackchannel'",
"text" : "'"$sitename"' DDNS Update Failed: '$record_name': '$record_identifier' ('$ip')."
}'
fi
if [[ $discorduri != "" ]]; then
curl -i -H "Accept: application/json" -H "Content-Type:application/json" -X POST \
--data-raw '{
"content" : "'"$sitename"' DDNS Update Failed: '$record_name': '$record_identifier' ('$ip')."
}' $discorduri
fi
exit 1;; exit 1;;
*) *)
logger "DDNS Updater: $ip $record_name DDNS updated." logger "DDNS Updater: $ip $record_name DDNS updated."
if [[ $slackuri != "" ]]; then
curl -L -X POST $slackuri \
--data-raw '{
"channel": "'$slackchannel'",
"text" : "'"$sitename"' Updated: '$record_name''"'"'s'""' new IP Address is '$ip'"
}'
fi
if [[ $discorduri != "" ]]; then
curl -i -H "Accept: application/json" -H "Content-Type:application/json" -X POST \
--data-raw '{
"content" : "'"$sitename"' Updated: '$record_name''"'"'s'""' new IP Address is '$ip'"
}' $discorduri
fi
exit 0;; exit 0;;
esac esac