Skip to content

Commit

Permalink
IMPORTANT: Automate the certificate installation on MacOS
Browse files Browse the repository at this point in the history
On MacOs, a certificate is automatically generated and installed.
  • Loading branch information
daquinoaldo committed Jan 15, 2019
1 parent a756936 commit b22b3e0
Show file tree
Hide file tree
Showing 11 changed files with 153 additions and 17 deletions.
12 changes: 11 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# MacOS
.DS_STORE

# IDEs
.idea
*.iml
.DS_STORE

# Node
node_modules

# Other
coverage
cert/CA.*
cert/localhost.*
cert/server.csr
33 changes: 22 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,6 @@ Serve static files or import as module in your project.
[![npm version](https://img.shields.io/npm/v/https-localhost.svg)](https://www.npmjs.com/package/https-localhost?activeTab=versions)


### Install and trust the certificate
Add the [rootCA.pem](rootCA.pem) certificate to your list of trusted certificates.
This step depends on the operating system you're running:

- Mac OS: open Keychain Access, choose System from the left navigation bar, choose "Import items..." from the File app
menu and select the file. Then double-click on the certificate and select always-trust in the Trust panel.

- Linux: Depending on your Linux distribution, you can use `trust`, `update-ca-certificates` or another command to mark
the generated root certificate as trusted.


### Use standalone
From terminal navigate into the folder and run `sudo npm install -g` to install this tool globally.

Expand Down Expand Up @@ -51,5 +40,27 @@ To redirect the http traffic to https use `app.redirect()`.
You can also serve static files with `app.serve(path)`


### [Optional/Linux] Install and trust the certificate
After `npm install` will run a script that tries to install and validate automatically the certificate.
**Actually works only on MacOS.**

However, this script is in beta and provided as-is, so there isn't any guarantee that will work.
For that reason you can also install the certificate manually, as follows.

If you decide to not install it, it's fine, the package still work.
However, visiting localhost there will be a invalid certificate issue.

To trust the certificate just add the [cert/defaultCA.pem](cert/defaultCA.pem) certificate
to your list of trusted certificates.

This step depends on the operating system you're running:
- Mac OS:
open Keychain Access, choose System from the left navigation bar, choose "Import items..." from the File app
menu and select the file. Then double-click on the certificate and select always-trust in the Trust panel.
- Linux:
Depending on your Linux distribution, you can use `trust`, `update-ca-certificates`
or another command to mark the generated root certificate as trusted.


### License
[AGPL-3.0](LICENSE)
File renamed without changes.
File renamed without changes.
File renamed without changes.
34 changes: 34 additions & 0 deletions cert/generate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
const exec = require("child_process").exec

// noinspection FallThroughInSwitchStatementJS
switch (process.platform) {
case "darwin": // MacOS
console.log("\n----------------------------------------------\n" +
"Please input your sudo password when required.\n" +
"----------------------------------------------\n")
exec("bash cert/generate.sh", (error, stdout, stderr) => {
console.log(stdout)
console.error(stderr)
if (error !== null) console.error(`exec error: ${error}`)
})
break
case "linux":
console.warn("Cannot generate the localhost certificate on linux yet. " +
"Coming soon.")
process.exit(0)
case "win32":
console.warn("Cannot generate the localhost certificate on Windows.")
process.exit(0)
case "freebsd":
console.warn("Cannot generate the localhost certificate on freebsd. " +
"Help wanted.")
process.exit(0)
case "sunos":
console.warn("Cannot generate the localhost certificate on sunos. " +
"Help wanted.")
process.exit(0)
default:
console.warn("Cannot generate the localhost certificate on your " +
"platform. Contact the developer.")
process.exit(0)
}
47 changes: 47 additions & 0 deletions cert/generate.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#!/usr/bin/env bash

# capture errors and notify the user
set -e
trap 'if [[ $? -ne 0 ]]; then echo "ERROR: something went wrong."; fi' EXIT

# check the os
case "$(uname -s)" in
Darwin*) machine=MacOS;;
Linux*) machine=Linux
echo "Linux support coming soon"
exit 1;;
CYGWIN*) machine=Linux
echo "WARNING: Support for Cygwin not guaranteed. Trying with the Linux script (coming soon)."
exit 1;;
MINGW*) machine=Linux
echo "WARNING: Support for MinGw not guaranteed. Trying with the Linux script (coming soon)."
exit 1;;
*) echo "Unknown operating system."; exit 1;;
esac

