-
Notifications
You must be signed in to change notification settings - Fork 29
/
ddns.php
executable file
·125 lines (113 loc) · 3.58 KB
/
ddns.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#!/usr/bin/env php
<?php
require __DIR__ . '/Cloudflare.php';
$confFile = __DIR__ . '/config.php';
if (!file_exists($confFile)) {
echo "Missing config file. Please copy config.php.skel to config.php and fill out the values therein.\n";
return 1;
}
$config = require $confFile;
foreach ([
'cloudflare_email',
'cloudflare_api_key',
'domain',
'record_name',
'ttl',
'proxied',
'protocol',
] as $key) {
if (!isset($config[$key]) || $config[$key] === '') {
echo "config.php is missing the '$key' config value\n";
return 1;
}
}
$api = new Cloudflare($config['cloudflare_email'], $config['cloudflare_api_key']);
// default to first value of config array
$domain = $config['domain'][0];
$recordName = $config['record_name'][0];
// set domain and record from request if value exists in config
if (isset($_GET['domain']) || isset($_GET['record'])) {
$domain = isset($_GET['domain']) ? $_GET['domain'] : null;
$recordName = isset($_GET['record']) ? $_GET['record'] : null;
if (
!$domain ||
!$recordName ||
!in_array($domain, $config['domain']) ||
!in_array($recordName, $config['record_name'])
) {
echo "Missing 'domain' or 'record_name' param, or domain or record_name is not in predefined list\n";
return 1;
}
}
if (isset($config['auth_token']) && $config['auth_token']) {
// API mode. Use IP from request params.
if (
empty($_GET['auth_token']) ||
empty($_GET['ip']) ||
$_GET['auth_token'] != $config['auth_token']
) {
echo "Missing or invalid 'auth_token' param, or missing 'ip' param\n";
return 1;
}
$ip = $_GET['ip'];
} else {
// Local mode. Get IP from service.
$ip = getIP($config['protocol']);
}
$verbose = !isset($argv[1]) || $argv[1] != '-s';
try {
$zone = $api->getZone($domain);
if (!$zone) {
echo "Domain $domain not found\n";
return 1;
}
$records = $api->getZoneDnsRecords($zone['id'], ['name' => $recordName]);
$record = $records && $records[0]['name'] == $recordName ? $records[0] : null;
if (!$record) {
if ($verbose) {
echo "No existing record found. Creating a new one\n";
}
$ret = $api->createDnsRecord($zone['id'], 'A', $recordName, $ip, [
'ttl' => $config['ttl'],
'proxied' => $config['proxied'],
]);
} elseif (
$record['type'] != 'A' ||
$record['content'] != $ip ||
$record['ttl'] != $config['ttl'] ||
$record['proxied'] != $config['proxied']
) {
if ($verbose) {
echo "Updating record.\n";
}
$ret = $api->updateDnsRecord($zone['id'], $record['id'], [
'type' => 'A',
'name' => $recordName,
'content' => $ip,
'ttl' => $config['ttl'],
'proxied' => $config['proxied'],
]);
} else {
if ($verbose) {
echo "Record appears OK. No need to update.\n";
}
}
return 0;
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
return 1;
}
// http://stackoverflow.com/questions/3097589/getting-my-public-ip-via-api
// http://major.io/icanhazip-com-faq/
function getIP($protocol)
{
$prefixes = [
'ipv4' => 'ipv4.',
'ipv6' => 'ipv6.',
'auto' => '',
];
if (!isset($prefixes[$protocol])) {
throw new Exception('Invalid "protocol" config value.');
}
return trim(file_get_contents('http://' . $prefixes[$protocol] . 'icanhazip.com'));
}