用nodejs写一个ddns服务


一个用nodejs写ddns服务

准备

域名注册(这里是用的阿里云注册的)
申请阿里云accessKeyId和accessKeySecret

具体代码

index.js

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
// https://hpdell.github.io/%E7%BC%96%E7%A8%8B/nodejs-ddns/index.html
// Node.js 实现阿里云域名的动态解析

const Core = require('@alicloud/pop-core');
const moment = require('moment');

let newIP = "127.0.0.1";
const RecordId = ''//对应域名的RecordId 通过OpenAPI Explorer(https://api.aliyun.com/#/)-云解析-DescribeDomainRecords直接获取即可
const RR = ''//对应域名前缀 如aaa.example.com的aaa
const accessKeyId = ''//调用阿里云api所需,请自行前往控制台获取
const accessKeySecret = ''//调用阿里云api所需,请自行前往控制台获取

let client = new Core({
accessKeyId,
accessKeySecret,
endpoint: 'https://alidns.aliyuncs.com',
apiVersion: '2015-01-09'
});

let describeDomainRecordInfoParams = {
RecordId
};

let updateDomainRecordParams = {
RecordId,
RR, //需要更改的域名记录
Type: "A" //更改的类型
}

let requestOption = {
method: 'POST'
}
const publicIp = require('public-ip');
const t = 3600000
console.log(`动态域名解析服务启动成功!检测间隔:${t / 1000 / 60}min`);
console.log(`现在时间:${moment().format("YYYY-MM-DD HH:mm:ss")},开始第一次更新`);
if (!accessKeyId || !accessKeySecret) {
console.log('请填写accessKeyId和accessKeySecret后再运行本程序!');
return
}
if (!RecordId) {
console.log('请填写RecordId后再运行本程序!');
return
}
if (!RR) {
console.log('请填写需要更改的域名记录后再运行本程序!');
return
}
check()
// 一小时查询一次3600000
clearInterval(timer)
var timer = setInterval(() => {
console.log(`本次检测时间:${moment().format("YYYY-MM-DD HH:mm:ss")}`);
check()
}, t);

function check() {
publicIp.v4().then(ip => {
if (ip) {
newIP = ip
console.log('本机IP:' + ip);
client.request("DescribeDomainRecordInfo", describeDomainRecordInfoParams, requestOption).then((result) => {
var oldIP = result.Value;
console.log('当前域名IP为:' + oldIP);
if (oldIP != newIP) {
console.log(`检测到IP不一致!旧:${oldIP},新:${newIP},开始更新`);
updateDomainRecordParams = {
...updateDomainRecordParams,
"Value": newIP
};
client.request("UpdateDomainRecord", updateDomainRecordParams, requestOption).then(() => {
console.log('更新成功,新IP为:' + newIP);
// process.exit(0);
}).catch((reason) => {
console.error("更新IP失败,原因:", reason);
// process.exit(1);
});
} else {
console.log(`IP无更改,本次跳过`);
}
}).catch((reason) => {
console.error("获取域名IP失败,原因:", reason);
// process.exit(1);
})
}
});
}

pageage.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
{
"name": "ddns",
"version": "1.0.0",
"description": "ddns",
"main": "index.js",
"scripts": {
"start": "cross-env NODE_ENV=dev nodemon index.js ",
"build": "npm i && cross-env NODE_ENV=prod pm2 start index.js -n ddns && pm2 logs ddns",
"rebuild":"pm2 delete ddns && npm i && cross-env NODE_ENV=prod pm2 start index.js -n ddns && pm2 logs ddns",
"reload":"pm2 reload ddns && pm2 logs ddns"
},
"author": "sola",
"license": "ISC",
"dependencies": {
"@alicloud/pop-core": "^1.7.7",
"axios": "^0.19.0",
"moment": "^2.24.0",
"public-ip": "^3.2.0"
},
"devDependencies": {
"cross-env": "^6.0.0",
"nodemon": "^1.19.2"
}
}

部署

安装nodejs 和pm2;然后运行npm run build