custom https certs, http-to-https redirects

This commit is contained in:
AJ ONeal 2015-07-08 00:43:46 -06:00
parent c947d2c9e1
commit f068d84490
4 changed files with 138 additions and 11 deletions

View File

@ -1,7 +1,11 @@
localhost.daplie.com-server serve-https
=========================== ===========
Serves HTTPS using TLS (SSL) certs for localhost.daplie.com - great for testing and development. Serves HTTPS using TLS (SSL) certs.
Bundles a valid certificate for localhost.daplie.com - great for testing and development.
Also great for testing ACME certs from letsencrypt.org.
Install Install
------- -------
@ -21,6 +25,15 @@ Usage
* `-p <port>` - i.e. `sudo serve-https -p 443` * `-p <port>` - i.e. `sudo serve-https -p 443`
* `-d <dirpath>` - i.e. `serve-https -d /tmp/` * `-d <dirpath>` - i.e. `serve-https -d /tmp/`
* `-c <content>` - i.e. `server-https -c 'Hello, World! '` * `-c <content>` - i.e. `server-https -c 'Hello, World! '`
* `--insecure-port <port>` - run an http server that redirects to https
Specifying a custom HTTPS certificate:
* `--key /path/to/privkey.pem`
* `--cert /path/to/cert.pem`
* `--chain /path/to/chain.pem`
Note: you may specify a file containing all certificate authorities or use even `--chain` multiple times such as `--chain /path/to/intermediate-ca-1.pem --chain /path/to/intermediate-ca-2.pem`
Examples Examples
-------- --------
@ -28,7 +41,7 @@ Examples
```bash ```bash
serve-https -p 1443 -c 'Hello from 1443' & serve-https -p 1443 -c 'Hello from 1443' &
serve-https -p 2443 -c 'Hello from 2443' & serve-https -p 2443 -c 'Hello from 2443' &
serve-https -p 3443 -d /tmp & serve-https -p 3443 -d /tmp --insecure-port 4080 &
curl https://localhost.daplie.com:1443 curl https://localhost.daplie.com:1443
> Hello from 1443 > Hello from 1443
@ -39,3 +52,29 @@ curl --insecure https://localhost:2443
curl https://localhost.daplie.com:3443 curl https://localhost.daplie.com:3443
> [html index listing of /tmp] > [html index listing of /tmp]
``` ```
And if you tested <http://localhost.daplie.com:4080> in a browser,
it would redirect to <https://localhost.daplie.com:3443>.
(in curl it would just show an error message)
### Testing ACME Let's Encrypt certs
You can get free https certificates from letsencrypt.org (ACME letsencrypt)
and even a free domain from https://freedns.afraid.org.
```bash
serve-https -p 8443 \
--key /etc/letsencrypt/live/test.mooo.com/privkey.pem \
--cert /etc/letsencrypt/live/test.mooo.com/cert.pem \
--chain /etc/letsencrypt/live/test.mooo.com/chain.pem \
-c "$(cat '/etc/letsencrypt/live/test.mooo.com/chain.pem')"
```
```bash
curl --insecure https://test.mooo.com:8443 > ./chain.pem
curl https://test.mooo.com:8843 --cacert ./chain.pem
```
* [QuickStart Guide for Let's Encrypt](https://coolaj86.com/articles/lets-encrypt-on-raspberry-pi/)
* [QuickStart Guide for FreeDNS](https://coolaj86.com/articles/free-dns-hosting-with-freedns-afraid-org.html)

View File

@ -41,6 +41,7 @@
"finalhandler": "^0.4.0", "finalhandler": "^0.4.0",
"localhost.daplie.com-certificates": "^1.0.2", "localhost.daplie.com-certificates": "^1.0.2",
"minimist": "^1.1.1", "minimist": "^1.1.1",
"redirect-https": "^1.1.0",
"serve-index": "^1.7.0", "serve-index": "^1.7.0",
"serve-static": "^1.10.0" "serve-static": "^1.10.0"
} }

View File

