Skip to content

Instantly share code, notes, and snippets.

@nathanlesage
Last active April 11, 2026 18:40
Show Gist options
  • Select an option

  • Save nathanlesage/680de7eb848c49a9454f5034c52cde81 to your computer and use it in GitHub Desktop.

Select an option

Save nathanlesage/680de7eb848c49a9454f5034c52cde81 to your computer and use it in GitHub Desktop.
DynDNS with Netcup and Fritz!Box

Custom DynDNS with Netcup and Fritz!Box

The following script allows you to set up an auto-updating DynDNS using the Netcup API.

Note

You do not necessarily need a Fritz!Box. Anything that can call some URL and provide an IP address will work.

Who is this for?

Anyone who is a customer with Netcup GmbH and has a Domain there, and wants to point, e.g., a subdomain of that to their own home router.

What do you need?

You'll need to be a customer with Netcup and you need to have a domain there that uses Netcup's DNS Nameservers. You also need some web space where PHP runs, and which is publicly accessible. Also, the PHP needs the cURL extension.

How To

You can get started in a few easy steps:

  1. Download the script ddns.php and place it somewhere accessible onto a web server.
  2. Check that it works by visiting the correct domain (e.g., http://example.com/ddns.php) and confirm that the script is accessible
  3. Once that is confirmed, think of a username or password and set them in the script (updateUser and updatePass). These are NOT the Netcup login credentials. These are just so that nobody can just arbitrarily run this script.
  4. Next, retrieve your credentials from Netcup. You can find all of them in the Customer Control Panel: customerID, apiKey, apiPass. You will need to accept some terms to generate a new key, and you then also need to generate a password for that key.
  5. Now, ensure that you have your wanted DNS record set in the customer control panel. For example, if you wish to use the domain ddns.example.com, ensure that there is an "A"-entry for "ddns" under the domain "example.com" that points to somewhere. I recommend you leave it to something "wrong" so that you can later verify that the script correctly runs.
  6. Once the entry is created, use your browser's developer tools to inspect the new entry and retrieve the record ID. (The input element should have a name property with a value looking like this: record[1234567][host]). The number is what you want.
  7. Now, place all of this information into the script and save it.

You can now provide the link to the script to your Fritz!Box (or whatever else) so that it automatically updates the DNS record whenever your IP address changes. A full example for an Update URL with Fritz!Box would look like this: https://example.com/ddns.php?ipv4=<ipaddr>&user=<username>&pass=<pass>&domain=<domain>. (Note that this script has hard-coded the domain, because I only need one. If you want to, update the script accordingly.)

<?php
// USAGE
//
// 1. Fill in all fields below.
// 2. Point whatever it is you want to run this script to the link of this
// script. Ensure they call this script with at least the parameters "user",
// "pass", and "ipv4".
// NOTE that the Fritz!Box UI requires you to also define a <domain> parameter.
// Do so, this script will simply ignore it.
////////////////////////////////////////////////////////////////////////////////
/////////////////////////////// DEFINE CONSTANTS ///////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// Credentials to ensure only the correct people can run this script. Provide
// your own values here, and ensure that anyone who calls this script provides
// a "user" and a "pass" parameter with these values.
$updateUser = "your-username";
$updatePass = "your-password";
// Provide your Netcup Customer ID (numerical)
$customerId = "123456";
// Provide your Netcup API key
$apiKey = "your-api-key";
// Provide your Netcup API password
$apiPass = "your-api-password";
// Specify the domain to be updated
$domain = "example.com";
// Provide all hostnames under the given domain that you wish to update to point
// to the provided IP address. These correspond to the contents of the "host"
// field in the GUI DNS settings. You can provide subdomains ("www" for domain
// "example.com"), or wildcards ("@" to refer to the domain itself or "*" as a
// catch-all).
$hostnames = array("www", "ddns");
// JSON API Endpoint
$endpoint = "https://ccp.netcup.net/run/webservice/servers/endpoint.php?JSON";
////////////////////////////////////////////////////////////////////////////////
///////////////////////////// AUTHENTICATE CALLER //////////////////////////////
////////////////////////////////////////////////////////////////////////////////
if (
!isset($_GET['user']) || $_GET['user'] != $updateUser ||
!isset($_GET['pass']) || $_GET['pass'] != $updatePass
) {
echo "Wrong username or password.<br>\n";
exit(1);
}
if (!isset($_GET['ipv4'])) {
echo "Required parameter ipv4 is missing.<br>\n";
exit(1);
}
echo "Successfully authenticated.<br>\n";
// Get the IP address from the request
$ipAddress = $_GET['ipv4'];
////////////////////////////////////////////////////////////////////////////////
////////////////////////////// UTILITY FUNCTIONS ///////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// Small utility function to make the main work below easier.
function makeCurlCall ($payload) {
global $endpoint;
$jsonPayload = json_encode($payload);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $endpoint);
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonPayload);
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/json", "User-Agent: Netcup DDNS Updater Script"));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, true);
return json_decode(curl_exec($ch));
}
// Utility function to generate the DNS records
function generateDnsRecords ($hostnames, $ipAddress) {
$records = array();
foreach($hostnames as $hostname) {
array_push($records, array(
"hostname" => $hostname,
"type" => "A",
"destination" => $ipAddress
));
}
return $records;
}
// Determine if the call was successful
function success ($result) {
return $result->status == "success";
}
// Utility function to retrieve an API call result status message
function getStatus ($result) {
return $result->shortmessage . ". " . $result->longmessage . "<br>\n";
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////// PERFORM THE UPDATE //////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// First, login
$result = makeCurlCall(array(
"action" => "login",
"param" => array(
"apikey" => $apiKey,
"apipassword" => $apiPass,
"customernumber" => $customerId
)
));
echo getStatus($result);
if (!success($result)) {
exit(1);
}
// This gives us the apiSessionId
$apiSessionId = $result->responsedata->apisessionid;
echo "Updating DNS records to point to new IP...<br>\n";
// Next step, update the record
$updatePayload = array(
"action" => "updateDnsRecords",
"param" => array(
"domainname" => $domain,
"customernumber" => $customerId,
"apikey" => $apiKey,
"apisessionid" => $apiSessionId,
// Context: https://forum.netcup.de/thread/13363-dns-api-falsche-formatierung-der-dns-records/?postID=156680#post156680
"dnsrecordset" => array("dnsrecords" => generateDnsRecords($hostnames, $ipAddress))
)
);
$result = makeCurlCall($updatePayload);
echo getStatus($result);
// Lastly, logout again -- even if the call above did not succeed.
$result = makeCurlCall(array(
"action" => "logout",
"param" => array(
"apikey" => $apiKey,
"customernumber" => $customerId,
"apisessionid" => $apiSessionId
)
));
echo getStatus($result);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment