Skip to content

DNS Update via Bash Script and API (Advanced)

Important

To use DynDNS a DNS API user MUST exist. To do that follow the guide Create User in Customer Portal!

For all domain customers we offer a DynDNS service which communicates with the Servercow nameservers via the Servercow DNS API.

In this guide you will learn how to build a DynDNS service for your domain using a bash script.


Preparation

The script is designed for the Bash shell. If your Linux distribution uses a different shell, please install the Bash shell.

On every operating system cURL is required.


DynDNS via Script and Systemd service

The script

In the following you see an example script, which simply sets the new entry with cURL commands. This script will continue to run indefinitely (until a manual abort), so it is ideal to make a service out of it later:

#!/bin/bash
while true; do
  if [ -f /tmp/old_ip4 ]; then
  IP4_OLD=$(</tmp/old_ip4)
  else
      IP4_OLD=none
  fi

  IP4_NEW=$(curl -s ip4.mailcow.email)
  if [[ "${IP4_NEW}" != "${IP4_OLD}" ]]; then
      curl -s -X POST 'https://api.servercow.de/dns/v1/domains/YOUR_DOMAIN.tld' \
      -H 'X-Auth-Username: YOUR_API_USER' \
      -H 'X-Auth-Password: YOUR_API_PASSWORD' \
      -H 'Content-Type: application/json' \
      --data "{\"type\":\"A\",\"name\":\"subdomain\",\"content\":\"${IP4_NEW}\",\"ttl\":60}" -o /dev/null
  fi
  echo ${IP4_NEW} > /tmp/old_ip4

  if [ -f /tmp/old_ip6 ]; then
  IP6_OLD=$(</tmp/old_ip6)
  else
      IP6_OLD=none
  fi

  IP6_NEW=$(curl -s ip6.mailcow.email)
  if [[ "${IP6_NEW}" != "${IP6_OLD}" ]]; then
      curl -s -X POST 'https://api.servercow.de/dns/v1/domains/YOUR_DOMAIN.tld' \
      -H 'X-Auth-Username: YOUR_API_USER' \
      -H 'X-Auth-Password: YOUR_API_PASSWORD' \
      -H 'Content-Type: application/json' \
      --data "{\"type\":\"AAAA\",\"name\":\"subdomain\",\"content\":\"${IP4_NEW}\",\"ttl\":60}" -o /dev/null
  fi
  echo ${IP6_NEW} > /tmp/old_ip6
  sleep 120
done
#!/bin/bash
while true; do
  if [ -f /tmp/old_ip ]; then
  IP_OLD=$(</tmp/old_ip)
  else
      IP_OLD=none
  fi

  IP_NEW=$(curl -s ip4.mailcow.email)
  if [[ "${IP_NEW}" != "${IP_OLD}" ]]; then
      curl -s -X POST 'https://api.servercow.de/dns/v1/domains/YOUR_DOMAIN.tld' \
      -H 'X-Auth-Username: YOUR_API_USER' \
      -H 'X-Auth-Password: YOUR_API_PASSWORD' \
      -H 'Content-Type: application/json' \
      --data "{\"type\":\"A\",\"name\":\"subdomain\",\"content\":\"${IP_NEW}\",\"ttl\":60}" -o /dev/null
  fi
  echo ${IP_NEW} > /tmp/old_ip
  sleep 120
done
#!/bin/bash
while true; do
  if [ -f /tmp/old_ip ]; then
  IP_OLD=$(</tmp/old_ip)
  else
      IP_OLD=none
  fi

  IP_NEW=$(curl -s ip6.mailcow.email)
  if [[ "${IP_NEW}" != "${IP_OLD}" ]]; then
      curl -s -X POST 'https://api.servercow.de/dns/v1/domains/YOUR_DOMAIN.tld' \
      -H 'X-Auth-Username: YOUR_API_USER' \
      -H 'X-Auth-Password: YOUR_API_PASSWORD' \
      -H 'Content-Type: application/json' \
      --data "{\"type\":\"AAAA\",\"name\":\"subdomain\",\"content\":\"${IP_NEW}\",\"ttl\":60}" -o /dev/null
  fi
  echo ${IP_NEW} > /tmp/old_ip
  sleep 120
done

Please make the script executable:

chmod +x /path/to/script/dyndns.sh

The Systemd service (autostart the script)

So that the script regularly updates the IPs we can automate this.

For this we create a systemd service, which starts the script automatically for us in the background at startup. Since the script runs indefinitely we can keep the service quite simple.

Let's create the service:

systemctl edit --force --full dnsupdate.service

