Bash Script: ispconfg_ update_dns_record.sh

Discussion in 'Plugins/Modules/Addons' started by Tuumke, Dec 12, 2019.

  1. Tuumke

    Tuumke Active Member

    I was looking for a way to have some sort of Dynamic DNS function. Even though im supposed to have a static IP at home, it has change quite a few times the past few weeks/months. Kind of annoying when you are trying to reach your NAS and you see that your IP has changed. So i started to look for a way to update my NAS's DNS record with a new IP address automagicly. That's when i ran into this post by @sghazagh. I think he used the PHP api to update his record, but i wanted to use a BASH script. Not that i'm really good at that, to be honest, i think this is my first "complex" bash script.
    I took a few hit and runs, but when managing ur own ISPConfig, its easy to reset the DNS record and try again :p

    I'm gonna write in the post below how to get the right ID and ZONE for the record.

    So without further ado:

    Code:
    #!/usr/bin/env bash
    
    # +------------------------------------------------------+
    # | update_ispconfg_dns_record.sh                        |
    # +------------------------------------------------------+
    # | Made by: Tuumke
    # | For: ISPConfig
    # | Support: https://www.howtoforge.com/community/threads/bash-script-update_ispconfg_dns_record-sh.83426/
    # +------------------------------------------------------+
    
    set -e
    
    ## Define if debugging is either "true" or "false"
    debug="false"
    if [ $debug = "true" ];then
        echo "      ____________________________"
        echo "+----| D E B U G G I N G  IS  ON  |----+"
        echo "+--------------------------------------+"
    fi
    
    ## Define an export file we can fill with json. Will be deleted at end of script.
    ## If it already exists, because for some reason it wasnt deleted, we will delete it now
    exportfile='currentdata.json'
    if [ -f $exportfile ]; then
        rm $exportfile
    fi
    
    
    ## Login settings, such as username, password and url for API
    remote_user='yourid'
    remote_password='yourpass'
    remote_url='https://yourdomain.tld:8080/remote/json.php'
    primaryid='recordid'
    
    ## function to easily make a curl request.
    ## restCall method data
    restCall() {
        curl -sSk -X POST -H "Content-Type: application/json" -H "Cache-Control: no-cache" -d "${2}" "${remote_url}?${1}"
    }
    
    
    ## Login and get a session ID
    echo "|     ____________________________"
    echo "+----| L O G I N     S T A T U S  |----+"
    session_id=`restCall login "{\"username\": \"${remote_user}\",\"password\": \"${remote_password}\"}" | jq -r '.response'`
    if [[ $isession == "false" ]]; then
        echo "| Login failed!"
        exit 1
    else
        echo "| Logged in."
        if [ $debug == "true" ];then
            echo -e "| Session is:\t$session_id"
        fi
    fi
    echo "+--------------------------------------+"
    
    ## Define current data for the A record and save it to a file
    currentdata=`restCall dns_a_get "{\"session_id\": \"$session_id\",\"primary_id\":\"$primaryid\"}" | jq -r ".response"`
    echo $currentdata > $pwd\currentdata.json
    
    ## Define data needed for JSON put
    server_id=`jq -r ".server_id" $exportfile`
    zone=`jq -r ".zone" $exportfile`
    name=`jq -r ".name" $exportfile`
    type=`jq -r ".type" $exportfile`
    data=`jq -r ".data" $exportfile`
    aux=`jq -r ".aux" $exportfile`
    ttl=`jq -r ".ttl" $exportfile`
    active=`jq -r ".active" $exportfile`
    stamp=`jq -r ".stamp" $exportfile`
    declare serial=`jq -r ".serial" $exportfile`
    
    if [ $debug == "true" ]; then
        echo "|     ____________________________"
        echo "+----| C U R R E N T dns D A T A  |----+"
        echo -e "| Server_id:\t$server_id"
        echo -e "| Zone:\t\t$zone"
        echo -e "| Name:\t\t$name"
        echo -e "| Type:\t\t$type"
        echo -e "| Data:\t\t$data"
        echo -e "| Aux:\t\t$aux"
        echo -e "| TTL:\t\t$ttl"
        echo -e "| Active:\t$active"
        echo -e "| Stamp:\t$stamp"
        echo -e "| Serial:\t$serial"
        echo "+--------------------------------------+"
    fi
    
    ## Get current IP address and check if they match
    currentip=`curl -sSk https://watismijnip.info/ | sed -E 's/<[^>]*>//g'`
    echo "|     ____________________________"
    echo "+----|   C O M P A R E      I P   |----+"
    if [ $currentip == $data ]; then
        echo "+----| no   need   for   update   |----+"
        echo "+--------------------------------------+"
        echo -e "| $type Record:\t$data"
        echo -e "| currentIP:\t$currentip"
        ## IF ips match, no need for an update
        needupdate="false"
    else
        echo "+----|    update      required    |----+"
        echo "+--------------------------------------+"
        echo -e "| A Record:\t$data"
        echo -e "| CurrentIP:\t$currentip"
        echo "+--------------------------------------+"
        ## IF ips dont match, we need to update the record
        needupdate="true"
    fi
    
    
    ## If an update is needed run the code below
    if [ $needupdate == "true" ];then
    
        declare -i serial_date=${serial:0:8}
        declare -i count=${serial:8:2}
        current_date_date=`date +%Y%m%d`
        declare -i current_date=$current_date_date
        if [ $debug == "true"  ]; then
            echo "|     ____________________________"
            echo "+----|  D E B U G        I N F O  |----+"
            echo -e "| Serial_date:\t$serial_date"
        echo -e "| Current_date:\t$current_date"
            display_count=`printf '%02d' $count`
        echo -e "| Count:\t$display_count"
        fi
    
        if [ $serial_date == $current_date ]; then
    
            newcount=$(expr $count + 1)
            newcount=`printf '%02d' $newcount`
            echo -e "| New count:\t$newcount"
    
            if [ $newcount > 99 ]; then
    
                declare serial_date="$serial_date"
                declare -i count=1
                declare newcount=`printf '%02d' $count`
    
            fi
    
            declare -i new_serial="$serial_date$newcount"
    
            if [ $debug == "true" ]; then
                echo "+--------------------------------------+"
                echo "|     ____________________________"
                echo "+----|  D E B U G        I N F O  |----+"
                echo "| When dates are equal"
                echo "| New_serial: $new_serial"
                echo "+--------------------------------------+"
            fi
    
    
        else
            declare -i count="01"
            newcount=`printf '%02d' $count`
            declare -i new_serial="$current_date$newcount"
            if [ $debug == "true" ]; then
                echo "+--------------------------------------+"
                echo "|     ____________________________"
                echo "+----|  D E B U G        I N F O  |----+"
                echo "| When dates are not equal"
                echo "| New_serial: $new_serial"
                echo "+--------------------------------------+"
            fi
    
    
        fi
    
        newstamp=`date '+%Y-%m-%d %H:%m:%S'`
        echo "|     ____________________________"
        echo "+----|  N E W    TIME   S T A M P |----+"
        echo "| $newstamp"
        echo "+--------------------------------------+"
    
        params=$( jq -n \
            --arg j_server_id "$server_id" \
            --arg j_zone "$zone" \
            --arg j_name "$name" \
            --arg j_type "$type" \
            --arg j_data "$currentip" \
            --arg j_aux "$aux" \
            --arg j_ttl "$ttl" \
            --arg j_active "$active" \
            --arg j_stamp "$newstamp" \
            --arg j_serial "$new_serial" \
            '{server_id: $j_server_id, zone: $j_zone, name: $j_name, type: $j_type, data: $j_data, aux: $j_aux, ttl: $j_ttl,  active: $j_active, stamp: $j_stamp, serial: $j_serial}' )
    
        echo "|     ____________________________"
        echo "+----|  P A R A M S      U S E D  |----+"
        echo "| $params "
        echo "+--------------------------------------+"
    
    #    result=`restCall dns_a_update "{\"session_id\": \"$session_id\",\"client_id\":\"1\",\"primary_id\":\"128\",\"params\": $params}" | jq -r ".response"`
    
        echo "|     ____________________________"
        echo "+----|       R E S U L T S        |----+"
        echo "| $result "
        echo "+--------------------------------------+"
    fi
    
    ## Cleanup and log out
    if [ -f $exportfile ]; then
            rm $exportfile
    fi
    
    
    # Log out
    if [[ `restCall logout "{\"session_id\": \"$session_id\"}" |jq -r .response` == "true" ]]; then
        echo "|     ____________________________"
        echo "+----|        L O G O U T         |----+"
        echo "| Logout successful"
        echo "+--------------------------------------+"
        exit 0
    else
        echo "|     ____________________________"
        echo "+----|        L O G O U T         |----+"
        echo "| Logout failed!"
        echo "+--------------------------------------+"
        exit 1
    fi
    
    
     
    Last edited: Dec 12, 2019
    elmacus and till like this.
  2. Tuumke

    Tuumke Active Member

    How to get ClientID
    1. Browse to your ISPConfig panel
    2. Go to the Clients tab
    3. ID is displayed in the first column
    How to get DNS Zones
    Use the script below to get the DNS zone of a the client:
    Code:
    #!/usr/bin/env bash
    # +------------------------------------------------------+
    # | ispconfg_get_dns_zone.sh                        |
    # +------------------------------------------------------+
    # | Made by: Tuumke
    # | For: ISPConfig
    # | Support: https://www.howtoforge.com/community/threads/bash-script-update_ispconfg_dns_record-sh.83426/
    # +------------------------------------------------------+
    
    set -e
    
    ## Define if debugging is either "true" or "false"
    debug="false"
    if [ $debug = "true" ];then
        echo "      ____________________________"
        echo "+----| D E B U G G I N G  IS  ON  |----+"
        echo "+--------------------------------------+"
    fi
    
    ## Define an export file we can fill with json. Will be deleted at end of script.
    ## If it already exists, because for some reason it wasnt deleted, we will delete it now
    exportfile='currentdata.json'
    if [ -f $exportfile ]; then
        rm $exportfile
    fi
    
    
    ## Login settings, such as username, password and url for API
    remote_user='youruser'
    remote_password='yourpassword'
    remote_url='https://yourdomain.tld:8080/remote/json.php'
    clientid='clientid'
    
    ## function to easily make a curl request.
    ## restCall method data
    restCall() {
        curl -sSk -X POST -H "Content-Type: application/json" -H "Cache-Control: no-cache" -d "${2}" "${remote_url}?${1}"
    }
    
    
    ## Login and get a session ID
    echo "|     ____________________________"
    echo "+----| L O G I N     S T A T U S  |----+"
    session_id=`restCall login "{\"username\": \"${remote_user}\",\"password\": \"${remote_password}\"}" | jq -r '.response'`
    if [[ $isession == "false" ]]; then
        echo "| Login failed!"
        exit 1
    else
        echo "| Logged in."
        if [ $debug == "true" ];then
            echo -e "| Session is:\t$session_id"
        fi
    fi
    echo "+--------------------------------------+"
    
    ## Define current data for the A record and save it to a file
    dnszones=`restCall dns_zone_get_by_user "{\"session_id\": \"$session_id\",\"client_id\":\"$clientid\",\"server_id\":\"1\"}" | jq -r ".response"`
    #echo $dnszones
    echo $dnszones > $pwd\dnszones.json
    
    
    echo "|     ____________________________"
    echo "+----|    D N S      Z O N E S    |----+"
    jq '.[] | {id, origin}' dnszones.json
    echo "+--------------------------------------+"
    
    ## Cleanup and log out
    if [ -f $exportfile ]; then
        rm $exportfile
    fi
    
    
    ## Log out
    if [[ `restCall logout "{\"session_id\": \"$session_id\"}" |jq -r .response` == "true" ]]; then
        echo "|     ____________________________"
        echo "+----|        L O G O U T         |----+"
        echo "| Logout successful"
        echo "+--------------------------------------+"
        exit 0
    else
        echo "|     ____________________________"
        echo "+----|        L O G O U T         |----+"
        echo "| Logout failed!"
        echo "+--------------------------------------+"
        exit 1
    fi
    
     
    Last edited: Dec 12, 2019
    ahrasis likes this.
  3. Tuumke

    Tuumke Active Member

    How to get the DNS records frome the zone?
    You can use this script:
    Code:
    #!/usr/bin/env bash
    
    # +------------------------------------------------------+
    # | ispconfg_get_dnszone_records.sh                        |
    # +------------------------------------------------------+
    # | Made by: Tuumke
    # | For: ISPConfig
    # | Support: https://www.howtoforge.com/community/threads/bash-script-update_ispconfg_dns_record-sh.83426/
    # +------------------------------------------------------+
    
    set -e
    
    ## Define if debugging is either "true" or "false"
    debug="false"
    if [ $debug = "true" ];then
        echo "      ____________________________"
        echo "+----| D E B U G G I N G  IS  ON  |----+"
        echo "+--------------------------------------+"
    fi
    
    ## Define an export file we can fill with json. Will be deleted at end of script.
    ## If it already exists, because for some reason it wasnt deleted, we will delete it now
    exportfile='dnszonerecords.json'
    if [ -f $exportfile ]; then
        rm $exportfile
    fi
    
    
    ## Login settings, such as username, password and url for API
    remote_user='youruser'
    remote_password='yourpassword'
    remote_url='https://yourdomain.tld:8080/remote/json.php'
    zoneid='yourzoneid'
    
    ## function to easily make a curl request.
    ## restCall method data
    restCall() {
        curl -sSk -X POST -H "Content-Type: application/json" -H "Cache-Control: no-cache" -d "${2}" "${remote_url}?${1}"
    }
    
    
    ## Login and get a session ID
    echo "|     ____________________________"
    echo "+----| L O G I N     S T A T U S  |----+"
    session_id=`restCall login "{\"username\": \"${remote_user}\",\"password\": \"${remote_password}\"}" | jq -r '.response'`
    if [[ $isession == "false" ]]; then
        echo "| Login failed!"
        exit 1
    else
        echo "| Logged in."
        if [ $debug == "true" ];then
            echo -e "| Session is:\t$session_id"
        fi
    fi
    echo "+--------------------------------------+"
    
    ## Define current data for the A record and save it to a file
    dnszones=`restCall dns_rr_get_all_by_zone "{\"session_id\": \"$session_id\",\"zone_id\":\"$zoneid\"}" | jq -r ".response"`
    #echo $dnszones
    echo $dnszones > $pwd\dnszonerecords.json
    
    
    echo "|     ____________________________"
    echo "+----|    D N S      Z O N E S    |----+"
    jq '.[] | {id, zone, name, type, data}' dnszonerecords.json
    echo "+--------------------------------------+"
    
    ## Cleanup and log out
    if [ -f $exportfile ]; then
        rm $exportfile
    fi
    
    
    # Log out
    if [[ `restCall logout "{\"session_id\": \"$session_id\"}" |jq -r .response` == "true" ]]; then
        echo "|     ____________________________"
        echo "+----|        L O G O U T         |----+"
        echo "| Logout successful"
        echo "+--------------------------------------+"
        exit 0
    else
        echo "|     ____________________________"
        echo "+----|        L O G O U T         |----+"
        echo "| Logout failed!"
        echo "+--------------------------------------+"
        exit 1
    fi
    
     
    Last edited: Dec 12, 2019
    Steini86 and ahrasis like this.

Share This Page