Eu escrevi meu próprio tradutor de porta no NodeJS, e estou enviando o código aqui, caso alguém mais queira usá-lo. Ele faz conexões criptografadas com certificados https e também com a porta de texto simples 80. Eu o executo em uma instância EC2 t2.micro por US $ 10 por mês e ele funciona muito bem.
O único recurso necessário é que o navegador suporte SNICallback para que o servidor proxy possa usar dinamicamente o certificado correto para o domínio solicitado.
Este pequeno aplicativo abaixo aproveita o link para o NodeJS.
var proxyTable = {
'mydomain.com': 'http://localhost:8001',
'demo1.mydomain.com': 'https://localhost:8002', // https after proxy
'demo2.mydomain.com': 'https://localhost:8005', // https after proxy
'demo3.mydomain.com': 'https://localhost:8006', // https after proxy
'demo4.mydomain.com': 'https://localhost:8007', // https after proxy
'demo5.mydomain.com': 'https://localhost:8008', // https after proxy
}
http.createServer(function(req, res) {
var hostname = req.headers.host.replace(/^www\./, ''); // remove www. subdomain prefix
if (proxyTable[hostname]) {
if (-1 != httpsDomains.indexOf(hostname)) { // redirect to https for httpsDomains
redirectToHttps(req, res); // res.redirect() not available here
} else {
proxy.web(req, res, {target: proxyTable[hostname]});
}
} else {
displayError(res, hostname)
}
}).listen(80);
// Use SNICallback to dynamically use various SSL certificates depending upon hostname.
// To add a new SSL domain, add to secureContext AND proxyTable
const efboKey = fs.readFileSync(global.appRootPath + '/../mydomain.com.key', 'utf8');
const efboCert = fs.readFileSync(global.appRootPath + '/../mydomain.com.crt', 'utf8');
const efboCaBundleArray = makeCertificateAuthorityArray(global.appRootPath + '/../mydomain.com.ca-bundle', 'utf8');
const efboHttpsComponents = {
key: efboKey,
cert: efboCert,
ca: efboCaBundleArray,
};
var secureContext = {
'mydomain.com': tls.createSecureContext(efboHttpsComponents),
'demo1.mydomain.com': tls.createSecureContext(efboHttpsComponents),
'demo2.mydomain.com': tls.createSecureContext(efboHttpsComponents),
'demo3.mydomain.com': tls.createSecureContext(efboHttpsComponents),
'demo4.mydomain.com': tls.createSecureContext(efboHttpsComponents),
'demo5.mydomain.com': tls.createSecureContext(efboHttpsComponents),
}
try {
var options = {
SNICallback: function (hostname, cb) {
if (secureContext[hostname]) {
if (cb) {
cb(null, secureContext[hostname]);
} else {
return secureContext[hostname]; // compatibility for older versions of node
}
} else {
throw new Error('No keys/certificates for hostname requested');
}
},
// must list a key and cert because required by tls.createServer()
key: efboKey,
cert: efboCert,
ca: efboCaBundleArray,
}
https.createServer(options, function (req, res) {
var hostname = req.headers.host.replace(/^www\./, ''); // remove www. subdomain prefix
proxy.web(req, res, {target: proxyTable[hostname], secure: false}); // proxy https to http
}).listen(443);
} catch (err){
console.error(err.message);
console.error(err.stack);
}