环境
nodejs版本不低于10.16
系统window,centos 均可
{
"name": "aliyun-ddns",
"version": "2.1.0",
"main": "ddns.js",
"scripts": {
"start": "node ddns.js"
},
"author": "luoyefe",
"license": "MIT",
"dependencies": {
"@alicloud/pop-core": "^1.7.13",
"axios": "^0.20.0"
},
"description": "借助阿里云解析API实现DDNS"
}
nodejs代码
const config={
accessKeyId: "666666", // 你的阿里云AccessKey ID
accessKeySecret: "888888",// 你的阿里云AccessKey Secret
DomainName: 'google.com', //你的域名
RRKeyWord: 'ddns', // 子域名
}
const Core = require('@alicloud/pop-core');
const axios = require('axios');
const client = new Core({
accessKeyId: config.accessKeyId,
accessKeySecret: config.accessKeySecret,
endpoint: 'https://alidns.aliyuncs.com',
apiVersion: '2015-01-09'
});
// 获取当前公网IP地址,用多个API ,防止一个失效后,有另外的进行替代
async function getPublicIP() {
const ipApis = [
'https://api.ipify.org?format=json',
'https://ipinfo.io/json',
'https://icanhazip.com',
'http://ip-api.com/json'
];
for (const api of ipApis) {
try {
const response = await axios.get(api);
const ip = response.data.ip || response.data; // 处理不同API的返回结构
console.log(`成功从 ${api} 获取公网IP: ${ip}`);
return ip;
} catch (error) {
console.error(`从 ${api} 获取公网IP失败:`, error);
}
}
throw new Error('所有IP查询API均不可用');
}
// 获取指定域名和子域名的DNS记录ID及其值
async function getRecordIdAndValue(domainName, rr) {
return new Promise((resolve, reject) => {
client.request('DescribeDomainRecords', {
DomainName: domainName,
RRKeyWord: rr
}, { method: 'POST' }).then((result) => {
const record = result.DomainRecords.Record.find(r => r.RR === rr);
if (record) {
resolve({ recordId: record.RecordId, value: record.Value });
} else {
reject(new Error('没有找到对应的记录'));
}
}, (ex) => {
reject(ex);
});
});
}
// 更新DNS记录
async function updateDNSRecord(recordId, ip,rr) {
return new Promise((resolve, reject) => {
client.request('UpdateDomainRecord', {
RecordId: recordId,
RR: rr,
Type: 'A',
Value: ip
}, { method: 'POST' }).then((result) => {
resolve(result);
}, (ex) => {
console.log("client.request失败",ex)
reject(ex);
});
});
}
// 主程序
(async () => {
try {
let domainName=config.DomainName;
let rr=config.RRKeyWord;
const ip = await getPublicIP();
console.log('当前公网IP地址:', ip);
const { recordId, value } = await getRecordIdAndValue(domainName, rr);
console.log('DNS记录ID:', recordId);
console.log('当前DNS记录值:', value);
if (value !== ip) {
const result = await updateDNSRecord(recordId, ip,rr);
console.log('DNS记录更新成功:', result);
} else {
console.log('DNS记录值未变化,无需更新');
}
} catch (error) {
console.error('操作失败:', error);
}
})();