Phoenix: Provide task to generate local ssl certificate

Created on 23 May 2018  路  14Comments  路  Source: phoenixframework/phoenix

There's a lot going on right now that is going to mean we need either a script or instructions to get SSL setup locally with SAN support.

First, HTTP/2 (H2) requires TLS. Even in development mode.

Google Chrome will throw an H2 protocol error if you use a known bad cipher.

Firefox 48 and Chrome 58 both require SAN to trust a cert. (Unless it's a wildcard.) See https://www.chromestatus.com/feature/4981025180483584

This is actually extra important because without SAN server push (PUSH_PROMISE) will not work in Chrome.

So I don't think there's much of a choice. I think we need to instruct people to generate certs that include SAN for development.

Unfortunately, for openssl to use SAN you need to use a config file as there is no command line option to give it subject alt names.

If we generate an ssl config file like such (lets say this is app-name.cnf):

[req]
default_bits = 4096
prompt = no
default_md = sha256
x509_extensions = v3_req
distinguished_name = dn

[dn]
C = EX
ST = Elixir
L = Phoenix
O = App
emailAddress = [email protected]
CN = app-name.phx.sh

[v3_req]
subjectAltName = @alt_names

[alt_names]
DNS.1 = app-name.phx.sh
DNS.2 = *.phx.sh

Then we can run the following to generate a cert/key pair with OpenSSL:

openssl req -new -x509 -newkey rsa:2048 -sha256 -nodes -keyout app-name.key -days 3560 -out app-name.crt -config app-name.cnf

enhancement

Most helpful comment

The downside of a private CA, added to the OS/browser trust store, is the implications of the private key leaking. A malicious user could use it to launch MitM attacks against any Internet site that does not have some sort of certificate pinning in place. Not everyone testing the occasional HTTPS application on localhost has the skills to properly secure that private key, or to understand the implications of misplacing it.

There is no one answer here, and everyone is free to use the tools that work for them. The purpose of the Mix task in Phoenix 1.4 is to support at least one way of testing HTTPS out-of-the-box, with no external dependencies or (OS-specific) CLI commands.

All 14 comments

I saw @sasa1977 announced a library to work with Let's encrypt from Elixir. Maybe we should consider pushing developers towards that instead of generating certificates? It seems like a less error prone path to me.

@voltone has written a Mix task that we plan to add to Plug (and/or Phoenix) that generates certificates: https://gist.github.com/voltone/4d209059c5947d8b73413e05d0e665de

The issue is that it requires OTP 20 but we can say that H2 is an Erlang/OTP 20+ exclusive feature, especially because choosing Cowboy 2 is still opt-in.

So the best way to go go here is probably to make sure our generated certificates include this recommendation too.

PS: Weare aware the gist above has issues with HSTS. However it is worth noting that we warn if you use force_ssl in localhost and we do plan to disable HSTS altogether for localhost in another Plug issue.

That gist appears to include support for SAN (subjectAltName).

I don't think we need any changes. We probably just need documentation to include a reminder about SAN and H2.

Yes, I think that generating self-signed certificates with :public_key is a simple and a great solution for this.

The aim of my library is to support the development of projects which in fact do want to certify via letsencrypt, and so it's more specialized, and the usage is more complex.

@idyll i will reopen this because I actually forgot we had that gist around. :P This will make sure we will include it either on phoenix or plug.

The OTP 20 constraint is because generating an RSA key pair using OpenSSL NIFs would block the scheduler, so it requires dirty schedulers. Older OTP versions should be able to generate EC key pairs.

I could update the script to generate an ECDSA cert instead in support of older OTP versions. Depending on the selected curve that should work with all browsers and other modern clients. Old Java versions might be a problem, but not sure that's a blocker. We can always add a CLI argument to switch to RSA for those who need it (and who are on OTP 20).

@voltone it is fine to require OTP 20. Erlang/OTP 21 will be out this in two weeks maximum and Elixir v1.8 that comes in Jan/2019 will require Erlang/OTP 20+ anyway.

@voltone Are you happy to open a PR with this feature so we can review it and merge it in?

Yeah, I can try. The reason I originally wrote a gist rather than a PR is because I was comfortable with the Mix task itself, but I didn't have time to look at adding tests for it. I'll give it a shot later.

@voltone If you do have time to do so, that's awesome. If not, open a PR with the mix task and we take care of writing the tests.

I created PR #2941, please have a look and let me know...

I use https for local development and would recommend using mkcert to create a Certificate Authority which will then generate self signed certificates. Browsers (Firefox) are a pain in the butt to get working correctly and are only becoming more stringent with their requirements. By generating your own trusted CA, you can get around a lot of the issues that you will run into with self signed certificates completely.

The downside of a private CA, added to the OS/browser trust store, is the implications of the private key leaking. A malicious user could use it to launch MitM attacks against any Internet site that does not have some sort of certificate pinning in place. Not everyone testing the occasional HTTPS application on localhost has the skills to properly secure that private key, or to understand the implications of misplacing it.

There is no one answer here, and everyone is free to use the tools that work for them. The purpose of the Mix task in Phoenix 1.4 is to support at least one way of testing HTTPS out-of-the-box, with no external dependencies or (OS-specific) CLI commands.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mitchellhenke picture mitchellhenke  路  3Comments

tjsousa picture tjsousa  路  4Comments

GPrimola picture GPrimola  路  3Comments

chrismccord picture chrismccord  路  4Comments

adamaiken89 picture adamaiken89  路  3Comments