# generate the CA
echo "Creating a certification authority to sign the certificate..."
openssl req -x509 -newkey rsa:4096 -keyout cert/CA.key -out cert/CA.pem -days 1024 -nodes -subj "/C=US/ST=None/L=None/O=None/OU=None/CN=localhost"
echo "Generated CA.key and CA.pem."

# install the CA
case ${machine} in
MacOS*)
sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain cert/CA.pem
;;
Linux*)
echo "WARNING: Only Ubuntu is supported. No guarantee for other Linux distributions."
sudo mkdir /usr/local/share/ca-certificates/localhost
cp cert/CA.key /usr/local/share/ca-certificates/localhost/CA.key
cp cert/CA.pem /usr/local/share/ca-certificates/localhost/CA.pem
sudo chmod 775 /usr/local/share/ca-certificates/localhost
sudo update-ca-certificates
;;
*) exit 1;;
esac

# crate the certificate
echo "Creating a certificate for localhost and signing with out CA..."
openssl req -new -sha256 -nodes -out cert/server.csr -newkey rsa:2048 -keyout cert/localhost.key -config cert/server.conf
openssl x509 -req -in cert/server.csr -CAkey cert/CA.key -CA cert/CA.pem -CAcreateserial -out cert/localhost.crt -days 1024 -sha256 -extfile cert/x509.ext
echo "Generated localhost.key and localhost.crt."
14 changes: 14 additions & 0 deletions cert/server.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[req]
default_bits=2048
prompt=no
default_md=sha256
distinguished_name=dn

[dn]
C=US
ST=None
L=None
O=None
OU=None
emailAddress=mail@example.com
CN=localhost
7 changes: 7 additions & 0 deletions cert/x509.ext
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names

[alt_names]
DNS.1 = localhost
20 changes: 16 additions & 4 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,21 @@ const minify = require("express-minify")
/* CONFIGURE THE SERVER */

// SSL certificate
const certOptions = {
key: fs.readFileSync(path.resolve(__dirname, "cert/server.key")),
cert: fs.readFileSync(path.resolve(__dirname, "cert/server.crt"))
let certOptions
try {
certOptions = {
key: fs.readFileSync(path.resolve(__dirname, "cert/localhost.key")),
cert: fs.readFileSync(path.resolve(__dirname, "cert/localhost.crt"))
}
} catch (e) {
// istanbul ignore next
certOptions = {
key: fs.readFileSync(path.resolve(__dirname, "cert/default.key")),
cert: fs.readFileSync(path.resolve(__dirname, "cert/default.crt"))
}
// istanbul ignore next
console.warn("Using the default certificate. " +
"Validate it installing the defaultCA.pem certificate in the cert folder")
}

// create a server with express
Expand Down Expand Up @@ -53,7 +65,7 @@ app.serve = function(path = process.cwd(), port = process.env.PORT || 443) {
/* MAIN (running as script) */

// usage: `serve [<path>]` or `node index.js [<path>]`
/* istanbul ignore if */
// istanbul ignore if
if (require.main === module) {
// retrieve the static path from the process argv or use the cwd
// 1st is node, 2nd is serve or index.js, 3rd (if exists) is the path
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"scripts": {
"pretest": "eslint --ignore-path .gitignore .",
"test": "./node_modules/istanbul/lib/cli.js cover ./node_modules/mocha/bin/_mocha -- -R spec ./test/*.js --exit",
"postinstall": "node cert/generate.js",
"start": "node index.js"
},
"bin": {
Expand All @@ -30,7 +31,7 @@
"bugs": {
"url": "https://github.com/daquinoaldo/https-localhost/issues"
},
"homepage": "https://daquinoaldo.github.io/https-localhost/",
"homepage": "https://daquinoaldo.github.io/https-localhost",
"dependencies": {
"compression": "^1.7.3",
"express": "^4.16.4",
Expand Down

0 comments on commit b22b3e0

Please sign in to comment.