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(JSON.stringify(data, null, ' '));
|
||||||
console.log('Test with');
|
console.log('Test with');
|
||||||
console.log('dig ' + options.hostname + ' ' + options.type);
|
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 options;
|
||||||
var hostname = opts.updater || 'redirect-www.org';
|
var hostname = opts.updater || 'redirect-www.org';
|
||||||
var port = opts.port || 65443;
|
var port = opts.port || 65443;
|
||||||
|
var req;
|
||||||
|
|
||||||
options = {
|
options = {
|
||||||
host: hostname
|
host: hostname
|
||||||
|
@ -49,7 +50,7 @@ module.exports.update = function (opts) {
|
||||||
|
|
||||||
options.agent = new https.Agent(options);
|
options.agent = new https.Agent(options);
|
||||||
|
|
||||||
https.request(options, function(res) {
|
req = https.request(options, function(res) {
|
||||||
var textData = '';
|
var textData = '';
|
||||||
|
|
||||||
res.on('error', function (err) {
|
res.on('error', function (err) {
|
||||||
|
@ -60,8 +61,22 @@ module.exports.update = function (opts) {
|
||||||
// console.log(chunk.toString());
|
// console.log(chunk.toString());
|
||||||
});
|
});
|
||||||
res.on('end', function () {
|
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 dummyCerts;
|
||||||
var serveFavicon;
|
var serveFavicon;
|
||||||
var secureContexts = {};
|
var secureContexts = {};
|
||||||
|
var loopbackApp;
|
||||||
|
var loopbackToken = require('crypto').randomBytes(32).toString('hex');
|
||||||
|
|
||||||
function loadDummyCerts() {
|
function loadDummyCerts() {
|
||||||
if (dummyCerts) {
|
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) {
|
function getAppContext(domaininfo) {
|
||||||
var localApp;
|
var localApp;
|
||||||
|
|
||||||
|
if ('loopback.daplie.invalid' === domaininfo.dirname) {
|
||||||
|
return getLoopbackApp();
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// TODO live reload required modules
|
// TODO live reload required modules
|
||||||
localApp = require(path.join(vhostsdir, domaininfo.dirname, 'app.js'));
|
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();
|
return runServer();
|
||||||
};
|
};
|
||||||
|
|
|
@ -87,7 +87,7 @@
|
||||||
"negotiator": "^0.5.1",
|
"negotiator": "^0.5.1",
|
||||||
"node-pre-gyp": "^0.6.4",
|
"node-pre-gyp": "^0.6.4",
|
||||||
"node-uuid": "1.x",
|
"node-uuid": "1.x",
|
||||||
"nodemailer": "1.x",
|
"nodemailer": "^1.4.0",
|
||||||
"nodemailer-mailgun-transport": "1.x",
|
"nodemailer-mailgun-transport": "1.x",
|
||||||
"oauth": "0.9.x",
|
"oauth": "0.9.x",
|
||||||
"oauth2orize": "git://github.com/coolaj86/oauth2orize.git#v1.0.1+scope.1",
|
"oauth2orize": "git://github.com/coolaj86/oauth2orize.git#v1.0.1+scope.1",
|
||||||
|
|
Loading…
Reference in New Issue