67

I followed the tutorial below to create a https server https://docs.nodejitsu.com/articles/HTTP/servers/how-to-create-a-HTTPS-server/

and the program runs without errors

but when I can not open https://localhost:8000 in my chrome

it always get a ERR_SSL_PROTOCOL_ERROR

enter image description here

jww
  • 97,681
  • 90
  • 411
  • 885
Littlee
  • 3,791
  • 6
  • 29
  • 61
  • 79
    Checking that https works is part of developing a website these days. Humble developers use localhost. I think the question is a good one. –  Mar 09 '18 at 11:51
  • It may be a somewhat better fit to Webmaster.SE, since it is more about setting up the environment, rather than coding as such. – Sherwood Botsford Nov 23 '20 at 19:51

10 Answers10

49

Well one quick way to do this is with ngrok.

It's really easy to use and only takes few secs to run. It is as simple as downloading your system version. Unzip and run ngrok.exe. It will open a command line type of window. Make sure your Apache server or the one you use is running.

Then to only listen on an HTTPS tunnel endpoint run the following

ngrok http -bind-tls=true site.dev:80

or on whatever port you need https to be installed.

Open browser and type https://localhost/myApp you will see it works.

And if you type http://localhost/myApp it also works.

Hope this is helpful to anyone for a fast solution.

Balloon Fight
  • 661
  • 8
  • 16
  • 1
    This doesn't work. Error: `You may only specify one port to tunnel to on the command line, got 3: [http -bind-tls=true site.dev:80]` – modle13 Nov 16 '17 at 04:31
  • 19
    what's site.dev here? – Pavan Nov 20 '17 at 12:45
  • 1
    @Pavan It looks like that is referring to, and I'm quoting from the `ngrok --help` docs, "forward traffic to example.com:8000". Or in this case, "to site.dev:80". I instead used `ngrok http 3000 -subdomain=custom -bind-tls=true`, then went to `https://custom.ngrok.io` on my local. – theblang Jun 11 '18 at 22:20
  • this is really awesome. Super easy solution. Thanks for sharing – max Jan 10 '19 at 22:32
  • It has solved my problems, I was trying in other ways and finally found a way to go forward locally... – Utpal Kumar Das May 03 '20 at 18:59
  • 2
    Running this command on Windows gives `unknown flag: --bind-tls`, anyone know how to get past this? – Eric Hasegawa Mar 07 '23 at 15:40
12

I use Caddyserver with config like this:

:443
tls self_signed
nemo
  • 12,241
  • 3
  • 21
  • 26
10

You need to do two things:

  • generate a self-signed SSL certificate and
  • add it to the trusted certificates

Managed to do this on a macOS like so:

openssl req -x509 -out localhost.crt -keyout localhost.key \
  -newkey rsa:2048 -nodes -sha256 \
  -subj '/CN=localhost' -extensions EXT -config <( \
   printf "[dn]\nCN=localhost\n[req]\ndistinguished_name = dn\n[EXT]\nsubjectAltName=DNS:localhost\nkeyUsage=digitalSignature\nextendedKeyUsage=serverAuth")
  • And to add the certificate to the trusted certificates, ran the following command (suggested on this blog):
sudo security add-trusted-cert -d -r trustRoot -k "/Library/Keychains/System.keychain" "/private/tmp/certs/certname.cer"
Ioanna
  • 1,311
  • 2
  • 23
  • 36
  • 2
    Sorry, is the downvote due to the macOS specific solution? I thought it would be straight forward to find the way to achieve that on other OSs, having an example. Should I make the response OS-independent? – Ioanna May 13 '19 at 02:24
  • 2
    If it's not about that, please let me know if I'm wrong so that I won't make the same mistake... – Ioanna May 13 '19 at 07:06
  • I get an error: Error reading file /private/tmp/certs/certname.cer - I don't seem to have a certs folder ? – Matt Parkins Jan 26 '20 at 15:54
  • The first command does not generate the `/private/tmp/certs/certname.cer` file expected by the second. – Stan James Jul 18 '22 at 21:02
8

If this is meant for testing and you don't need a valid cert (which seems to be the case since you're using "localhost") you can use a "self-signed" cert, just make sure to configure nginx to point to those.

I could explain the details, but there's actually a great post about that on Digital Ocean community tutorials:

https://www.digitalocean.com/community/tutorials/how-to-create-a-self-signed-ssl-certificate-for-nginx-in-ubuntu-16-04

just be sure to adapt the port (443) if you want to listen on 8000.

Mikec
  • 198
  • 7
6

I finally set up my create-react-app https dev server

the reason why I'm doing this is to test device motion API on a mobile device.

install mkcert https://github.com/FiloSottile/mkcert

brew install mkcert

mkcert -install

