Skip to content

Instantly share code, notes, and snippets.

@ethicka
Last active February 18, 2024 16:29
Show Gist options
  • Star 92 You must be signed in to star a gist
  • Fork 33 You must be signed in to fork a gist
  • Save ethicka/27c36c975a5c2cbbd1874bc78bab61c4 to your computer and use it in GitHub Desktop.
Save ethicka/27c36c975a5c2cbbd1874bc78bab61c4 to your computer and use it in GitHub Desktop.
Localhost SSL Certificate on Mac OS

🚨 2020 Update: I recommend using mkcert to generate local certificates. You can do everything below by just running the commands brew install mkcert and mkcert -install. Keep it simple!


This gives you that beautiful green lock in Chrome. I'm assuming you're putting your SSL documents in /etc/ssl, but you can put them anywhere and replace the references in the following commands. Tested successfully on Mac OS Sierra and High Sierra.

Set up localhost.conf

sudo nano /etc/ssl/localhost/localhost.conf

Content:

[req]
default_bits = 1024
distinguished_name = req_distinguished_name
req_extensions = v3_req

[req_distinguished_name]

[v3_req]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names

[alt_names]
DNS.1 = localhost

Commands

Run these commands:

sudo openssl genrsa -out /etc/ssl/localhost/localhost.key 2048
sudo openssl rsa -in /etc/ssl/localhost/localhost.key -out /etc/ssl/localhost/localhost.key.rsa

If you're changing the domain from localhost then update the variable CN in the following:

sudo openssl req -new -key /etc/ssl/localhost/localhost.key.rsa -subj /CN=localhost -out /etc/ssl/localhost/localhost.csr -config /etc/ssl/localhost/localhost.conf

I set the certificate to expire in 10 years (3650 days).

sudo openssl x509 -req -extensions v3_req -days 3650 -in /etc/ssl/localhost/localhost.csr -signkey /etc/ssl/localhost/localhost.key.rsa -out /etc/ssl/localhost/localhost.crt -extfile /etc/ssl/localhost/localhost.conf
sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain /etc/ssl/localhost/localhost.crt

Done.

Bonus: BrowserSync works over HTTPS

The whole reason I got into this was to get browserSync to work over HTTPS. This will allow you to use browserSync in your gulpfile.js with the following added browserSync command:

browserSync.init({
  https: {
    key: "/etc/ssl/localhost/localhost.key",
    cert: "/etc/ssl/localhost/localhost.crt"
  },
});

Or in Webpacks (webpack.config.watch.js or webpack.config.js):

new BrowserSyncPlugin({
  advanced: {
    browserSync: {
      https: {
        key: "/etc/ssl/localhost/localhost.key",
        cert: "/etc/ssl/localhost/localhost.crt"
      },
    }
  }
}),
@mortensassi
Copy link

this is great! thank you

@daveharmswebdev
Copy link

works on Catalina!!!

Copy link

ghost commented Dec 12, 2019

good work.

@MKlblangenois
Copy link

Hi @ethicka !

I've just tried your tips, but I got an infinite loading with BrowserSync, but UI works fine. Have you any idea why ? I'm on MacOS 10.15.2

Thanks !

@ethicka
Copy link
Author

ethicka commented Feb 4, 2020

@MKlblangenois Did you update your configuration so it's going to https://localhost:3000 instead of http? That might cause a redirect issue. Also, try accessing it in an incognito window or open the inspector so it's not getting the site from cache. Those are usually what cause issues for me.

@G-Nat
Copy link

G-Nat commented Feb 5, 2020

I have this infinite loop too now.. without localhost.conf – on Catalina (MacOS 10.15.2) ANd it's not only chrome, it reloads crazy in safari too.
I am migration my workspace from High Sierra, everything works fine there... but now on Catalina i have so much issues... omg. Including this hot reload (saying localhost, connection refused)

@VonRehberg
Copy link

I tried it myself and it wasnt working as the default hash is not taken into consideration.
You need to add -sha256 option when signing the CSR and reduce the validity period to 2 years. Afterwards I was able to connect to the server.

@Rutvik17
Copy link

Thanks alottt!!!

@funtime41
Copy link

Thanks - Trying this in Catalina - but still https://localhost/ localhost refused to connect. I think I am using etc/apache2 - do I need to update .conf or .ini files to point to the mkcert in my system or something? Thanks for you help in advance

@ethicka
Copy link
Author

ethicka commented May 24, 2021

@funtime41 I haven't tested this since High Sierra so I don't know. I would try using /etc/ssl or other non-reserved folder – I didn't find the location mattered as long as it was accessible by the script I was using it for. I haven't used this specific solution for awhile, though – I've been using mkcert since 2020 successfully for localhost SSLs.

@ThriledLokki983
Copy link

ThriledLokki983 commented Oct 29, 2021

Hi, could anyone be kind to support me on how to configure chrome to accept both http://localhost && https://localhost ??
After getting the ssl set up, my chrome wont even open non secure localhost communication. (e.g. http://localhost:3000 will not open on chrome but it does open on Safari and Firefox)

@mortensassi
Copy link

mortensassi commented Oct 29, 2021

@ThriledLokki983 Mkcert is the way to go

  1. Install Mkcert globally
  2. go to your project (Where package.json is)
  3. mkdir certs and then cd certs
  4. here you create your certs with mkcert localhost
  5. now setup your browser-sync
browserSync.init({
  https: {
    key: "certs/cert-key.pem", // or whatever gets generated
    cert: "certs/cert.pem"
  },
});

hope that helps!

Also if you have trouble with chrome, try open the page in a private browser or delete browser data
And Firefox needs NSS, so make sure to install that too

@chengtie
Copy link

chengtie commented Nov 1, 2021

Hello, Is it normal that sudo nginx -t returns nginx: [warn] "ssl_stapling" ignored, issuer certificate not found for certificate "/etc/ssl/localhost/localhost.crt"?

@freddysein
Copy link

Great dude, this worked for localhost and any domain name locally. All installed on a mac running Monterey v12.4.
Thank you
Freddy

@wanxe
Copy link

wanxe commented Aug 12, 2022

it works, thank u!

@dibsonthis
Copy link

Works like a charm, thank you. I needed pem files, but it was an easy extra step to export the .crt and .key to .pem.

@pbalan
Copy link

pbalan commented Jun 29, 2023

Thanks for this! Same for me I had to convert both to .pem for this to work.

sudo openssl x509 -in /etc/ssl/localhost/localhost.crt -out /etc/ssl/localhost/localhost.pem
sudo openssl rsa -in /etc/ssl/localhost/localhost.key -out /etc/ssl/localhost/localhost.key.pem

@h3ct0rjs
Copy link

h3ct0rjs commented Sep 27, 2023

just one question @ethicka @pbalan before I try, if instead of using localhost as my domain name I want to use otherone , should I change :

[alt_names]
DNS.1 = DOMAIN.COM

I'm new into the macos environment

@jerry7991
Copy link

Great dude, this worked for localhost and any domain name locally.
Thank you

@aldoyh
Copy link

aldoyh commented Oct 10, 2023

Thank you so much @ethicka.

And for those are still struggling on macOS checkout these projects, they have it out of the Box!

  1. PhpWebStudy
  2. And From Laravel valet or their latest product Herd

Enjoy!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment