Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add passphrase option #746

Merged
merged 7 commits into from Oct 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 9 additions & 0 deletions README.md
Expand Up @@ -103,6 +103,15 @@ Then you need to run the server with `-S` for enabling SSL and `-C` for your cer
http-server -S -C cert.pem
```

If you wish to use a passphrase with your private key you can include one in the openssl command via the -passout parameter (using password of foobar)


e.g.
`openssl req -newkey rsa:2048 -passout pass:foobar -keyout key.pem -x509 -days 365 -out cert.pem`

For security reasons, the passphrase will only be read from the `NODE_HTTP_SERVER_SSL_PASSPHRASE` environment variable.


This is what should be output if successful:

``` sh
Expand Down
4 changes: 3 additions & 1 deletion bin/http-server
Expand Up @@ -68,6 +68,7 @@ if (argv.h || argv.help) {
var port = argv.p || argv.port || parseInt(process.env.PORT, 10),
host = argv.a || '0.0.0.0',
tls = argv.S || argv.tls,
sslPassphrase = process.env.NODE_HTTP_SERVER_SSL_PASSPHRASE,
proxy = argv.P || argv.proxy,
proxyOptions = argv['proxy-options'],
utc = argv.U || argv.utc,
Expand Down Expand Up @@ -175,7 +176,8 @@ function listen(port) {
if (tls) {
options.https = {
cert: argv.C || argv.cert || 'cert.pem',
key: argv.K || argv.key || 'key.pem'
key: argv.K || argv.key || 'key.pem',
passphrase: sslPassphrase,
};
try {
fs.lstatSync(options.https.cert);
Expand Down
1 change: 1 addition & 0 deletions doc/http-server.1
Expand Up @@ -114,6 +114,7 @@ If not specified, uses cert.pem.
.BI \-K ", " \-\-key " " [\fIFILE\fR]
Path to SSL key file.
If not specified, uses key.pem.
Passphrase will be read from NODE_HTTP_SERVER_SSL_PASSPHRASE (if set)

.TP
.BI \-r ", " \-\-robots " " [\fIUSER\-AGENT\fR]
Expand Down
6 changes: 5 additions & 1 deletion lib/http-server.js
Expand Up @@ -173,7 +173,11 @@ function HttpServer(options) {
serverOptions.https = options.https;
}

this.server = union.createServer(serverOptions);
this.server = serverOptions.https && serverOptions.https.passphrase
// if passphrase is set, shim must be used as union does not support
? require('./shims/https-server-shim')(serverOptions)
: union.createServer(serverOptions);

if (options.timeout !== undefined) {
this.server.setTimeout(options.timeout);
}
Expand Down
67 changes: 67 additions & 0 deletions lib/shims/https-server-shim.js
@@ -0,0 +1,67 @@
/* eslint-disable no-process-env */
/* eslint-disable no-sync */
var https = require('https');
var fs = require('fs');
var core = require('union/lib/core');
var RoutingStream = require('union/lib/routing-stream');

module.exports = function (options) {
var isArray = Array.isArray(options.after);
var credentials;

if (!options) {
throw new Error('options is required to create a server');
}

function requestHandler(req, res) {
var routingStream = new RoutingStream({
before: options.before,
buffer: options.buffer,
after:
isArray &&
options.after.map(function (After) {
return new After();
}),
request: req,
response: res,
limit: options.limit,
headers: options.headers
});

routingStream.on('error', function (err) {
var fn = options.onError || core.errorHandler;
fn(err, routingStream, routingStream.target, function () {
routingStream.target.emit('next');
});
});

req.pipe(routingStream);
}

var serverOptions;

serverOptions = options.https;
if (!serverOptions.key || !serverOptions.cert) {
throw new Error(
'Both options key and cert are required.'
);
}

credentials = {
key: fs.readFileSync(serverOptions.key),
cert: fs.readFileSync(serverOptions.cert),
passphrase: process.env.NODE_HTTP_SERVER_SSL_PASSPHRASE
};

if (serverOptions.ca) {
serverOptions.ca = !Array.isArray(serverOptions.ca)
? [serverOptions.ca]
: serverOptions.ca;

credentials.ca = serverOptions.ca.map(function (ca) {
return fs.readFileSync(ca);
});
}

return https.createServer(credentials, requestHandler);
};