generate cert files.

mkcert -key-file ./.cert/key.pem -cert-file ./.cert/cert.pem "<LAN_IP_ADDRESS>"

use LAN IP address instead of "localhost", because we will open our https page on a mobile device that has connected to the same WiFi.

create a .env file to set env variables

HTTPS=true
SSL_CRT_FILE=./.cert/cert.pem
SSL_KEY_FILE=./.cert/key.pem

start the dev server

npm start

last but not least, install the cert file on the mobile device, the .pem file generated by mkcert is located in ~/Library/Application Support/mkcert in my case.

install cert file on an Android device

https://support.google.com/pixelphone/answer/2844832?hl=en

install cert file on an iOS device

serve the .pem file on a static server, and open the file address on Safari

Littlee
  • 3,791
  • 6
  • 29
  • 61
4

Assuming you are using node.js, then http-server has -S or --ssl with -C and -K to enable https.

Adriano
  • 3,788
  • 5
  • 32
  • 53
Qiulang
  • 10,295
  • 11
  • 80
  • 129
  • Just tried this but http-server doesn't support passphrases so not sure how this would even work. – Mac_W Oct 09 '19 at 16:17
  • Keep in mind http-server is good for dev usage, but not necessarily good for production usage. Passphrases is not a must for TLS/SSL mode. – Qiulang Oct 10 '19 at 02:41
  • I wasn't using for production, I had issue creating self-signing certificates without passphrase – Mac_W Oct 10 '19 at 09:41
  • Then it will just work as I have been using it that way for a long time. – Qiulang Oct 10 '19 at 09:53
1

A very simple way is using local-ssl-proxy

    npm i -g local-ssl-proxy

    local-ssl-proxy --source 3001 --target 3000
Seth Samuel
  • 245
  • 1
  • 3
  • 1
    Is the idea here to run two processes in parallel? The simple HTTP server, and also the local-ssl-proxy? – Tao Jan 18 '23 at 11:30
0

The solution provided by Balloon Fight is absolutely what I was looking for and it works. But the command mentioned didn't work for me, so here is what worked for me.

I am using Lubuntu 20.04 LTS (64-bit).

Lubuntu is a lightweight Linux flavor using Debian, Ubuntu and LXDE as its base.

Steps for OSX would probably be similar. Steps for Windows and Ubuntu GNOME are also mentioned.


  1. Go to ngrok and create an account.

  2. Download ngrok and install.

For Windows, just unzip the file and open it. It'll run in cmd.

For Ubuntu GNOME, you would probably be able to run the file directly in terminal.

For Lubuntu (or if previous didn't work for you). Move the file as follows:

mv "path/to/ngrok" "/usr/bin/"
  1. If the file had directly opened up in terminal or cmd. Copy and paste the command from your profile on ngrok into cmd or terminal. The command looks like this:

    ./ngrok authtoken <your_auth_token>

If you are on Lubuntu, or if the file did not open directly in terminal. Change directory as follows:

cd "/usr/bin/"

And then copy and paste the command from your profile on ngrok into terminal. The command looks like this:

./ngrok authtoken <your_auth_token>
  1. Run your server. Nodejs or what you usually use.

  2. If you are still in the same directory as 'ngrok' file. Copy and paste the following command into terminal or cmd:

    ngrok http 3000 -host-header="localhost:3000"

Change 3000 to the port you are using for the local server.

If you are out of 'ngrok' file's directory. Open it up in terminal or cmd.

For Lubuntu, use the following command to change directory:

cd "/usr/bin/"

Then run the command:

ngrok http 3000 -host-header="localhost:3000"

Change 3000 to the port you are using for the local server.

I got to know about this command from this video.

  1. Copy and paste the HTTPS link, in the second 'Forwarding' row, to your browser.

The link looks something like this: https://12fab5c82c57.ngrok.io

For the next time you are required to do it. Just repeat step 4, 5 and 6.

halfer
  • 19,824
  • 17
  • 99
  • 186
Varun
  • 73
  • 1
  • 10
  • It would be nice to have a solution that doesn't use ngrok because there is a 2 hour timeout on the dynamically created hostnames, and secondly, to bypass this requires a paid membership which is $20-25/month. – Shane Sepac Jun 06 '22 at 00:35
0

One more option:

npx https-localhost

The https://www.npmjs.com/package/https-localhost package depends on having npm installed, of course, and takes care of generating the required certificate and trusting it locally.

To serve an arbitrary path on an arbitrary port, you might do something like:

PORT=10000 npx https-localhost ~/my-experiment
Tao
  • 13,457
  • 7
  • 65
  • 76
-1

Check this answer about how to setup https for localhost.

enter image description here enter image description here

Cristi Maris
  • 1,329
  • 22
  • 21