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 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
How to get ClientID Browse to your ISPConfig panel Go to the Clients tab 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
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