113

I'm using the npm package "http-server" (https://www.npmjs.com/package/http-server) to set up a simple webserver, but I cannot get it to use SSL. My command in package.json is

http-server -p 8000 -o -S

with a cert.pem and key.pem in my root directory (for now). The "-o" option opens a browser to the default page, but the page is served using HTTP and not even accessible through HTTPS. I don't get any errors or warnings. I've also tried adding the "-C" and "-K" options without luck. Has any one had any success with this package?

delucasvb
  • 5,393
  • 4
  • 25
  • 35
  • @Abhijeet That link is unavailable. – Rabbi Shuki Gur May 01 '19 at 20:38
  • @RabbiShukiGur sorry I don't own the resource. But thanks to https://web.archive.org [It's still available](https://web.archive.org/web/20190114150423/https://docs.nodejitsu.com/articles/HTTP/servers/how-to-create-a-HTTPS-server/) – Abhijeet May 02 '19 at 07:24

4 Answers4

221

First, make sure that you have key.pem and cert.pem files. You can generate them using this command:

openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -keyout key.pem -out cert.pem

You will be prompted with a few questions after entering the command. Use 127.0.0.1 as value for "Common name" if you want to be able to install the certificate in your OS's root certificate store or browser so that it is trusted.

This generates a cert-key pair and it will be valid for roughly 10 years (3650 days to be exact).

Then you need to run the server with -S for enabling SSL and -C for your certificate file:

$ http-server -S -C cert.pem -o
Starting up http-server, serving ./ through https
Available on:
  https:127.0.0.1:8080
  https:192.168.1.101:8080
  https:192.168.1.104:8080
Hit CTRL-C to stop the server
delucasvb
  • 5,393
  • 4
  • 25
  • 35
slomek
  • 4,873
  • 3
  • 17
  • 16
53

I installed mkcert:

brew install mkcert
brew install nss # if you use Firefox
mkcert -install

Then, in your project directory:

mkcert 0.0.0.0 localhost 127.0.0.1 ::1

Finally, I renamed generated files:

  • 0.0.0.0+3-key.pem -> key.pem
  • 0.0.0.0+3.pem -> cert.pem

And ran the following command:

http-server -S -C cert.pem -o

Then I got:

enter image description here

I referenced this blog: https://qiita.com/walkers/items/b90a97a99bbb27f6550f (written in Japanese)

Jeremy Caney
  • 7,102
  • 69
  • 48
  • 77
yummy_raspberry
  • 681
  • 5
  • 6
2

Just for future reference, my problem was solved by updating the package to the latest version in package.json. I copy-pasted an old example file without updating the version numbers.

delucasvb
  • 5,393
  • 4
  • 25
  • 35
1

EDIT: Since writing this answer there is a new tool mkcert that does this for you. See https://stackoverflow.com/a/61905546/9540493 instead. My original answer below for historical interest.

Firefox didn't accept self-signed certs, so a bit more effort was required. First create a CA:

openssl req -batch -new -newkey ec:(openssl ecparam -name prime256v1|psub) -nodes -keyout ca-key.pem -x509 -out ca.pem -days 3650 -subj "/CN=A localhost CA"

Add ca.pem (A localhost CA) to trusted certs of your OS and/or Firefox (other browsers use system CAs). Keep the ca* files in a secure location for future use, so you never have to do this again.

Then, for any site that you are running, and whenever you wish to change settings, create cert.pem and key.pem with:

openssl req -batch -new -newkey ec:(openssl ecparam -name prime256v1|psub) -nodes -keyout key.pem -subj /CN=localhost | openssl x509 -req -CAkey ca-key.pem -CA ca.pem -CAcreateserial -out cert.pem -days 365 -extfile (echo subjectAltName=DNS:localhost|psub)

The above should work on most systems. If not, you might want to create temporary files ecparam.tmp and ext.tmp. Commands functionally equivalent to the two oneliners:

# Output Elliptic Curve parameters to a temporary file
openssl ecparam -name prime256v1 -out ecparam.tmp

# Create CA
openssl req -batch -new -newkey ec:ecparam.tmp -nodes -keyout ca-key.pem \
  -x509 -out ca.pem -days 3650 -subj "/CN=A localhost CA"

# Create a CSR for localhost, then sign it by CA
echo subjectAltName=DNS:localhost > ext.tmp
openssl req -batch -new -newkey ec:ecparam.tmp -nodes -keyout key.pem \
  -subj /CN=localhost | openssl x509 -req -CAkey ca-key.pem -CA ca.pem \
  -CAcreateserial -out cert.pem -days 365 -extfile ext.tmp
Tronic
  • 1,248
  • 12
  • 16
  • When I run the first command I get an error. `openssl req -batch -new -newkey ec:<(openssl ecparam -name prime256v1) -nodes -keyout ca-key.pem -x509 -out ca.pem -days 3650 -subj "/CN=A localhost CA"` `req: Unrecognized flag ---BEGIN EC PARAMETERS----- req: Use -help for summary. ` – Kelly Jan 13 '20 at 22:30
  • Code updated with psub which should be better compatible with various shells. – Tronic Mar 23 '20 at 14:20
  • `NET::ERR_CERT_COMMON_NAME_INVALID` chrome 81 not accepting this cert – Tushar Kolhe Jul 18 '20 at 14:47
  • Are you accessing by "localhost", rather than by IP address? For IP or other addresses to work, you'll need to add more lines to ext.tmp, like `subjectAltName=IP:127.0.0.1`. The use of extfile can be entirely avoided with latest OpenSSL versions by using the `-addext` argument https://security.stackexchange.com/questions/74345/provide-subjectaltname-to-openssl-directly-on-the-command-line – Tronic Jul 19 '20 at 15:49