Skip to content

Commit 3895318

Browse files
committed
Added IPv6 support
1 parent 6a430fe commit 3895318

File tree

4 files changed

+115
-21
lines changed

4 files changed

+115
-21
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
### Implemented
1616
* All necessary API functions for DNS actions implemented (REST API)
1717
* Determines correct public IP address, uses fallback API for determining the IP address, in case main API does return invalid / no IP
18+
* IPv6 Support
1819
* Updating of a specific subdomain, domain root, or subdomain
1920
* Creation of DNS record, if it doesn't already exist
2021
* If configured, lowers TTL to 300 seconds for the domain on each run, if necessary
@@ -23,12 +24,11 @@
2324
### Missing
2425
* Support for domain root and wildcard / specific subdomains at the same time
2526
* Caching the IP provided to netcup DNS, to avoid running into (currently not existing) rate limits in the DNS API
26-
* IPv6 Support
2727
* Probably a lot more :grin: – to be continued...
2828

2929
## Getting started
3030
### Configuration
31-
Configuration is very simple: Just fill out `config.php` with the required values.
31+
Configuration is very simple: Just fill out `config.php` with the required values. The options are explained in there.
3232

3333
### How to use
3434
`php update.php`

config.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111
//Enter subdomain to be used for dynamic DNS, alternatively '@' for domain root or '*' for wildcard. If the record doesn't exist, the script will create it.
1212
define('HOST', 'server');
1313

14+
//If set to true, the script will check for your public IPv6 address too and add it as an AAAA-Record / change an existing AAAA-Record for the host.
15+
//Activate this only if you have IPv6 connectivity, or you *WILL* get errors.
16+
define('USE_IPV6', false);
17+
1418
//If set to true, this will change TTL to 300 seconds on every run if necessary.
1519
define('CHANGE_TTL', true);
1620

