Using a local development trusted CA on MacOS

TLS certificates are so ubiquitous that you now very often need them even during the development phase.

Developers are thus used to create “self-signed” certificates and configure their client requiring TLS support to accept self-signed certificates. This can be fine for development: As both the client and the server are on the same computer, the risk of man-in-the-middle attacks is limited. However, this can still be a dangerous setup, as you take the risk to forget the option and ship to production a client that accepts self-signed certificates. It would thus be vulnerable to man-in-the-middle attacks and defeat the purpose of using TLS in the first place.

We can help you build your next macOS app in weeks rather than months
Read more about ProcessOne and Swift »

The best approach is to create your own local certificate authority for development and to have your development computer trust that root CA. This article will show how to configure such an environment on MacOS with both ejabberd and Phoenix. If you are developing on Linux however, you should be able to use mkcert as well and can skip the part on setting up the iOS simulator.

Note: Be careful not to share your root CA key, as it could be exploited to run targeted man-in-the-middle attacks against your development computer.

Creating the local trusted Certificate Authority

The mkcert project is making this setup very easy.

First, install mkcert on your Mac, for example with Homebrew:

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

Then, create your CA root certificate and install it in your trusted store (it will ask your admin password):

$ mkcert -install
Using the local CA at "/Users/mremond/Library/Application Support/mkcert"
The local CA is now installed in the Firefox trust store (requires browser restart)! ????

Finally, create your signed certificate for your localhost:

$ mkcert localhost 127.0.0.1 ::1
Using the local CA at "/Users/mremond/Library/Application Support/mkcert"

Created a new certificate valid for the following names ????
 - "localhost"
 - "127.0.0.1"
 - "::1"

The certificate is at "./localhost+2.pem" and the key at "./localhost+2-key.pem"

You should now be able to use Safari or Firefox with a service using that new certificate without having any SSL trust warning.

Installing your root certificate in your iOS simulator and development device

When developing iOS applications, you have to use HTTPS or secure Websockets (or have to set a temporary exception in your project info.plist). Reusing your local certificate authority is thus the best approach as well during development. You just have to tell iOS to trust your local CA.

  1. Drag and drop the rootCA.pem file on your simulator. That file is locating in the directory ~/Library/Application Support/mkcert. The simulator will open Safari and offer you to download the file.

  2. Accept the file download. Safari will then confirm that the file has been added to your profiles.

You now need to install it from the setting to trust it.

  1. Go to the Settings app and then to “General -> Profile”. Select your new mkcert profile and click install and then confirm installation. The root certificate should now be displayed as verified.

  2. Still in the Settings app, you can now go to “General -> About -> Certificate Trust Settings” to enable full trust for that root certificate.

You will now have no trust warning when you connect on HTTPS on localhost on a site using your signed cert. You can also use HTTPS or Secure Websockets from a development iOS app, without any workaround.

You can use a similar approach on your development device to have your device download the rootCA.pem file and ensure the OS will trust it.

Configuring your server applications to use your signed certificates

ejabberd

Configuring ejabberd to use your signed development certificate can be done copying your localhost+2.pem and localhost+2-key.pem file to ejabberd config directory and referring to them in the config file:

hosts:
  - localhost

...

certfiles:
  - localhost+2-key.pem
  - localhost+2.pem

listen:
  -
    port: 5222
    ip: "::"
    module: ejabberd_c2s
    max_stanza_size: 262144
    shaper: c2s_shaper
    access: c2s
    starttls_required: true
  -
    port: 5269
    ip: "::"
    module: ejabberd_s2s_in
    max_stanza_size: 524288
  -
    port: 5443
    ip: "::"
    module: ejabberd_http
    tls: true
    request_handlers:
      "/admin": ejabberd_web_admin
      "/api": mod_http_api
      "/bosh": mod_bosh
      "/captcha": ejabberd_captcha
      "/upload": mod_http_upload
      "/ws": ejabberd_http_ws
      "/oauth": ejabberd_oauth

You should now be able to use ejabberd https service on https://localhost:5443 without any warning. You thus can use secure Websocket and BOSH over HTTPS.

Phoenix

Copy your localhost key and cert to your Phoenix project directory priv/cert:

$ mkdir priv/cert
$ mv localhost+2* priv/cert

Update the file config/dev.exs to use your localhost development key and cert. Add your https configuration in your endpoint config:

  https: [
    port: 4001,
    cipher_suite: :strong,
    keyfile: "priv/cert/localhost+2-key.pem",
    certfile: "priv/cert/localhost+2.pem"
  ],

Now, when you start your development server with mix phx.server, it will support a new trusted https service on port 4001.

Photo by Christopher Gower, Unsplash.


Let us know what you think 💬


One thought on “Using a local development trusted CA on MacOS

  1. I LOVE YOU! Saved me after spending so many hours!

    I actually needed to add my local private IP

    mkcert localhost 127.0.0.1 ::1 192.168.x.xxx

    Thank you!

Leave a Comment


This site uses Akismet to reduce spam. Learn how your comment data is processed.