custom https certs, http-to-https redirects
This commit is contained in:
parent
c947d2c9e1
commit
f068d84490
47
README.md
47
README.md
|
@ -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)
|
||||||
|
|
|
@ -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"
|
||||||
}
|
}
|
||||||
|
|
81
serve.js
81
serve.js
|
@ -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) {
|
||||||
|
|
|
@ -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
|
Loading…
Reference in New Issue