feat: use SNI instead of create random server

This commit is contained in:
avwo
2018-06-02 13:13:48 +08:00
parent fc99872463
commit 5cd60f6ba2
3 changed files with 43 additions and 9 deletions
+3 -3
View File
@@ -124,10 +124,10 @@ function createCertificate(hostname) {
}]
} ]);
cert.sign(ROOT_KEY, forge.md.sha256.create());
cert = {
cert = createSecureContext({
key: pki.privateKeyToPem(ROOT_KEY),
cert: pki.certificateToPem(cert)
};
});
cachePairs.set(hostname, cert);
return cert;
}
@@ -168,7 +168,7 @@ function loadCustomCerts() {
var altNames = getAltNames(cert);
altNames.forEach(function(item) {
if (item.type === 2 && !customPairs[item.value]) {
customPairs[item.value] = cert;
customPairs[item.value] = createSecureContext(cert);
}
});
} catch (e) {}
+2 -3
View File
@@ -12,8 +12,7 @@ var rules = require('../rules');
var pluginMgr = require('../plugins');
var socketMgr = require('../socket-mgr');
var httpsUtil = require('./util');
var getDomain = httpsUtil.getDomain;
var serverAgent = httpsUtil.serverAgent;
var getSNIServer = httpsUtil.getSNIServer;
var parseReq = require('hparser').parse;
var RULE_KEY = 'x-whistle-rule-value';
@@ -602,7 +601,7 @@ module.exports = function(socket, hostname, callback) {
abortIfUnavailable(reqSocket);
callback(reqSocket);
} else {
serverAgent.createServer(getDomain(hostname), handleTlsSocket, function(port) {
getSNIServer(handleTlsSocket, function(port) {
reqSocket = net.connect(port, LOCALHOST, function() {
tunnelTmplData[reqSocket.localPort] = {
clientIp: socket.clientIp,
+38 -3
View File
@@ -1,8 +1,43 @@
var serverAgent = require('hagent').serverAgent;
var hagent = require('hagent');
var tls = require('tls');
var ca = require('./ca');
serverAgent.createCertificate = ca.createCertificate;
exports.serverAgent = serverAgent;
var createTLSServer = function(options, listener) {
return tls.createServer(options, listener);
};
var getTLSServer = hagent.create(createTLSServer, 41500);
var callbacks = [];
var TIMEOUT = 3000;
var sniPort;
var SNICallback = function(serverName, cb) {
serverName = ca.getDomain(serverName);
cb(null, ca.createCertificate(serverName));
};
exports.getSNIServer = function(listener, callback) {
if (sniPort) {
return callback(sniPort);
}
getTLSServer({ SNICallback: SNICallback }, listener, function(server, port) {
var removeServer = function() {
sniPort = null;
try {
server.close();
} catch(e) {} //重复关闭会导致异常
};
server.on('error', removeServer);
var timeout = setTimeout(removeServer, TIMEOUT);
server.once('secureConnection', function() {
clearTimeout(timeout);
});
sniPort = port;
callbacks.forEach(function(cb) {
cb(sniPort);
});
});
};
exports.getDomain = ca.getDomain;
exports.existsCustomCert = ca.existsCustomCert;
exports.getRootCAFile = ca.getRootCAFile;