From e8873cc3288db36450eae7ae9ab4a7d4ab9158cc Mon Sep 17 00:00:00 2001 From: 9cco Date: Sun, 13 Feb 2022 17:11:22 +0100 Subject: [PATCH 1/8] 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. --- cloudflare-template.sh | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/cloudflare-template.sh b/cloudflare-template.sh index 60e6776..be35122 100644 --- a/cloudflare-template.sh +++ b/cloudflare-template.sh @@ -7,7 +7,7 @@ auth_key="" # Your API Token or Global AP zone_identifier="" # Can be found in the "Overview" tab of your domain record_name="" # Which record you want to be synced ttl="3600" # Set the DNS TTL (seconds) -proxy=false # Set the proxy to true or false +proxy="false" # Set the proxy to true or false slacksitename="" # Title of site "Example Site" slackchannel="" # Slack Channel #example slackuri="" # URI for Slack WebHook "https://hooks.slack.com/services/xxxxx" @@ -17,9 +17,15 @@ slackuri="" # URI for Slack WebHook "http ########################################### ## Check if we have a public IP ########################################### -ip=$(curl -s https://api.ipify.org || curl -s https://ipv4.icanhazip.com/) +command -v dig &> /dev/null +# Use the DNS lookup if dig is available. +if [[ $? -eq 0 ]]; then + ip=$(dig +short myip.opendns.com @resolver1.opendns.com); +else + ip=$(curl -s https://api.ipify.org || curl -s https://ipv4.icanhazip.com/) +fi -if [ "${ip}" == "" ]; then +if [[ "${ip}" == "" ]]; then logger -s "DDNS Updater: No public IP found" exit 1 fi @@ -27,7 +33,7 @@ fi ########################################### ## Check and set the proper auth header ########################################### -if [ "${auth_method}" == "global" ]; then +if [[ "${auth_method}" == "global" ]]; then auth_header="X-Auth-Key:" else auth_header="Authorization: Bearer" @@ -69,18 +75,28 @@ record_identifier=$(echo "$record" | sed -E 's/.*"id":"(\w+)".*/\1/') ########################################### ## Change the IP@Cloudflare using the API ########################################### +api_data=$(cat < Date: Sat, 19 Feb 2022 12:35:53 +0100 Subject: [PATCH 2/8] Fixed problem with dig not always giving correct output --- cloudflare-template.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cloudflare-template.sh b/cloudflare-template.sh index be35122..2537c26 100644 --- a/cloudflare-template.sh +++ b/cloudflare-template.sh @@ -21,7 +21,8 @@ command -v dig &> /dev/null # Use the DNS lookup if dig is available. if [[ $? -eq 0 ]]; then ip=$(dig +short myip.opendns.com @resolver1.opendns.com); -else +fi +if [[ $ip -eq "" ]]; then ip=$(curl -s https://api.ipify.org || curl -s https://ipv4.icanhazip.com/) fi From 9d2e7fcc8a47d7ab3b90bc7c15a4cc0dd76c9df6 Mon Sep 17 00:00:00 2001 From: 9cco Date: Fri, 25 Feb 2022 12:24:17 +0100 Subject: [PATCH 3/8] 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. --- cloudflare-template.sh | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/cloudflare-template.sh b/cloudflare-template.sh index 2537c26..8f9e863 100644 --- a/cloudflare-template.sh +++ b/cloudflare-template.sh @@ -17,18 +17,16 @@ slackuri="" # URI for Slack WebHook "http ########################################### ## Check if we have a public IP ########################################### -command -v dig &> /dev/null -# Use the DNS lookup if dig is available. -if [[ $? -eq 0 ]]; then +# Use curl if curl is available +if [[ $(command -v curl &> /dev/null; echo $?) ]]; then + ip=$(curl -s https://api.ipify.org || curl -s https://ipv4.icanhazip.com/) +elif [[ $(command -v dig &> /dev/null; echo $?) ]]; then ip=$(dig +short myip.opendns.com @resolver1.opendns.com); fi -if [[ $ip -eq "" ]]; then - ip=$(curl -s https://api.ipify.org || curl -s https://ipv4.icanhazip.com/) -fi -if [[ "${ip}" == "" ]]; then - logger -s "DDNS Updater: No public IP found" - exit 1 +if [[ ! $ip =~ [0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3} ]]; then + logger -s "DDNS Updater: Failed to find a valid IP." + exit 1 fi ########################################### From ebcc60faa34bbbd5e0f529abdafb5a3b42c7bbde Mon Sep 17 00:00:00 2001 From: 9cco Date: Sat, 26 Feb 2022 02:46:48 +0100 Subject: [PATCH 4/8] Improved regex as pr timetoexpire comment --- cloudflare-template.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloudflare-template.sh b/cloudflare-template.sh index 8f9e863..70e45a3 100644 --- a/cloudflare-template.sh +++ b/cloudflare-template.sh @@ -24,7 +24,7 @@ elif [[ $(command -v dig &> /dev/null; echo $?) ]]; then ip=$(dig +short myip.opendns.com @resolver1.opendns.com); fi -if [[ ! $ip =~ [0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3} ]]; then +if [[ ! $ip =~ ^([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])$ ]]; then logger -s "DDNS Updater: Failed to find a valid IP." exit 1 fi From 6a50f940cb225247d2a7284f33088a560d044d6b Mon Sep 17 00:00:00 2001 From: 9cco Date: Sat, 26 Feb 2022 11:10:26 +0100 Subject: [PATCH 5/8] 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. --- cloudflare-template.sh | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/cloudflare-template.sh b/cloudflare-template.sh index 70e45a3..6ece278 100644 --- a/cloudflare-template.sh +++ b/cloudflare-template.sh @@ -17,16 +17,26 @@ slackuri="" # URI for Slack WebHook "http ########################################### ## Check if we have a public IP ########################################### -# Use curl if curl is available +# Use curl if curl is installed on the system. if [[ $(command -v curl &> /dev/null; echo $?) ]]; then ip=$(curl -s https://api.ipify.org || curl -s https://ipv4.icanhazip.com/) -elif [[ $(command -v dig &> /dev/null; echo $?) ]]; then - ip=$(dig +short myip.opendns.com @resolver1.opendns.com); +else + logger -s "Error: 'curl' was not found on your system. Install it with 'sudo apt install curl' in order to use this script" + exit 1 fi -if [[ ! $ip =~ ^([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])$ ]]; then - logger -s "DDNS Updater: Failed to find a valid IP." - exit 1 +# Use regex to check for proper IPv4 format. Try using 'dig' if curl requests failed. +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])$' +if [[ ! $ip =~ $ipv4_regex ]]; then + logger -s "Warning: Neither 'api.ipify.org' nor 'ipv4.icanhazip.com' were able to obtain your ip-address. Trying to use less secure DNS lookup on 'myip.opendns.com' through 'dig' instead." + if [[ $(command -v dig &> /dev/null; echo $?) ]]; then + ip=$(dig +short myip.opendns.com @resolver1.opendns.com) + fi + # Also sanitize the 'dig' output through the same regex as before. + if [[ ! $ip =~ $ipv4_regex ]]; then + logger -s "DDNS Updater: Failed to find a valid IP." + exit 2 + fi fi ########################################### @@ -74,21 +84,11 @@ record_identifier=$(echo "$record" | sed -E 's/.*"id":"(\w+)".*/\1/') ########################################### ## Change the IP@Cloudflare using the API ########################################### -api_data=$(cat < Date: Sat, 26 Feb 2022 12:09:26 +0100 Subject: [PATCH 6/8] Added cloudflare.com as a way of finding the ip --- cloudflare-template.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cloudflare-template.sh b/cloudflare-template.sh index 6ece278..be6aec7 100644 --- a/cloudflare-template.sh +++ b/cloudflare-template.sh @@ -19,7 +19,7 @@ slackuri="" # URI for Slack WebHook "http ########################################### # Use curl if curl is installed on the system. if [[ $(command -v curl &> /dev/null; echo $?) ]]; then - ip=$(curl -s https://api.ipify.org || curl -s https://ipv4.icanhazip.com/) + ip=$(curl -s https://cloudflare.com/cdn-cgi/trace | grep -E '^ip' | sed -E 's/^ip=([0-9\.]*)$/\1/' || curl -s https://api.ipify.org || curl -s https://ipv4.icanhazip.com/) else logger -s "Error: 'curl' was not found on your system. Install it with 'sudo apt install curl' in order to use this script" exit 1 @@ -28,7 +28,7 @@ fi # Use regex to check for proper IPv4 format. Try using 'dig' if curl requests failed. 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])$' if [[ ! $ip =~ $ipv4_regex ]]; then - logger -s "Warning: Neither 'api.ipify.org' nor 'ipv4.icanhazip.com' were able to obtain your ip-address. Trying to use less secure DNS lookup on 'myip.opendns.com' through 'dig' instead." + logger -s "Warning: Neither 'cloudflare.com', 'api.ipify.org' nor 'ipv4.icanhazip.com' were able to obtain your ip-address. Trying to use less secure DNS lookup on 'myip.opendns.com' through 'dig' instead." if [[ $(command -v dig &> /dev/null; echo $?) ]]; then ip=$(dig +short myip.opendns.com @resolver1.opendns.com) fi From 08ef1d559d7b8a8f4e57bade78af4c52635786f4 Mon Sep 17 00:00:00 2001 From: 9cco Date: Sun, 27 Feb 2022 13:44:48 +0100 Subject: [PATCH 7/8] 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. --- cloudflare-template.sh | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/cloudflare-template.sh b/cloudflare-template.sh index be6aec7..51d9572 100644 --- a/cloudflare-template.sh +++ b/cloudflare-template.sh @@ -17,26 +17,20 @@ slackuri="" # URI for Slack WebHook "http ########################################### ## Check if we have a public IP ########################################### -# Use curl if curl is installed on the system. -if [[ $(command -v curl &> /dev/null; echo $?) ]]; then - ip=$(curl -s https://cloudflare.com/cdn-cgi/trace | grep -E '^ip' | sed -E 's/^ip=([0-9\.]*)$/\1/' || 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 - logger -s "Error: 'curl' was not found on your system. Install it with 'sudo apt install curl' in order to use this script" - exit 1 + # Extract just the ip from the ip line from cloudflare. + ip=$(echo $ip | sed -E "s/^ip=($ipv4_regex)$/\1/") fi -# Use regex to check for proper IPv4 format. Try using 'dig' if curl requests failed. -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])$' +# Use regex to check for proper IPv4 format. if [[ ! $ip =~ $ipv4_regex ]]; then - logger -s "Warning: Neither 'cloudflare.com', 'api.ipify.org' nor 'ipv4.icanhazip.com' were able to obtain your ip-address. Trying to use less secure DNS lookup on 'myip.opendns.com' through 'dig' instead." - if [[ $(command -v dig &> /dev/null; echo $?) ]]; then - ip=$(dig +short myip.opendns.com @resolver1.opendns.com) - fi - # Also sanitize the 'dig' output through the same regex as before. - if [[ ! $ip =~ $ipv4_regex ]]; then - logger -s "DDNS Updater: Failed to find a valid IP." - exit 2 - fi + logger -s "DDNS Updater: Failed to find a valid IP." + exit 2 fi ########################################### From 00db8af28ff57f3bc7bd8cb6f9a56d3b35027618 Mon Sep 17 00:00:00 2001 From: 9cco Date: Sat, 12 Mar 2022 12:45:16 +0100 Subject: [PATCH 8/8] Stricter regex, should now catch all false positives --- cloudflare-template.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloudflare-template.sh b/cloudflare-template.sh index 51d9572..56b3725 100644 --- a/cloudflare-template.sh +++ b/cloudflare-template.sh @@ -28,7 +28,7 @@ else fi # Use regex to check for proper IPv4 format. -if [[ ! $ip =~ $ipv4_regex ]]; then +if [[ ! $ip =~ ^$ipv4_regex$ ]]; then logger -s "DDNS Updater: Failed to find a valid IP." exit 2 fi