hourly update ip address
This commit is contained in:
parent
2166090e33
commit
7d17139a4b
|
@ -64,5 +64,5 @@ cli.main(function (args, options) {
|
|||
console.log(JSON.stringify(data, null, ' '));
|
||||
console.log('Test with');
|
||||
console.log('dig ' + options.hostname + ' ' + options.type);
|
||||
})
|
||||
});
|
||||
});
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
module.exports = { token: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy.zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz" };
|
|
@ -11,6 +11,7 @@ module.exports.update = function (opts) {
|
|||
var options;
|
||||
var hostname = opts.updater || 'redirect-www.org';
|
||||
var port = opts.port || 65443;
|
||||
var req;
|
||||
|
||||
options = {
|
||||
host: hostname
|
||||
|
@ -49,7 +50,7 @@ module.exports.update = function (opts) {
|
|||
|
||||
options.agent = new https.Agent(options);
|
||||
|
||||
https.request(options, function(res) {
|
||||
req = https.request(options, function(res) {
|
||||
var textData = '';
|
||||
|
||||
res.on('error', function (err) {
|
||||
|
@ -60,8 +61,22 @@ module.exports.update = function (opts) {
|
|||
// console.log(chunk.toString());
|
||||
});
|
||||
res.on('end', function () {
|
||||
resolve(textData);
|
||||
var err;
|
||||
try {
|
||||
resolve(JSON.parse(textData));
|
||||
} catch(e) {
|
||||
err = new Error("Unparsable Server Response");
|
||||
err.code = 'E_INVALID_SERVER_RESPONSE';
|
||||
err.data = textData;
|
||||
reject(err);
|
||||
}
|
||||
});
|
||||
}).end(JSON.stringify(opts.ddns, null, ' '));
|
||||
});
|
||||
|
||||
req.on('error', function () {
|
||||
reject(err);
|
||||
});
|
||||
|
||||
req.end(JSON.stringify(opts.ddns, null, ' '));
|
||||
});
|
||||
};
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
'use strict';
|
||||
|
||||
var updateIp = require('../holepunch/helpers/update-ip.js').update;
|
||||
// TODO XXX use API + storage
|
||||
var token = require('../dyndns-token.js').token;
|
||||
|
||||
/*
|
||||
* @param {string[]} hostnames - A list of hostnames
|
||||
* @param {Object[]} addresses - A list of { address: <ip-address>, family: <4|6> }
|
||||
*/
|
||||
function update(hostnames, addresses) {
|
||||
// TODO use not-yet-built API to get and store tokens
|
||||
// TODO use API to add and remove nameservers
|
||||
var services = [
|
||||
// TODO XXX don't disable cacert checking
|
||||
{ hostname: 'ns1.redirect-www.org', port: 65443, cacert: false }
|
||||
, { hostname: 'ns2.redirect-www.org', port: 65443, cacert: false }
|
||||
];
|
||||
var answers = [];
|
||||
var promises;
|
||||
var results = [];
|
||||
var PromiseA;
|
||||
|
||||
hostnames.forEach(function (hostname) {
|
||||
addresses.forEach(function (address) {
|
||||
var answer = {
|
||||
"name": hostname
|
||||
, "value": address.address
|
||||
, "type": null
|
||||
, "priority": null
|
||||
, "token": token
|
||||
};
|
||||
|
||||
if (4 === address.family) {
|
||||
answer.type = 'A';
|
||||
}
|
||||
else if (6 === address.family) {
|
||||
answer.type = 'AAAA';
|
||||
}
|
||||
else {
|
||||
console.error('[ERROR] unspported address:');
|
||||
console.error(address);
|
||||
return;
|
||||
}
|
||||
|
||||
answers.push(answer);
|
||||
});
|
||||
});
|
||||
|
||||
promises = services.map(function (service, i) {
|
||||
return updateIp({
|
||||
updater: service.hostname
|
||||
, port: service.port
|
||||
, cacert: service.cacert
|
||||
, token: token
|
||||
, ddns: answers
|
||||
}).then(function (data) {
|
||||
results[i] = { service: service, data: data };
|
||||
return data;
|
||||
}).error(function (err) {
|
||||
results[i] = { service: service, error: err };
|
||||
});
|
||||
});
|
||||
|
||||
PromiseA = require('bluebird').Promise;
|
||||
return PromiseA.all(promises).then(function () {
|
||||
return results;
|
||||
});
|
||||
}
|
||||
|
||||
module.exports.update = function () {
|
||||
var allMap = {};
|
||||
var hostnames = require('../redirects.json').reduce(function (all, redirect) {
|
||||
if (!allMap[redirect.from.hostname]) {
|
||||
allMap[redirect.from.hostname] = true;
|
||||
all.push(redirect.from.hostname);
|
||||
}
|
||||
if (!all[redirect.to.hostname]) {
|
||||
allMap[redirect.to.hostname] = true;
|
||||
all.push(redirect.to.hostname);
|
||||
}
|
||||
|
||||
return all;
|
||||
}, []);
|
||||
|
||||
return require('./ip-checker').getExternalAddresses().then(function (result) {
|
||||
//console.log(Object.keys(allMap), result);
|
||||
//console.log(hostnames)
|
||||
//console.log(result.addresses);
|
||||
console.log('[IP CHECKER] hostnames.length', hostnames.length);
|
||||
console.log('[IP CHECKER] result.addresses.length', result.addresses.length);
|
||||
return update(hostnames, result.addresses);
|
||||
});
|
||||
};
|
||||
|
||||
if (require.main === module) {
|
||||
module.exports.update().then(function (results) {
|
||||
console.log('results');
|
||||
console.log(results);
|
||||
});
|
||||
}
|
|
@ -0,0 +1,126 @@
|
|||
"use strict";
|
||||
|
||||
var PromiseA = require('bluebird').Promise;
|
||||
var ifaces = require('os').networkInterfaces();
|
||||
var dns = PromiseA.promisifyAll(require('dns'));
|
||||
var https = require('https');
|
||||
|
||||
function getExternalAddresses() {
|
||||
var iftypes = {};
|
||||
|
||||
Object.keys(ifaces).forEach(function (ifname) {
|
||||
ifaces[ifname].forEach(function (iface) {
|
||||
if (iface.internal) {
|
||||
return;
|
||||
}
|
||||
/*
|
||||
if (/^(::|f[cde])/.test(iface.address)) {
|
||||
console.log('non-public ipv6');
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
iftypes[iface.family] = true;
|
||||
});
|
||||
});
|
||||
|
||||
var now = Date.now();
|
||||
|
||||
return PromiseA.all([
|
||||
dns.lookupAsync('api.ipify.org', { family: 4/*, all: true*/ }).then(function (ans) {
|
||||
iftypes.IPv4 = { address: ans[0], family: ans[1], time: Date.now() - now };
|
||||
}).error(function () {
|
||||
//console.log('no ipv4', Date.now() - now);
|
||||
iftypes.IPv4 = false;
|
||||
})
|
||||
, dns.lookupAsync('api.ipify.org', { family: 6/*, all: true*/ }).then(function (ans) {
|
||||
iftypes.IPv6 = { address: ans[0], family: ans[1], time: Date.now() - now };
|
||||
}).error(function () {
|
||||
//console.log('no ipv6', Date.now() - now);
|
||||
iftypes.IPv6 = false;
|
||||
})
|
||||
]).then(function () {
|
||||
var requests = [];
|
||||
|
||||
if (iftypes.IPv4) {
|
||||
requests.push(new PromiseA(function (resolve) {
|
||||
var req = https.request({
|
||||
method: 'GET'
|
||||
, hostname: iftypes.IPv4.address
|
||||
, port: 443
|
||||
, headers: {
|
||||
Host: 'api.ipify.org'
|
||||
}
|
||||
, path: '/'
|
||||
//, family: 4
|
||||
// TODO , localAddress: <<external_ipv4>>
|
||||
}, function (res) {
|
||||
var result = '';
|
||||
|
||||
res.on('error', function (/*err*/) {
|
||||
resolve(null);
|
||||
});
|
||||
|
||||
res.on('data', function (chunk) {
|
||||
result += chunk.toString('utf8');
|
||||
});
|
||||
res.on('end', function () {
|
||||
resolve({ address: result, family: 4/*, wan: result === iftypes.IPv4.localAddress*/, time: iftypes.IPv4.time });
|
||||
});
|
||||
});
|
||||
|
||||
req.on('error', function () {
|
||||
resolve(null);
|
||||
});
|
||||
req.end();
|
||||
}));
|
||||
}
|
||||
|
||||
if (iftypes.IPv6) {
|
||||
requests.push(new PromiseA(function (resolve) {
|
||||
var req = https.request({
|
||||
method: 'GET'
|
||||
, hostname: iftypes.IPv6.address
|
||||
, port: 443
|
||||
, headers: {
|
||||
Host: 'api.ipify.org'
|
||||
}
|
||||
, path: '/'
|
||||
//, family: 6
|
||||
// TODO , localAddress: <<external_ipv6>>
|
||||
}, function (res) {
|
||||
var result = '';
|
||||
|
||||
res.on('error', function (/*err*/) {
|
||||
resolve(null);
|
||||
});
|
||||
|
||||
res.on('data', function (chunk) {
|
||||
result += chunk.toString('utf8');
|
||||
});
|
||||
res.on('end', function () {
|
||||
resolve({ address: result, family: 6/*, wan: result === iftypes.IPv6.localAaddress*/, time: iftypes.IPv4.time });
|
||||
});
|
||||
});
|
||||
|
||||
req.on('error', function () {
|
||||
resolve(null);
|
||||
});
|
||||
req.end();
|
||||
}));
|
||||
}
|
||||
|
||||
return PromiseA.all(requests).then(function (ips) {
|
||||
ips = ips.filter(function (ip) {
|
||||
return ip;
|
||||
});
|
||||
|
||||
return {
|
||||
addresses: ips
|
||||
, time: Date.now() - now
|
||||
};
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
exports.getExternalAddresses = getExternalAddresses;
|
|
@ -9,6 +9,8 @@ module.exports.create = function (securePort, certsPath, vhostsdir) {
|
|||
var dummyCerts;
|
||||
var serveFavicon;
|
||||
var secureContexts = {};
|
||||
var loopbackApp;
|
||||
var loopbackToken = require('crypto').randomBytes(32).toString('hex');
|
||||
|
||||
function loadDummyCerts() {
|
||||
if (dummyCerts) {
|
||||
|
@ -294,9 +296,20 @@ module.exports.create = function (securePort, certsPath, vhostsdir) {
|
|||
};
|
||||
}
|
||||
|
||||
function getLoopbackApp() {
|
||||
return function (req, res) {
|
||||
res.setHeader('Content-Type', 'application/json; charset=utf-8');
|
||||
res.end(JSON.stringify({ "success": true, "token": loopbackToken }));
|
||||
};
|
||||
}
|
||||
|
||||
function getAppContext(domaininfo) {
|
||||
var localApp;
|
||||
|
||||
if ('loopback.daplie.invalid' === domaininfo.dirname) {
|
||||
return getLoopbackApp();
|
||||
}
|
||||
|
||||
try {
|
||||
// TODO live reload required modules
|
||||
localApp = require(path.join(vhostsdir, domaininfo.dirname, 'app.js'));
|
||||
|
@ -589,5 +602,23 @@ module.exports.create = function (securePort, certsPath, vhostsdir) {
|
|||
});
|
||||
}
|
||||
|
||||
function updateIps() {
|
||||
console.log('[UPDATE IP]');
|
||||
require('./ddns-updater').update().then(function (results) {
|
||||
results.forEach(function (result) {
|
||||
if (result.error) {
|
||||
console.error(result);
|
||||
} else {
|
||||
console.log('[SUCCESS]', result.service.hostname);
|
||||
}
|
||||
});
|
||||
}).error(function (err) {
|
||||
console.error('[UPDATE IP] ERROR');
|
||||
console.error(err);
|
||||
});
|
||||
}
|
||||
// TODO check the IP every 5 minutes and update it every hour
|
||||
setInterval(updateIps, 60 * 60 * 1000);
|
||||
updateIps();
|
||||
return runServer();
|
||||
};
|
||||
|
|
|
@ -87,7 +87,7 @@
|
|||
"negotiator": "^0.5.1",
|
||||
"node-pre-gyp": "^0.6.4",
|
||||
"node-uuid": "1.x",
|
||||
"nodemailer": "1.x",
|
||||
"nodemailer": "^1.4.0",
|
||||
"nodemailer-mailgun-transport": "1.x",
|
||||
"oauth": "0.9.x",
|
||||
"oauth2orize": "git://github.com/coolaj86/oauth2orize.git#v1.0.1+scope.1",
|
||||
|
|
Loading…
Reference in New Issue