#!/usr/bin/env bash # This script will update given netcup domain dns record with the actual ip of the calling service # Parameters: # IPVERSION: 4 or 6 # DOMAIN_NAME: the zone name eg. test.com # DNS_RECORD_ID: the id of the dns record that should be updated # HOSTNAMERECORD: the hostname in domain # NC_Apikey: Api Key from your netcup account # NC_Apipw: Api password from your netcup account # NC_CID: Customer ID from your netcup account IPVERSION=$1 DOMAIN_NAME=$2 DNS_RECORD_ID=$3 HOSTNAMERECORD=$4 NC_Apikey=$5 NC_Apipw=$6 NC_CID=$7 NC_ENDPOINT='https://ccp.netcup.net/run/webservice/servers/endpoint.php?JSON' CACHE_PATH="/var/cache/update_netcup_ddns" usage() { # # Displays usage of script # # returns usage # echo echo "./update_netcup_ddns.sh " echo } query_ip_address() { # # Queries the IP address in use # # returns IP address or exits with log message # local IPVERSION=$1 local CACHE_PATH=$2 case $IPVERSION in 4) QUERY_ADDRESS=$(curl -s -4 -q v4.ident.me | grep -oE '((1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])\.){3}(1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])') STATEFILE="$CACHE_PATH/ddns_state_ipv"$IPVERSION"_$DOMAIN_NAME.txt" ;; 6) QUERY_ADDRESS=$(curl -s -6 -q v6.ident.me | grep -oE '^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$') STATEFILE="$CACHE_PATH/ddns_state_ipv"$IPVERSION"_$DOMAIN_NAME.txt" ;; *) usage exit 1 ;; esac if [ ! -d $CACHE_PATH ]; then mkdir -p $CACHE_PATH; fi if [ ! -f $STATEFILE ]; then touch $STATEFILE; fi if [ ! -z $QUERY_ADDRESS ]; then echo $QUERY_ADDRESS else logger -t $(basename $0) -p user.err "Unable to query IP address" exit 255; fi } get_auth_token() { # # Get auth token # # returns auth_token # echo $(curl -s -X POST \ $NC_ENDPOINT \ --header 'Accept: */*' \ --header 'Content-Type: application/json' \ --data-raw '{ "action":"login", "param":{ "apikey": "'$NC_Apikey'", "apipassword": "'$NC_Apipw'", "customernumber": "'$NC_CID'" } }') } determine_record_type() { # # Determine dns record type # # returns dns record type (currently support A and AAAA) # local IPVERSION=$1 if [ $IPVERSION -eq 4 ]; then RECORDTYPE="A" elif [ $IPVERSION -eq 6 ]; then RECORDTYPE="AAAA" else logger -t $(basename $0) -p user.err "Could not determine IP version. Exiting" exit 1 fi echo $RECORDTYPE } get_ip_from_state() { # # Get IP address currently set in DNS # # returns address set in DNS # # local IPVERSION=$1 # local CACHE_PATH=$2 # # STATEFILE="$CACHE_PATH/ddns_state_ipv"$IPVERSION"_$DOMAIN_NAME.txt" # LAST_ADDRESS=$(<$STATEFILE) # # echo $LAST_ADDRESS sid=$(get_auth_token | tr '{}' '\n' | grep apisessionid | cut -d '"' -f 4) curl -s -X POST \ $NC_ENDPOINT \ --header 'Accept: */*' \ --header 'Content-Type: application/json' \ --data-raw '{ "action":"infoDnsRecords", "param":{ "apikey": "'$NC_Apikey'", "apisessionid": "'$sid'", "customernumber": "'$NC_CID'", "clientrequestid": "", "domainname": "'$DOMAIN_NAME'" } }' | jq -r '.responsedata.dnsrecords[] | select(.id == "'$DNS_RECORD_ID'") | .destination' } update_dns_record() { # # Update DNS record # # returns the IP address updated in DNS # update=$(curl -s -X POST \ $NC_ENDPOINT \ --header 'Accept: */*' \ --header 'Content-Type: application/json' \ --data-raw '{ "action":"updateDnsRecords", "param":{ "apikey": "'$NC_Apikey'", "apisessionid": "'$sessionid'", "customernumber": "'$NC_CID'", "clientrequestid": "", "domainname": "'$DOMAIN_NAME'", "dnsrecordset": { "dnsrecords": [ { "id": "'$DNS_RECORD_ID'", "hostname": "'$HOSTNAMERECORD'", "type": "'$(determine_record_type $IPVERSION)'", "destination": "'$QUERIED_ADDRESS'" } ] } } }') echo $update | jq -r '.responsedata.dnsrecords[] | select(.id == "'$DNS_RECORD_ID'") | .destination' } QUERIED_ADDRESS=$(query_ip_address $IPVERSION "$CACHE_PATH") LAST_ADDRESS=$(get_ip_from_state) # If IP address hasn't changed, exit, otherwise save the new IP if [ "$QUERIED_ADDRESS" == "$LAST_ADDRESS" ]; then logger -t $(basename $0) -p user.notice "No update necessary for $HOSTNAMERECORD.$DOMAIN_NAME ($(determine_record_type $IPVERSION))!" exit 0 fi echo $QUERIED_ADDRESS > "$CACHE_PATH/ddns_state_ipv"$IPVERSION"_$DOMAIN_NAME.txt" sessionid=$(get_auth_token | tr '{}' '\n' | grep apisessionid | cut -d '"' -f 4) if [ "$sessionid" = "" ]; then logger -t $(basename $0) -p user.err "SessionID was empty. Login failed." exit 1 fi logger -t $(basename $0) -p user.notice "Successfully logged in" logger -t $(basename $0) -p user.notice "Try registering new IP for FQDN $HOSTNAMERECORD.$DOMAIN_NAME ($QUERIED_ADDRESS - $(determine_record_type $IPVERSION))" update=$(update_dns_record) if [ "$update" == "$QUERIED_ADDRESS" ]; then logger -t $(basename $0) -p user.notice "Finished updating domain $DOMAIN_NAME" else logger -t $(basename $0) -p user.err "Could not update $HOSTNAMERECORD.$DOMAIN_NAME ($QUERIED_ADDRESS - $(determine_record_type $IPVERSION))" fi