begin cli
This commit is contained in:
parent
04e788ddb4
commit
1928278e3f
|
@ -0,0 +1,94 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var cli = require('cli');
|
||||||
|
//var mkdirp = require('mkdirp');
|
||||||
|
|
||||||
|
// TODO link with RVPN service: server, email, domains, agree-tos
|
||||||
|
// TODO txt records for browser plugin: TXT _http.example.com _https.example.com
|
||||||
|
cli.parse({
|
||||||
|
debug: [ false, " show traces and logs", 'boolean', false ]
|
||||||
|
, 'plain-ports': [ false, " Port numbers to test with plaintext loopback. (default: 65080) (formats: <port>,<internal:external>,<internal:external1|external2>)", 'string' ]
|
||||||
|
, 'tls-ports': [ false, " Port numbers to test with tls loopback. (default: null)", 'string' ]
|
||||||
|
, 'ipify-urls': [ false, " Comma separated list of URLs to test for external ip. (default: api.ipify.org)", 'string' ]
|
||||||
|
, 'protocols': [ false, " Comma separated list of ip mapping protocols. (default: none,upnp,pmp)", 'string' ]
|
||||||
|
, 'rvpn-configs': [ false, " Comma separated list of Reverse VPN config files in the order they should be tried. (default: null)", 'string' ]
|
||||||
|
// TODO allow standalone, webroot, etc
|
||||||
|
});
|
||||||
|
|
||||||
|
// ignore certonly and extraneous arguments
|
||||||
|
cli.main(function(_, options) {
|
||||||
|
console.log('');
|
||||||
|
var args = {};
|
||||||
|
//var hp = require('../');
|
||||||
|
|
||||||
|
function parsePorts(portstr) {
|
||||||
|
var parts = portstr.split(':');
|
||||||
|
var opts = {
|
||||||
|
internal: parseInt(parts[0], 10)
|
||||||
|
, external: (parts[1]||parts[0]).split('|').map(function (port) {
|
||||||
|
return parseInt(port, 10);
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
return opts;
|
||||||
|
}
|
||||||
|
|
||||||
|
function exists(x) {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('options');
|
||||||
|
console.log(options);
|
||||||
|
args.debug = options.debug;
|
||||||
|
args.plainPorts = options['plain-ports'];
|
||||||
|
args.tlsPorts = options['tls-ports'];
|
||||||
|
args.protocols = options.protocols;
|
||||||
|
args.ipifyUrls = options['ipify-urls'];
|
||||||
|
args.rvpnConfigs = options['rvpn-configs'];
|
||||||
|
|
||||||
|
if ('false' === args.ipifyUrls || false === args.ipifyUrls) {
|
||||||
|
args.ipifyUrls = [];
|
||||||
|
} else {
|
||||||
|
args.ipifyUrls = (args.ipifyUrls || 'api.ipify.org').split(',');
|
||||||
|
}
|
||||||
|
if ('false' === args.protocols || false === args.protocols) {
|
||||||
|
args.protocols = [];
|
||||||
|
} else {
|
||||||
|
args.protocols = (args.protocols || 'none,upnp,pmp').split(',');
|
||||||
|
}
|
||||||
|
// Coerce to string. cli returns a number although we request a string.
|
||||||
|
args.tlsPorts = (args.tlsPorts || "").toString().split(',').filter(exists).map(parsePorts);
|
||||||
|
args.rvpnConfigs = (args.rvpnConfigs || "").toString().split(',').filter(exists);
|
||||||
|
if ('false' === args.plainPorts || false === args.plainPorts) {
|
||||||
|
args.plainPorts = [];
|
||||||
|
} else {
|
||||||
|
args.plainPorts = (args.plainPorts || "65080").toString().split(',').map(parsePorts);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('args');
|
||||||
|
console.log(args);
|
||||||
|
/*
|
||||||
|
return hp.create({
|
||||||
|
debug: args.debug
|
||||||
|
, plainPorts: args.plainPorts
|
||||||
|
, tlsPorts: args.plainPorts
|
||||||
|
}).register(args, function (err, results) {
|
||||||
|
if (err) {
|
||||||
|
console.error('[Error]: letsencrypt-cli');
|
||||||
|
console.error(err.stack || err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// should get back account, path to certs, pems, etc?
|
||||||
|
console.log('\nCertificates installed at:');
|
||||||
|
console.log(Object.keys(results).filter(function (key) {
|
||||||
|
return /Path/.test(key);
|
||||||
|
}).map(function (key) {
|
||||||
|
return results[key];
|
||||||
|
}).join('\n'));
|
||||||
|
|
||||||
|
process.exit(0);
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
});
|
|
@ -0,0 +1,60 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var http = require('http');
|
||||||
|
var https = require('https');
|
||||||
|
var express = require('express');
|
||||||
|
|
||||||
|
var middleware = module.exports.middleware = require('./middleware');
|
||||||
|
|
||||||
|
module.exports.create = function (opts) {
|
||||||
|
var httpsOptions = opts.httpsOptions || require('localhost.daplie.com-certificates');
|
||||||
|
var results = {
|
||||||
|
plainServers: []
|
||||||
|
, tlsServers: []
|
||||||
|
};
|
||||||
|
var app = express();
|
||||||
|
|
||||||
|
app.use('/', middleware(opts));
|
||||||
|
|
||||||
|
(opts.plainPorts||[]).forEach(function (plainPort) {
|
||||||
|
var plainServer = http.createServer();
|
||||||
|
plainServer.__plainPort = plainPort;
|
||||||
|
http.on('request', app);
|
||||||
|
results.plainServers.push(plainServer);
|
||||||
|
});
|
||||||
|
|
||||||
|
(opts.tlsPorts||[]).forEach(function (tlsPort) {
|
||||||
|
var tlsServer = https.createServer(httpsOptions);
|
||||||
|
tlsServer.__tlsPort = tlsPort;
|
||||||
|
http.on('request', app);
|
||||||
|
results.tlsServers.push(tlsServer);
|
||||||
|
});
|
||||||
|
|
||||||
|
function onListen() {
|
||||||
|
/*jshint validthis: true*/
|
||||||
|
var server = this;
|
||||||
|
var addr = server.address();
|
||||||
|
var proto = 'honorCipherOrder' in server ? 'https' : 'http';
|
||||||
|
|
||||||
|
console.info('Listening on ' + proto + '://' + addr.address + ':' + addr.port);
|
||||||
|
}
|
||||||
|
|
||||||
|
process.nextTick(function () {
|
||||||
|
results.plainServers.forEach(function (plainServer) {
|
||||||
|
plainServer.listen(
|
||||||
|
plainServer.__plainPort.port
|
||||||
|
, plainServer.__plainPort.address || '0.0.0.0'
|
||||||
|
, onListen
|
||||||
|
);
|
||||||
|
});
|
||||||
|
results.tlsServers.forEach(function (tlsServer) {
|
||||||
|
tlsServer.listen(
|
||||||
|
tlsServer.__tlsPort.port
|
||||||
|
, tlsServer.__tlsPort.address || '0.0.0.0'
|
||||||
|
, onListen
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return results;
|
||||||
|
};
|
|
@ -0,0 +1,60 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var scmp = require('scmp');
|
||||||
|
|
||||||
|
function middleware(opts) {
|
||||||
|
var key = opts.key;
|
||||||
|
var val = opts.value;
|
||||||
|
var vhost = opts.vhost;
|
||||||
|
var pathnamePrefix = opts.prefix || '/.well-known/com.daplie.loopback/';
|
||||||
|
var defaultHostname = 'loopback.daplie.invalid';
|
||||||
|
|
||||||
|
if (!key) {
|
||||||
|
opts.key = require('crypto').randomBytes(8).toString('hex');
|
||||||
|
}
|
||||||
|
if (!val) {
|
||||||
|
opts.value = require('crypto').randomBytes(16).toString('hex');
|
||||||
|
}
|
||||||
|
if (!vhost && vhost !== false) {
|
||||||
|
vhost = defaultHostname;
|
||||||
|
}
|
||||||
|
if ('/' !== pathnamePrefix[pathnamePrefix.length - 1]) {
|
||||||
|
pathnamePrefix += '/';
|
||||||
|
}
|
||||||
|
|
||||||
|
return function (req, res, next) {
|
||||||
|
var hostname = (req.hostname || req.headers.host || '').toLowerCase();
|
||||||
|
var urlpath = (req.pathname || req.url);
|
||||||
|
|
||||||
|
if (vhost !== false && vhost !== hostname) {
|
||||||
|
if (opts.debug) {
|
||||||
|
console.log("[HP] Host '" + hostname + "' failed to match '" + vhost + "'");
|
||||||
|
}
|
||||||
|
next();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 !== urlpath.indexOf(pathnamePrefix)) {
|
||||||
|
if (opts.debug) {
|
||||||
|
console.log("[HP] Pathname '" + urlpath + "'"
|
||||||
|
+ " failed to match '" + pathnamePrefix + "'");
|
||||||
|
}
|
||||||
|
next();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scmp(key, urlpath.substr(pathnamePrefix.length, key.length))) {
|
||||||
|
if (opts.debug) {
|
||||||
|
console.log("[HP] Pathname '" + urlpath + "'"
|
||||||
|
+ " failed to match '" + pathnamePrefix + key + "'");
|
||||||
|
}
|
||||||
|
next();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
res.setHeader('Content-Type', 'text/plain');
|
||||||
|
res.end(val);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = middleware;
|
Loading…
Reference in New Issue