@ -2,21 +2,48 @@
'use strict'; 'use strict';
var https = require('https'); var https = require('https');
var http = require('http');
var fs = require('fs');
var path = require('path'); var path = require('path');
function createServer(port, pubdir, content) { function createInsecureServer(port, pubdir, opts) {
var options = require('localhost.daplie.com-certificates'); var server = http.createServer();
var server = https.createServer(options);
server.on('error', function (err) {
console.error(err);
process.exit(1);
});
server.on('request', require('redirect-https')({
port: port
}));
server.listen(opts.insecurePort, function () {
var msg = 'Serving ' + pubdir + ' at http://' + opts.servername;
var p = server.address().port;
if (80 !== p) {
msg += ':' + p;
}
console.info(msg);
});
}
function createServer(port, pubdir, content, opts) {
var server = https.createServer(opts);
var app = require('./app'); var app = require('./app');
var directive = { public: pubdir, content: content }; var directive = { public: pubdir, content: content };
if (opts.insecurePort) {
createInsecureServer(port, pubdir, opts);
}
server.on('error', function (err) { server.on('error', function (err) {
console.error(err); console.error(err);
process.exit(1); process.exit(1);
}); });
server.listen(port, function () { server.listen(port, function () {
var msg = 'Serving ' + pubdir + ' at https://localhost.daplie.com'; var msg = 'Serving ' + pubdir + ' at https://' + opts.servername;
var p = server.address().port; var p = server.address().port;
if (443 !== p) { if (443 !== p) {
msg += ':' + p; msg += ':' + p;
@ -40,10 +67,52 @@ module.exports.createServer = createServer;
function run() { function run() {
var minimist = require('minimist'); var minimist = require('minimist');
var argv = minimist(process.argv.slice(2)); var argv = minimist(process.argv.slice(2));
var port = argv.p || argv._[0] || 1443; var port = argv.p || argv.port || argv._[0] || 1443;
var pubdir = path.resolve(argv.d || argv._[1] || process.cwd()); var pubdir = path.resolve(argv.d || argv._[1] || process.cwd());
var content = argv.c; var content = argv.c;
createServer(port, pubdir, content);
var cert = require('localhost.daplie.com-certificates');
var opts = {
key: cert.key
, cert: cert.cert
, ca: cert.ca
, SNICallback: function (servername, cb) {
cb(null, require('tls').createSecureContext(opts));
return;
}
};
if (argv.key || argv.cert || argv.chain) {
if (!argv.key || !argv.cert || !argv.chain) {
console.error("You must specify each of --key --cert and --chain (chain may be empty)");
return;
}
if (!Array.isArray(argv.chain)) {
argv.chain = [argv.chain];
}
opts.key = fs.readFileSync(argv.key);
opts.cert = fs.readFileSync(argv.cert);
// turn multiple-cert pemfile into array of cert strings
opts.ca = argv.chain.reduce(function (chain, fullpath) {
return chain.concat(fs.readFileSync(fullpath, 'ascii')
.split('-----END CERTIFICATE-----')
.filter(function (ca) {
return ca.trim();
}).map(function (ca) {
return (ca + '-----END CERTIFICATE-----').trim();
}));
}, []);
}
opts.servername = 'localhost.daplie.com';
if (argv.servername) {
opts.servername = argv.servername;
}
opts.insecurePort = argv.i || argv['insecure-port'];
createServer(port, pubdir, content, opts);
} }
if (require.main === module) { if (require.main === module) {

18
test-chain.sh Executable file
View File

@ -0,0 +1,18 @@
#!/bin/bash
node serve.js \
--port 8443 \
--key node_modules/localhost.daplie.com-certificates/certs/server/my-server.key.pem \
--cert node_modules/localhost.daplie.com-certificates/certs/server/my-server.crt.pem \
--chain node_modules/localhost.daplie.com-certificates/certs/ca/intermediate.crt.pem \
--chain node_modules/localhost.daplie.com-certificates/certs/ca/root.crt.pem \
-c "$(cat node_modules/localhost.daplie.com-certificates/certs/ca/root.crt.pem)" &
PID=$!
sleep 1
curl -s --insecure http://localhost.daplie.com:8443 > ./root.pem
curl -s https://localhost.daplie.com:8443 --cacert ./root.pem
rm ./root.pem
kill $PID 2>/dev/null