Bash: Update-Script for (DynDNS)

Bash: Update-Script for (DynDNS)

Select language: Deutsch English

In the meantime I have used a large number of Raspberry Pis for measuring and monitoring purposes. Since these usually hang behind Internet connections with dynamic IP, I have been using no-ip. com as a DynDNS service for some time now. However, the Dynamic DNS Update Client (DUC) offered by NO-IP never really worked reliably for me and so I had no access to the Raspberry Pis on a regular basis. I therefore wrote myself a small bash-script for a reliable and fast update of the IP-address. The script is certainly not perfect, but it has been working reliably for months now.

The functionality is quickly explained:

  • the script uses Cronjob to regularly determine the current IP
  • the current IP is compared with the cached IP
  • If the IP has changed, NO-IP is notified by curl
  • the newly determined IP is cached for future comparisons
  • all IP updates and occurred errors are logged


Difficulty level:

As described above, the script uses curl to access NO-IP. Curl must therefore be installed first:

$ sudo apt-get install curl

The script is then stored under /usr/local/bin/noip_updater. sh and the permissions are adjusted:

$ sudo nano /usr/local/bin/
$ sudo chmod 700 /usr/local/bin/



The following content must be copied to the noip_updater. sh file and the USERNAME, PASSWORD and HOST variables must be customized:


# ------------------------------------------------------- # CONFIG # ------------------------------------------------------- USERNAME="dein-noip-benutzername" PASSWORD="dein-noip-passwort" HOST="" LOGFILE=/var/log/noip.log IPFILE=/tmp/current_ip USERAGENT="Datenreise NOIP Updater/0.4"
if [ ! -e $IPFILE ]; then touch $IPFILE if [ $? -ne 0 ]; then LOGTEXT="IP file could not be created." LOGDATE="[$(date +'%d.%m.%Y %H:%M:%S')]" echo "$LOGDATE $LOGTEXT" >> $LOGFILE exit 1 fi elif [ ! -w $IPFILE ]; then LOGTEXT="IP file is not writable." LOGDATE="[$(date +'%d.%m.%Y %H:%M:%S')]" echo "$LOGDATE $LOGTEXT" >> $LOGFILE exit 1 fi
# IP Validator # function validate_ip() { local ip=$1 local stat=1 if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then OIFS=$IFS IFS='.' ip=($ip) IFS=$OIFS [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \ && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]] stat=$? fi return $stat }
GET_IP_URLS=( "" "" "" "" ) for key in ${!GET_IP_URLS[@]}; do NEWIP=$(curl -s ${GET_IP_URLS[$key]} | grep -o '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}') if validate_ip $NEWIP; then break elif [ $key -eq $((${#GET_IP_URLS[@]} - 1)) ]; then LOGTEXT="Could not find current IP. Offline?" LOGDATE="[$(date +'%d.%m.%Y %H:%M:%S')]" echo "$LOGDATE $LOGTEXT" >> $LOGFILE exit 1 else LOGTEXT="Got a non-valid IP from ${GET_IP_URLS[$key]}." LOGDATE="[$(date +'%d.%m.%Y %H:%M:%S')]" echo "$LOGDATE $LOGTEXT" >> $LOGFILE fi done
if [ "$NEWIP" != "$STOREDIP" ]; then RESPONSE=$(curl -s -k -u $USERNAME:$PASSWORD --user-agent "$USERAGENT" "$HOST&myip=$NEWIP") RESPONSE=$(echo $RESPONSE | tr -cd "[:print:]") RESPONSE_A=$(echo $RESPONSE | awk '{ print $1 }') case $RESPONSE_A in "good") RESPONSE_B=$(echo $RESPONSE | awk '{ print $2 }') LOGTEXT="(good) DNS hostname(s) successfully updated to $RESPONSE_B." ;; "nochg") RESPONSE_B=$(echo $RESPONSE | awk '{ print $2 }') LOGTEXT="(nochg) IP address is current: $RESPONSE_B; no update performed." ;; "nohost") LOGTEXT="(nohost) Hostname supplied does not exist under specified account. Revise config file." ;; "badauth") LOGTEXT="(badauth) Invalid username password combination." ;; "badagent") LOGTEXT="(badagent) Client disabled - No-IP is no longer allowing requests from this update script." ;; "!donator") LOGTEXT="(!donator) An update request was sent including a feature that is not available." ;; "abuse") LOGTEXT="(abuse) Username is blocked due to abuse." ;; "911") LOGTEXT="(911) A fatal error on our side such as a database outage. Retry the update in no sooner than 30 minutes." ;; *) LOGTEXT="(error) Could not understand the response from No-IP. The DNS update server may be down." ;; esac echo $NEWIP > $IPFILE LOGDATE="[$(date +'%d.%m.%Y %H:%M:%S')]" echo "$LOGDATE $LOGTEXT" >> $LOGFILE fi exit 0



To execute the bash script at regular intervals, a cronjob must be created. For this purpose we work on crontab:

$ sudo nano /etc/crontab

At the bottom, the following entry is simply added and the change is saved on the crontab:

# NO-IP update
*/5 *   * * *   root    /usr/local/bin/

Then restart the Cron service.

$ sudo service cron restart

This article was helpful for you?
Please support – Thank you!


Rate this Post:
1 Star2 Stars3 Stars4 Stars5 Stars
4.10/5 (10 votes)

Bash: Update-Script for (DynDNS), 4.10 out of 5 based on 10 ratings