TransIP DDNS

Today I made a new PHP script using the TransIP API to update DNS entries. This way it’s possible to automatically update your (dynamic) home IP address for example.

To use this script you need a server with a static IP address and PHP support. If you don’t have a server with a static IP address, free hosting will do the job.

Follow these steps to install this script:

  1. Download the TransIP API to your server
  2. Go to the TransIP CP (My account > API settings)
  3. Enable the API and add your server’s IP address to the list
  4. Add a new Key Pair and copy the key to your clipboard
  5. Edit Transip/ApiSettings.php and set $login and $privateKey (the key you just copied)
    Alternatively you can set this in the script itself, see this comment
  6. Download the script below to your server (dns.php)
  7. Edit the settings in dns.php (domain, key, and records to update)
    This key is used to identify the client, this way the DNS won’t be updated with the IP address of someone else
    Do NOT use the same key as your TransIP API key, the use of a 25 characters long A-Z a-z 0-9 key is recommended
  8. Now, on the client, access dns.php on the server to update the DNS entries
    On Linux you can create a cronjob with the following command (don’t forget to replace the key):
    wget --spider http://example.com/dns.php?key=69l67Le20e819360d3YHO1175

You’re done. You can test if the script works by openening the URL in your browser and then check if the values are updated in the TransIP CP.


<?php
// SETTINGS
// The domain to edit
define('DOMAIN', 'example.com');

// The authentication key
define('KEY', '69l67Le20e819360d3YHO1175');

// The DNS entries to update (name => content)
// This script will NOT add new entries
$newValues = [
  'www' => $_SERVER['REMOTE_ADDR'],
];

// SCRIPT
// Exit if the key does not match
if($_GET['key'] != KEY) exit();

// Include the required files from the API
require_once('Transip/DomainService.php');

// Get the current DNS entries from TransIP
$dnsEntries = Transip_DomainService::getInfo(DOMAIN)->dnsEntries;

// Check every DNS entry
foreach($dnsEntries as $dnsEntry)
{
  // Check if the entry has to be updated and update it
  if(array_key_exists($dnsEntry->name, $newValues)) $dnsEntry->content = $newValues[$dnsEntry->name];
}

try
{
  // Commit the changes to the TransIP DNS servers
  Transip_DomainService::setDnsEntries(DOMAIN, $dnsEntries);
  // Done
  echo 'DNS updated.';
}
catch(SoapFault $f)
{
  // An error occured
  echo 'DNS not updated. ' . $f->getMessage();
}
?>

10 thoughts on “TransIP DDNS

  1. Hi.

    Great tutorial. Thanks! How would I go about just changing the IP of a subdomain? (So I can get home.example.com).

    Thanks!

    1. It depends on your configuration in the TransIP DNS CP for the domain example.com. There are 2 possible names: home.example.com. and just home. Check which one you’re using first in the DNS CP, then to make the script work, change www to the name of your home subdomain (or add a new entry):

      $newValues = [
      'www' => $_SERVER['REMOTE_ADDR'],
      'home' => $_SERVER['REMOTE_ADDR'],
      ];

  2. Excellent tutorial. I am a noob at programming and had it working with the latest TransIP API in less than an hour, including setting up and securing an http server with php. Thanks!

  3. Hi,

    First of all, thanks a lot for this tutorial.. it works great with subdomains, and the “www”, however i was wondering what needs to be done to get the @ A-record set correctly, so it points to the correct IP when i simply type in “example.com”

    When i add ‘@’ => $_SERVER[‘REMOTE_ADDR’], then i get the following error:

    DNS not updated. the content of an MX record must be in the format “priority target”: @ 86400 MX the content of an MX record must be in the format “priority target”: @ 86400 MX

    i have changed my real IP address with in the error message.

    Also I have three domains (all non-commercial), so would it be possible to update all of them within one script, or is it better to set the script up a few times, each for one individual domain?

    cheers,
    Chris

    1. Hey,

      I’m sorry for the late reply. I’m afraid this is a bug in my script.

      My script just takes the first occurrence of the name (‘@’ in this case) and updates it with the specified content.

      You probably have multiple records with the name ‘@’, and the TransIP API happens to return your MX record with the name ‘@’ as the first result. So this won’t update your A record, but your MX record instead, which is not what you want.

      If you’re still interested I could provide an example on how to fix this issue.

  4. Hi Naxiz,

    First of all thank you for your response.

    Yes, you are correct, I have 4 ‘@’ records in total..
    Next to the A record I still have two MX records (mail server and backup) and a TXT record for SPF.

    If you could provide an example on how to fix this behavior , so only the ‘@’ A record is being changed, this would be highly appreciated!

    thanks,
    Chris

    1. Hello, again sorry for my late reply.

      A quick workaround for your issue is is to add the following code right after the opening foreach bracket:

      if ($dnsEntry->type != 'A') continue;

      This way all records which are not of type ‘A’ will be skipped. Good luck!

  5. Hi, thanks for the example. This got met started.
    I modified your code, this way there is no need to change the API files.

    Before.
    // Get the current DNS entries from TransIP
    $dnsEntries = Transip_DomainService::getInfo(DOMAIN)->dnsEntries;

    Add
    //Set login and private key file
    Transip_ApiSettings::$login=’loginname’;
    Transip_ApiSettings::$privateKey= file_get_contents(‘private.key’);

    Save the private key in the file ‘private.key’.

    Jos

Leave a Reply

Your email address will not be published. Required fields are marked *