|
| 1 | +var httpProxy = require('http-proxy'), |
| 2 | + execSync = require('exec-sync'), |
| 3 | + sprintf = require("util").format, |
| 4 | + fs = require('fs'), |
| 5 | + path = require('path'), |
| 6 | + crypto = require('crypto'), |
| 7 | + https = require('https'), |
| 8 | + sys = require('sys'); |
| 9 | + |
| 10 | + |
| 11 | +var certPath = path.resolve(process.env.HOME, '.nassau-proxy'), |
| 12 | + listenPort = process.env.PORT || 443; |
| 13 | + |
| 14 | +function generateCertificate(name, CA) { |
| 15 | + var passKeyPath = path.resolve(certPath, name + ".pass.key"), |
| 16 | + keyPath = path.resolve(certPath, name + ".key"), |
| 17 | + csrPath = path.resolve(certPath, name + ".csr"), |
| 18 | + resultPath = path.resolve(certPath, name + ".crt"); |
| 19 | + |
| 20 | + fs.existsSync(certPath) || fs.mkdirSync(certPath); |
| 21 | + |
| 22 | + if (false === fs.existsSync(passKeyPath)) try { |
| 23 | + console.log("Generating: " + passKeyPath); |
| 24 | + execSync(sprintf('openssl genrsa -des3 -passout pass:nassauproxy -out "%s" 2048', passKeyPath)); |
| 25 | + } catch (E) {} |
| 26 | + |
| 27 | + if (false === fs.existsSync(keyPath)) try { |
| 28 | + console.log("Generating: " + keyPath); |
| 29 | + execSync(sprintf('openssl rsa -passin pass:nassauproxy -in "%s" -out "%s"', passKeyPath, keyPath)); |
| 30 | + } catch (E) {} |
| 31 | + |
| 32 | + if (false === fs.existsSync(csrPath)) try { |
| 33 | + console.log('Generating: ' + csrPath); |
| 34 | + execSync(sprintf("bash -c 'echo -e \"PL\\nmazowieckie\\nWarszawa\\nNassau SC\\n\\n"+name+"\\n\\n\\n\\n\\n\" | openssl req -new -key \"%s\" -out \"%s\"'", |
| 35 | + keyPath, csrPath |
| 36 | + )); |
| 37 | + } catch (E) {} |
| 38 | + |
| 39 | + if (false === fs.existsSync(resultPath)) try { |
| 40 | + if (CA) { |
| 41 | + console.log("Signing the certificate using your own CA: " + resultPath); |
| 42 | + execSync(sprintf('openssl x509 -req -days 365 -in "%s" -CA "%s" -CAkey "%s" -CAcreateserial -out "%s"', |
| 43 | + csrPath, CA.cert, CA.key, resultPath |
| 44 | + )); |
| 45 | + |
| 46 | + } else { |
| 47 | + console.log("Add this cert as a trusted root to get rid of SSL warnings: " + resultPath); |
| 48 | + |
| 49 | + execSync(sprintf('openssl x509 -req -days 365 -in "%s" -out "%s" -signkey "%s"', |
| 50 | + csrPath, resultPath, keyPath |
| 51 | + )); |
| 52 | + |
| 53 | + } |
| 54 | + } catch (E) {} |
| 55 | + |
| 56 | + return { |
| 57 | + "cert": resultPath, |
| 58 | + "key": keyPath |
| 59 | + } |
| 60 | +} |
| 61 | + |
| 62 | +// force the CA |
| 63 | +var CA = generateCertificate('ssl.proxy.nassau'); |
| 64 | + |
| 65 | +var ssl = { |
| 66 | + SNICallback: function (domain) { |
| 67 | + var domainCert = generateCertificate(domain, CA); |
| 68 | + |
| 69 | + return crypto.createCredentials({ |
| 70 | + key: fs.readFileSync(domainCert.key), |
| 71 | + cert: fs.readFileSync(domainCert.cert), |
| 72 | + ca: [fs.readFileSync(CA.cert)] |
| 73 | + }).context; |
| 74 | + }, |
| 75 | + key: fs.readFileSync(CA.key, 'utf8'), |
| 76 | + cert: fs.readFileSync(CA.cert, 'utf8'), |
| 77 | + requestCert: true, |
| 78 | + rejectUnauthorized: false |
| 79 | +}; |
| 80 | + |
| 81 | +var proxy = httpProxy.createProxyServer({ target: { host: "localhost", port: 80 } }); |
| 82 | + |
| 83 | +proxy.on('proxyReq', function(proxyReq, req, res, options) { |
| 84 | + proxyReq.setHeader('X-Forwarded-Protocol', 'https'); |
| 85 | + proxyReq.setHeader('X-Forwarded-Proto', 'https'); |
| 86 | +}); |
| 87 | +https.createServer(ssl, function(req, res) { |
| 88 | + proxy.web(req, res); |
| 89 | +}).listen(listenPort); |
| 90 | + |
| 91 | +console.log("Listening on " + listenPort); |
0 commit comments