-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathupdateddns.js
More file actions
172 lines (151 loc) · 6.27 KB
/
updateddns.js
File metadata and controls
172 lines (151 loc) · 6.27 KB
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
import { promises as fs } from 'fs';
// These are the parameters that need to be set. domainNames is an array of objects with the
// zoneName and aRecords for each domain. The aRecords are the subdomains or domains that you
// want to update with the new IP address.
const cloudflareAPIKey = '';
const domainNames = [{zoneName: "example.com", aRecords: ['<domain_or_subdomain>']}];
const IP_FILE_PATH = './previous_ip.txt';
const ipRegex = /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/;
// Main function
async function main() {
try {
const currentIP = await getCurrentIP();
// Make sure the IP address is valid using a regex
if (!ipRegex.test(currentIP)) {
console.error('Invalid IP address returned from IP service - aborting:', currentIP);
return;
}
// Check if the IP address has changed based on the stored IP
let previousIP = null;
try {
previousIP = await fs.readFile(IP_FILE_PATH, 'utf8');
} catch (error) {
if (error.code !== 'ENOENT') {
console.error('Error reading previous IP address:', error);
return;
}
}
if (currentIP === previousIP) {
console.log('IP address has not changed since last run. To force a run, delete the ' + IP_FILE_PATH + ' file. Address:', currentIP);
return;
}
if (currentIP) {
await updateCloudflareIP(currentIP);
await fs.writeFile(IP_FILE_PATH, currentIP, 'utf8');
console.log('IP address updated and saved:', currentIP);
} else {
console.error('Unable to fetch current IP address.');
}
} catch (error) {
console.error('An error occurred:', error);
}
}
// Function to get the current IP address
async function getCurrentIP() {
try {
const response = await fetch('https://ipinfo.io/ip');
const ipAddress = await response.text();
return ipAddress.trim();
} catch (error) {
console.error('Error fetching IP address:', error);
return null;
}
}
async function verifyAPIKey() {
try {
const headers = {
"Authorization": `Bearer ${cloudflareAPIKey}`,
'Content-Type': 'application/json',
};
const url = `https://api.cloudflare.com/client/v4/user/tokens/verify`;
const response = await fetch(url, { method: 'GET', headers });
const data = await response.json();
console.log(data);
if (data.success && data.result.status === 'active') {
return true;
}
}
catch (error) {
console.error('Error verifying API key:', error);
return false;
}
return false;
}
// Function to update Cloudflare DNS records
async function updateCloudflareIP(ipAddress) {
if(!verifyAPIKey()) {
console.error('Invalid API key');
return;
}
for(const domainName of domainNames) {
try {
const headers = {
'Authorization': `Bearer ${cloudflareAPIKey}`,
'Content-Type': 'application/json',
};
// Get the zone ID for the domain
let zoneId = null;
const url = `https://api.cloudflare.com/client/v4/zones?name=${domainName.zoneName}`;
const response = await fetch(url, { method: 'GET', headers });
const data = await response.json();
console.log(data);
try {
const response = await fetch(url, { method: 'GET', headers });
const data = await response.json();
console.log(data);
if (data.success) {
zoneId = data.result[0].id;
} else {
console.error('Error fetching zone ID:', data.errors);
return;
}
for (const aRecord of domainName.aRecords) {
const fqdn = `${aRecord}.${domainName.zoneName}`;
const dnsUrl = `https://api.cloudflare.com/client/v4/zones/${zoneId}/dns_records`;
const dnsResponse = await fetch(dnsUrl, { method: 'GET', headers });
const dnsData = await dnsResponse.json();
console.log(dnsData);
if (dnsData.success) {
const dnsRecords = dnsData.result;
const record = dnsRecords.find((record) => record.name === fqdn && record.type === 'A');
if (record) {
const recordId = record.id;
const updateUrl = `https://api.cloudflare.com/client/v4/zones/${zoneId}/dns_records/${recordId}`;
const body = {
content: ipAddress,
name: aRecord,
proxied: false,
type: 'A',
ttl: 1,
};
const updateResponse = await fetch(updateUrl, { method: 'PATCH', headers, body: JSON.stringify(body) });
const updateData = await updateResponse.json();
if (updateData.success) {
console.log(`Updated DNS record for ${aRecord} to ${ipAddress}`);
} else {
console.error(`Error updating DNS record for ${aRecord}:`, updateData.errors);
}
} else {
console.error(`DNS record for ${aRecord} not found.`);
}
} else {
console.error('Error fetching DNS records:', dnsData.errors);
}
}
} catch (error) {
console.error('An error occurred:', error);
}
if (data.success) {
zoneId = data.result[0].id;
console.log('Zone ID:', zoneId);
} else {
console.error('Error fetching zone ID:', data.errors);
return;
}
}
catch (error) {
console.error('Error updating Cloudflare DNS records:', error);
}
}
}
await main();