Selaa lähdekoodia

Refactor script

Joshua Avalon 6 vuotta sitten
vanhempi
commit
a94c445a64
3 muutettua tiedostoa jossa 91 lisäystä ja 101 poistoa
  1. 15 0
      CHANGELOG.md
  2. 24 41
      README.md
  3. 52 60
      cloudflareddns.sh

+ 15 - 0
CHANGELOG.md

@@ -0,0 +1,15 @@
+# 2.0.0
+
+### Features
+
+- Auto detect IPv4 and IPv6 to handle A or AAAA record.
+- No long need to edit the script directly.
+- Use Cloudflare API token instead of username and password for limiting permissions.
+- Update to correct status in Synology.
+- Notify user about errors in updating DDNS.
+
+### BREAKING CHANGES
+
+- Cloudflare API token must be used instead of username and password.
+- Username should enter Zone ID.
+- No longer output to log files.

+ 24 - 41
README.md

@@ -1,73 +1,56 @@
 # Synology Cloudflare DDNS Script 📜
-The is a script to be used to add [Cloudflare](https://www.cloudflare.com/) as a DDNS to [Synology](https://www.synology.com/) NAS. This is a modified version [script](https://gist.github.com/tehmantra/f1d2579f3c922e8bb4a0) from [Michael Wildman](https://gist.github.com/tehmantra). The script used an updated API, Cloudflare API v4.
+
+The is a script to be used to add [Cloudflare](https://www.cloudflare.com/) as a DDNS to [Synology](https://www.synology.com/) NAS. The script used an updated API, Cloudflare API v4.
 
 ## How to use
+
 ### Access Synology via SSH
+
 1. Login to your DSM
 2. Go to Control Panel > Terminal & SNMP > Enable SSH service
-3. Use your client or commandline to access Synology. If you don't have any, I recommand you can try out [MobaXterm](http://mobaxterm.mobatek.net/) for Windows.
+3. Use your client to access Synology via SSH.
 4. Use your Synology admin account to connect.
 
 ### Run commands in Synology
+
 1. Download `cloudflareddns.sh` from this repository to `/sbin/cloudflaredns.sh`
+
 ```
 wget https://raw.githubusercontent.com/joshuaavalon/SynologyCloudflareDDNS/master/cloudflareddns.sh -O /sbin/cloudflaredns.sh
 ```
+
 It is not a must, you can put I whatever you want. If you put the script in other name or path, make sure you use the right path.
 
 2. Give others execute permission
+
 ```
 chmod +x /sbin/cloudflaredns.sh
 ```
 
 3. Add `cloudflareddns.sh` to Synology
+
 ```
 cat >> /etc.defaults/ddns_provider.conf << 'EOF'
 [Cloudflare]
-        modulepath=/sbin/cloudflaredns.sh
-        queryurl=https://www.cloudflare.com/
+        modulepath=/sbin/cloudflareddns.sh
+        queryurl=https://www.cloudflare.com
+        website=https://www.cloudflare.com
 E*.
 ```
+
 `queryurl` does not matter because we are going to use our script but it is needed.
 
 ### Get Cloudflare parameters
-1. Go to your domain overview page and get the **Zone ID**.
-2. Go to your [account setting page](https://www.cloudflare.com/a/account/my-account) and get **API Key**.
-3. Get record id using Cloudflare API.
-```
-curl -X GET "https://api.cloudflare.com/client/v4/zones/[Zone ID]/dns_records" \
-     -H "X-Auth-Email: [Email]" \
-     -H "X-Auth-Key: [API Key]" \
-     -H "Content-Type: application/json"
-```
-You need to replace with [] with your parameter. Then, you get the `id` in `result` which is you **Record ID**.
-
-### Setup DDNS
-1. Enter the parameters to the `cloudflareddns.sh`.
-2. Login to your DSM
-3. Go to Control Panel > External Access > DDNS > Add
-4. Select Cloudflare as service provider. Enter your domain as hostname, your Cloudflare account as Username/Email, and API key as Password/Key
-
-## Parameters
-### \_\_USERNAME\_\_, \_\_PASSWORD\_\_, \_\_HOSTNAME\_\_, \_\_MYIP\_\_
-These are the parameters from Synology.
-
-### \_\_RECTYPE\_\_
-DNS record type
 
-### \_\_RECID\_\_
-Record ID
+1. Go to your domain overview page and copy your zone ID.
+2. Go to your profile > **API Tokens** > **Create Token**. It should have the permissions of `Zone > DNS > Edit`. Copy the api token.
 
-### \_\_ZONE\_ID\_\_
-Zone ID
-
-### \_\_TTL\_\_
-Time to live for DNS record. Value of 1 is 'automatic'
-
-### \_\_PROXY\_\_
-Whether the record is receiving the performance and security benefits of Cloudflare.
-
-### \_\_LOGFILE\_\_
-Log file location
+### Setup DDNS
 
-You can read the [Cloudflare API documentation v4](https://api.cloudflare.com/#dns-records-for-a-zone-update-dns-record) for more details.
+1. Login to your DSM
+2. Go to Control Panel > External Access > DDNS > Add
+3. Enter the following:
+   - Service provider: `Cloudflare`
+   - Hostname: `www.example.com`
+   - Username/Email: `<Zone ID>`
+   - Password Key: `<API Token>`

+ 52 - 60
cloudflareddns.sh

@@ -1,62 +1,54 @@
-#!/bin/sh
+#!/bin/bash
+set -e;
+
+ipv4Regex="((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])"
+
+proxy="true"
 
 # DSM Config
-__USERNAME__="$(echo ${@} | cut -d' ' -f1)"
-__PASSWORD__="$(echo ${@} | cut -d' ' -f2)"
-__HOSTNAME__="$(echo ${@} | cut -d' ' -f3)"
-__MYIP__="$(echo ${@}  | cut -d' ' -f4)"
-
-# log location
-__LOGFILE__="/var/log/cloudflareddns.log"
-
-# CloudFlare Config
-__RECTYPE__="A"
-__RECID__=""
-__ZONE_ID__=""
-__TTL__="1"
-__PROXY__="true"
-
-log() {
-    __LOGTIME__=$(date +"%b %e %T")
-    if [ "${#}" -lt 1 ]; then
-        false
-    else
-        __LOGMSG__="${1}"
-    fi
-    if [ "${#}" -lt 2 ]; then
-        __LOGPRIO__=7
-    else
-        __LOGPRIO__=${2}
-    fi
-
-    logger -p ${__LOGPRIO__} -t "$(basename ${0})" "${__LOGMSG__}"
-    echo "${__LOGTIME__} $(basename ${0}) (${__LOGPRIO__}): ${__LOGMSG__}" >> ${__LOGFILE__}
-}
-
-__URL__="https://api.cloudflare.com/client/v4/zones/${__ZONE_ID__}/dns_records/${__RECID__}"
-
-# Update DNS record:
-log "Updating with ${__MYIP__}..."
-__RESPONSE__=$(curl -s -X PUT "${__URL__}" \
-     -H "X-Auth-Email: ${__USERNAME__}" \
-     -H "X-Auth-Key: ${__PASSWORD__}" \
-     -H "Content-Type: application/json" \
-     --data "{\"type\":\"${__RECTYPE__}\",\"name\":\"${__HOSTNAME__}\",\"content\":\"${__MYIP__}\",\"ttl\":${__TTL__},\"proxied\":${__PROXY__}}")
-
-# Strip the result element from response json
-__RESULT__=$(echo ${__RESPONSE__} | grep -Po '"success":\K.*?[^\\],')
-echo ${__RESPONSE__}
-case ${__RESULT__} in
-    'true,')
-        __STATUS__='good'
-        true
-        ;;
-    *)
-        __STATUS__="${__RESULT__}"
-        log "__RESPONSE__=${__RESPONSE__}"
-        false
-        ;;
-esac
-log "Status: ${__STATUS__}"
-
-printf "%s" "${__STATUS__}"
+username="$1"
+password="$2"
+hostname="$3"
+ipAddr="$4"
+
+if [[ $ipAddr =~ $ipv4Regex ]]; then
+    recordType="A";
+else
+    recordType="AAAA";
+fi
+
+listDnsApi="https://api.cloudflare.com/client/v4/zones/${username}/dns_records?type=${recordType}&name=${hostname}"
+createDnsApi="https://api.cloudflare.com/client/v4/zones/${username}/dns_records"
+
+res=$(curl -s -X GET "$listDnsApi" -H "Authorization: Bearer $password" -H "Content-Type:application/json")
+resSuccess=$(echo "$res" | jq -r ".success")
+
+if [[ $resSuccess != "true" ]]; then
+    echo "badauth";
+    exit 1;
+fi
+
+recordId=$(echo "$res" | jq -r ".result[0].id")
+recordIp=$(echo "$res" | jq -r ".result[0].content")
+
+if [[ $recordIp = "$ipAddr" ]]; then
+    echo "nochg";
+    exit 0;
+fi
+
+if [[ $recordId = "null" ]]; then
+    # Record not exists
+    res=$(curl -s -X POST "$createDnsApi" -H "Authorization: Bearer $password" -H "Content-Type:application/json" --data "{\"type\":\"$recordType\",\"name\":\"$hostname\",\"content\":\"$ipAddr\",\"proxied\":$proxy}")
+else
+    # Record exists
+    updateDnsApi="https://api.cloudflare.com/client/v4/zones/${username}/dns_records/${recordId}";
+    res=$(curl -s -X PUT "$updateDnsApi" -H "Authorization: Bearer $password" -H "Content-Type:application/json" --data "{\"type\":\"$recordType\",\"name\":\"$hostname\",\"content\":\"$ipAddr\",\"proxied\":$proxy}")
+fi
+
+resSuccess=$(echo "$res" | jq -r ".success")
+
+if [[ $resSuccess = "true" ]]; then
+    echo "good";
+else
+    echo "badauth";
+fi