functions.php

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ function outputStderr($message)
7070
//Returns current public IPv4 address.
7171
function getCurrentPublicIPv4()
7272
{
73-
$publicIP = file_get_contents('https://api.ipify.org');
73+
$publicIP = rtrim(file_get_contents('https://api.ipify.org'));
7474

7575
//Let's check that this is really a IPv4 address, just in case...
7676
if (filter_var($publicIP, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
@@ -91,6 +91,28 @@ function getCurrentPublicIPv4()
9191
return false;
9292
}
9393

94+
//Returns current public IPv6 address
95+
function getCurrentPublicIPv6()
96+
{
97+
$publicIP = rtrim(file_get_contents('https://ip6.seeip.org'));
98+
99+
if (filter_var($publicIP, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
100+
return $publicIP;
101+
}
102+
103+
outputWarning("https://ip6.seeip.org didn't return a valid IPv6 address.");
104+
//If IP is invalid, try another API
105+
$publicIP = rtrim(file_get_contents('https://v6.ident.me/'));
106+
107+
//Let's check the result of the second API
108+
if (filter_var($publicIP, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
109+
return $publicIP;
110+
}
111+
112+
//Still no valid IP?
113+
return false;
114+
}
115+
94116
//Login into netcup domain API and returns Apisessionid
95117
function login($customernr, $apikey, $apipassword)
96118
{

update.php

Lines changed: 86 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
outputStdout("This script is not affiliated with netcup.");
99
outputStdout("=============================================\n");
1010

11+
outputStdout(sprintf("Updating DNS records for host %s on domain %s\n", HOST, DOMAIN));
12+
1113
// Login
1214
if ($apisessionid = login(CUSTOMERNR, APIKEY, APIPASSWORD)) {
1315
outputStdout("Logged in successfully!");
@@ -45,11 +47,11 @@
4547
}
4648

4749
//Find the host defined in config.php
48-
$foundHosts = array();
50+
$foundHostsV4 = array();
4951

5052
foreach ($infoDnsRecords['responsedata']['dnsrecords'] as $record) {
5153
if ($record['hostname'] === HOST && $record['type'] === "A") {
52-
$foundHosts[] = array(
54+
$foundHostsV4[] = array(
5355
'id' => $record['id'],
5456
'hostname' => $record['hostname'],
5557
'type' => $record['type'],
@@ -62,52 +64,118 @@
6264
}
6365

6466
//If we can't find the host, create it.
65-
if (count($foundHosts) === 0) {
66-
outputStdout(sprintf("Host %s doesn't exist, creating necessary DNS-Record.", HOST));
67-
$foundHosts[] = array(
67+
if (count($foundHostsV4) === 0) {
68+
outputStdout(sprintf("A record for host %s doesn't exist, creating necessary DNS record.", HOST));
69+
$foundHostsV4[] = array(
6870
'hostname' => HOST,
6971
'type' => 'A',
7072
'destination' => 'newly created Record',
7173
);
7274
}
7375

7476
//If the host with A record exists more than one time...
75-
if (count($foundHosts) > 1) {
76-
outputStderr(sprintf("Found multiple A-Records for the Host %s – Please specify a host for which only a single A-Record exists in config.php. Exiting.", HOST));
77+
if (count($foundHostsV4) > 1) {
78+
outputStderr(sprintf("Found multiple A records for the host %s – Please specify a host for which only a single A record exists in config.php. Exiting.", HOST));
7779
exit(1);
7880
}
7981

8082
//If we couldn't determine a valid public IPv4 address
81-
if (!$publicIP = getCurrentPublicIPv4()) {
83+
if (!$publicIPv4 = getCurrentPublicIPv4()) {
8284
outputStderr("Main API and fallback API didn't return a valid IPv4 address. Exiting.");
8385
exit(1);
8486
}
8587

86-
$ipchange = false;
88+
$ipv4change = false;
8789

8890
//Has the IP changed?
89-
foreach ($foundHosts as $record) {
90-
if ($record['destination'] !== $publicIP) {
91+
foreach ($foundHostsV4 as $record) {
92+
if ($record['destination'] !== $publicIPv4) {
9193
//Yes, it has changed.
92-
$ipchange = true;
93-
outputStdout(sprintf("IP has changed. Before: %s; Now: %s", $record['destination'], $publicIP));
94+
$ipv4change = true;
95+
outputStdout(sprintf("IPv4 address has changed. Before: %s; Now: %s", $record['destination'], $publicIPv4));
9496
} else {
9597
//No, it hasn't changed.
96-
outputStdout("IP hasn't changed. Current IP: ".$publicIP."");
98+
outputStdout("IPv4 address hasn't changed. Current IPv4 address: ".$publicIPv4);
9799
}
98100
}
99101

100102
//Yes, it has changed.
101-
if ($ipchange === true) {
102-
$foundHosts[0]['destination'] = $publicIP;
103+
if ($ipv4change === true) {
104+
$foundHostsV4[0]['destination'] = $publicIPv4;
103105
//Update the record
104-
if (updateDnsRecords(DOMAIN, CUSTOMERNR, APIKEY, $apisessionid, $foundHosts)) {
105-
outputStdout("IP address updated successfully!");
106+
if (updateDnsRecords(DOMAIN, CUSTOMERNR, APIKEY, $apisessionid, $foundHostsV4)) {
107+
outputStdout("IPv4 address updated successfully!");
106108
} else {
107109
exit(1);
108110
}
109111
}
110112

113+
if (USE_IPV6 === true) {
114+
//Find the host defined in config.php
115+
$foundHostsV6 = array();
116+
117+
foreach ($infoDnsRecords['responsedata']['dnsrecords'] as $record) {
118+
if ($record['hostname'] === HOST && $record['type'] === "AAAA") {
119+
$foundHostsV6[] = array(
120+
'id' => $record['id'],
121+
'hostname' => $record['hostname'],
122+
'type' => $record['type'],
123+
'priority' => $record['priority'],
124+
'destination' => $record['destination'],
125+
'deleterecord' => $record['deleterecord'],
126+
'state' => $record['state'],
127+
);
128+
}
129+
}
130+
131+
//If we can't find the host, create it.
132+
if (count($foundHostsV6) === 0) {
133+
outputStdout(sprintf("AAAA record for host %s doesn't exist, creating necessary DNS record.", HOST));
134+
$foundHostsV6[] = array(
135+
'hostname' => HOST,
136+
'type' => 'AAAA',
137+
'destination' => 'newly created Record',
138+
);
139+
}
140+
141+
//If the host with AAAA record exists more than one time...
142+
if (count($foundHostsV6) > 1) {
143+
outputStderr(sprintf("Found multiple AAAA records for the host %s – Please specify a host for which only a single AAAA record exists in config.php. Exiting.", HOST));
144+
exit(1);
145+
}
146+
147+
//If we couldn't determine a valid public IPv6 address
148+
if (!$publicIPv6 = getCurrentPublicIPv6()) {
149+
outputStderr("Main API and fallback API didn't return a valid IPv6 address. Do you have IPv6 connectivity? If not, please disable USE_IPV6 in config.php. Exiting.");
150+
exit(1);
151+
}
152+
153+
$ipv6change = false;
154+
155+
//Has the IP changed?
156+
foreach ($foundHostsV6 as $record) {
157+
if ($record['destination'] !== $publicIPv6) {
158+
//Yes, it has changed.
159+
$ipv6change = true;
160+
outputStdout(sprintf("IPv6 address has changed. Before: %s; Now: %s", $record['destination'], $publicIPv6));
161+
} else {
162+
//No, it hasn't changed.
163+
outputStdout("IPv6 address hasn't changed. Current IPv6 address: ".$publicIPv6);
164+
}
165+
}
166+
167+
//Yes, it has changed.
168+
if ($ipv6change === true) {
169+
$foundHostsV6[0]['destination'] = $publicIPv6;
170+
//Update the record
171+
if (updateDnsRecords(DOMAIN, CUSTOMERNR, APIKEY, $apisessionid, $foundHostsV6)) {
172+
outputStdout("IPv6 address updated successfully!");
173+
} else {
174+
exit(1);
175+
}
176+
}
177+
}
178+
111179
//Logout
112180
if (logout(CUSTOMERNR, APIKEY, $apisessionid)) {
113181
outputStdout("Logged out successfully!");

0 commit comments

Comments
 (0)