---
title: "ISPConfig Dynamic DNS"
tags: ["ispconfig", "ddns", "dns"]
categories: ["recipe", "sysadmin"]
description: "How to create and update a DDNS entry in ISPConfig"
date: 2019-05-22T18:54:00+02:00
draft: false
---
## How to create and update a DDNS entry in ISPConfig
If you manage your DNS server(s) with ISPConfig you may want a *dynamic entry* that gets updated automatically every time the target host changes its IP address.
Doing so in ISPConfig is quite straight forward: we can use the [ISPConfig SOAP API](https://git.ispconfig.org/ispconfig/ispconfig3/tree/master/remoting_client) to update an existing record with a PHP script to be run frequently by the target host.
In this [**recipe**]({{< ref "/categories/recipe" >}}) I will consider **updating an A record**.
1. First we need to create a remote user on the ISPConfig master server to authenticate, and grant it remote access and some functions:
In “System -> Remote User” add a new remote user, enable remote access and **grant** “DNS zone functions” and each DNS functions corresponding to the type of record you want to update: **so if you want to update an A record you must grant the generic “DNS zone functions” and the “DNS a functions”**
2. We then have to write a PHP script that will make a SOAP function call to the ISPConfig endpoint. The target host, or the host executing the script must have the [PHP SOAP module](https://www.php.net/manual/en/book.soap.php) installed.
Create the `update.php` script as follow:
```
3) {
// Third parameter: IP address of target host
$ip = $argv[3];
// Otherwise
} else {
// Figure out the public IP of this host:
$ip = trim(file_get_contents("http://icanhazip.com/"));
if (filter_var($ip, FILTER_VALIDATE_IP) === false) {
die("Unable to retrieve public IP address (icanhazip.com returned $ip)\n");
}
}
print("Setting DDNS host $ddns_host.$domain to IP $ip\n");
// Using the SOAP module initialize a SoapClient
$client = new SoapClient(null,
array('location' => $soap_location,
'uri' => $soap_uri,
'trace' => 1,
'exceptions' => 1));
try {
// Login to SOAP server
$session_id = $client->login($soap_user, $soap_password);
// Grab DNS zone ID
$zone_id = $client->dns_zone_get_id($session_id, $domain);
// Grab DNS zone
$zone = $client->dns_zone_get($session_id, $zone_id);
// Grab DNS records
$records = $client->dns_rr_get_all_by_zone($session_id, $zone_id);
// Find right record: hostname must match and type must be A
$dns_record = null;
foreach ($records as $rec) {
if ($rec['type']=='A' && $rec['name']==$ddns_host) {
$dns_record = $rec;
}
}
// If no record found
if (is_null($dns_record)) {
//Logout from SOAP server
$client->logout($session_id);
die("Unable to find DNS record for host $ddns_host in domain $domain on the server...\n");
}
// If IP stored in record is different from current IP
if ($dns_record['data'] != $ip) {
// Set new IP
$dns_record['data'] = $ip;
// Increment record serial number
$dns_record['serial'] = $dns_record['serial']+1;
// Update modified record in DNS server
$client->dns_a_update($session_id, null, $dns_record['id'], $dns_record);
// Increment zone serial number
$zone['serial'] = $zone['serial'] + 1;
// Update modified zone in DNS server
$client->dns_zone_update($session_id, 0, $zone_id, $zone);
print("Successfully set DNS entry for host $ddns_host in domain $domain to $ip.\n");
// Otherwise
} else {
print("IP address of $ddns_host.$domain already set to $ip.\n");
}
//Logout from SOAP server
$client->logout($session_id);
} catch (SoapFault $e) {
die('SOAP Error: '.$e->getMessage()."\n");
}
?>
```
Create the `config.php` as follow:
```