As content we use:

Systemd service to start the dyndns script
[Unit]
Description=Update DNS
[Service]
Type=simple
ExecStart=/path/to/script/dyndns.sh
KillMode=process

[Install]
WantedBy=multi-user.target

Activate the service:

systemctl enable dnsupdate.service
systemctl start dnsupdate.service

Now the script should run automatically and check every 21 minutes if the own IP has changed and if necessary point the DNS entry to the new IP.


DynDNS via script and Cronjob

The script

As an alternative to the Systemd variant as a service, you can also use the script in such a way that it is manually triggered by a cronjob and terminated after execution.

We remove the infinite loop and call the script at a fixed time via cronjob.

In this case the script looks like this:

#!/bin/bash
if [ -f /tmp/old_ip4 ]; then
IP4_OLD=$(</tmp/old_ip4)
else
    IP4_OLD=none
fi

IP4_NEW=$(curl -s ip4.mailcow.email)
if [[ "${IP4_NEW}" != "${IP4_OLD}" ]]; then
    curl -s -X POST 'https://api.servercow.de/dns/v1/domains/YOUR_DOMAIN.tld' \
    -H 'X-Auth-Username: YOUR_API_USER' \
    -H 'X-Auth-Password: YOUR_API_PASSWORD' \
    -H 'Content-Type: application/json' \
    --data "{\"type\":\"A\",\"name\":\"subdomain\",\"content\":\"${IP4_NEW}\",\"ttl\":60}" -o /dev/null
fi
echo ${IP4_NEW} > /tmp/old_ip4

if [ -f /tmp/old_ip6 ]; then
IP6_OLD=$(</tmp/old_ip6)
else
    IP6_OLD=none
fi

IP6_NEW=$(curl -s ip6.mailcow.email)
if [[ "${IP6_NEW}" != "${IP6_OLD}" ]]; then
    curl -s -X POST 'https://api.servercow.de/dns/v1/domains/YOUR_DOMAIN.tld' \
    -H 'X-Auth-Username: YOUR_API_USER' \
    -H 'X-Auth-Password: YOUR_API_PASSWORD' \
    -H 'Content-Type: application/json' \
    --data "{\"type\":\"AAAA\",\"name\":\"subdomain\",\"content\":\"${IP4_NEW}\",\"ttl\":60}" -o /dev/null
fi
echo ${IP6_NEW} > /tmp/old_ip6
#!/bin/bash
if [ -f /tmp/old_ip ]; then
IP_OLD=$(</tmp/old_ip)
else
    IP_OLD=none
fi

IP_NEW=$(curl -s ip4.mailcow.email)
if [[ "${IP_NEW}" != "${IP_OLD}" ]]; then
    curl -s -X POST 'https://api.servercow.de/dns/v1/domains/YOUR_DOMAIN.tld' \
    -H 'X-Auth-Username: YOUR_API_USER' \
    -H 'X-Auth-Password: YOUR_API_PASSWORD' \
    -H 'Content-Type: application/json' \
    --data "{\"type\":\"A\",\"name\":\"subdomain\",\"content\":\"${IP_NEW}\",\"ttl\":60}" -o /dev/null
fi
echo ${IP_NEW} > /tmp/old_ip
#!/bin/bash
if [ -f /tmp/old_ip ]; then
IP_OLD=$(</tmp/old_ip)
else
    IP_OLD=none
fi

IP_NEW=$(curl -s ip6.mailcow.email)
if [[ "${IP_NEW}" != "${IP_OLD}" ]]; then
    curl -s -X POST 'https://api.servercow.de/dns/v1/domains/YOUR_DOMAIN.tld' \
    -H 'X-Auth-Username: YOUR_API_USER' \
    -H 'X-Auth-Password: YOUR_API_PASSWORD' \
    -H 'Content-Type: application/json' \
    --data "{\"type\":\"AAAA\",\"name\":\"subdomain\",\"content\":\"${IP_NEW}\",\"ttl\":60}" -o /dev/null
fi
echo ${IP_NEW} > /tmp/old_ip

Please make this script executable as well:

chmod +x /path/to/script/dyndns.sh

The Cronjob

To create the cronjob we recommend for newbies the page: crontab-generator.org!

We give you a cronjob, which runs every 5 minutes as an example:

crontab -e # Edit cronjobs on your system

*/5 * * * * /bin/bash /path/to/script/dyndns.sh

You can determine the time interval according to your needs. However, we do not recommend longer intervals than a maximum of 1 hour.


  1. The time to the next test can be changed in the script by the duration of the sleep command.