Reputation: 5773
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?
Upvotes: 123
Views: 118995
Reputation: 2813
I use Node.js package @Subash/mkcert, based on Forge.
It’s not the same as @FiloSottile/mkcert.
@Subash/mkcert is a free cross-platform package. I use it successfully on Ubuntu (see my example Travis CI build for Ubuntu 22.04.3 LTS Jammy Jellyfish) and on Windows (see my example AppVeyor CI build for Windows Server 2019) with the tools described in items 3.2—3.4 of this answer.
Simple installation via bun/npm/pnpm/Yarn — package managers, some one of which are already used by http-server users. The user doesn’t have to install anything additional, as in @FiloSottile/mkcert.
Simple usage:
# [INFO] @Subash/mkcert installation
npm install --global mkcert
# [INFO] Create a certificate authority
mkcert create-ca
# [INFO] Create a certificate
mkcert create-cert
# [INFO] Run http-server in background with HTTPS
# [INFO] Linux command
nohup http-server --cert cert.crt --key cert.key --tls &
# [INFO] Windows command
powershell -Command "Start-Process cmd -ArgumentList '/c http-server --cert cert.crt --key cert.key --tls'"
User of @Subash/mkcert can configure the certificate’s validity period using the --validity
option. The developer of @FiloSottile/mkcert refused to add the same option.
Programs/applications/tools/utilities that check the validity of a certificate don’t accept certificates from @Subash/mkcert. I’m having similar problems with self-signed certificates generated by OpenSSL and @FiloSottile/mkcert. Examples of problems:
Browsers. The user must manually bypass browser warnings.
Chrome. If a user is running on a local server tools that require Chrome or Puppeteer, he should use solutions like --ignore-certificate-errors
flag. For example, Pa11y users should use this configuration:
module.exports = {
defaults: {
chromeLaunchConfig: {
"args": [
"--ignore-certificate-errors"
]
}
}
};
Linkchecker. Linkchecker users must disable SSL certificate checking in the configuration file.
[checking]
sslverify=0
Node.js. If the user runs Node.js programs such as check-pages on the local server, he may need a solution like set environment variable NODE_TLS_REJECT_UNAUTHORIZED
with value 0
, which disables SSL certificate checking.
This answer is relevant for the latest versions of the tools described in it as of February 2024. In the future, data of my answer may be obsolete.
I hope that in the future my answer will be outdated and that will appear a free cross-platform solution that requires simple installation and configuration and allows users to test their projects on http-server with HTTPS without the hassle of verifying SSL certificates.
Upvotes: 0
Reputation: 1336
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
Upvotes: 1
Reputation: 761
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:
I referenced this blog: https://qiita.com/walkers/items/b90a97a99bbb27f6550f (written in Japanese)
Upvotes: 61
Reputation: 5126
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
Upvotes: 234
Reputation: 5773
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.
Upvotes: 2