hotel icon indicating copy to clipboard operation
hotel copied to clipboard

feat: allow self-signed certificate

Open floydwch opened this issue 8 years ago • 21 comments

floydwch avatar Mar 22 '16 10:03 floydwch

Hi @typicode,

How about this PR?

floydwch avatar Jun 23 '16 21:06 floydwch

Hi @floydwch

Sorry for the delay. Actually, I don't understand how it's better than the self-signed certificate that is shipped with hotel?

typicode avatar Jun 27 '16 16:06 typicode

@typicode That's fine. Hotel's built-in self-signed certificate would suffer from man-in-the-middle attack since the private key is stored in the repo. Anyone can take the key and cert to launch a MITM attack, right? So, enable user to use their self-signed certificate can get rid off such issue.

floydwch avatar Jun 27 '16 23:06 floydwch

I see, didn't thought about that, thanks. But for servers, all the traffic goes through hotel and the certificate is local so except if I'm missing something I don't think it's possible to do a MITM attack.

For example:

project$ hotel add 'cmd'
$ curl project.dev

It will only go through 127.0.0.1, there won't be a request on the network to another computer and the certificate doesn't come from another server.

typicode avatar Jun 28 '16 09:06 typicode

Suppose the user import the certificate to the trust list, MITM attack becomes possible. Because the certificate is a root certificate, it can be used to generate faked but trusted SSL certificate. Therefore, the MITM is possible.

floydwch avatar Jun 28 '16 09:06 floydwch

+1

tonytonyjan avatar Jul 04 '16 09:07 tonytonyjan

@floydwch thank you for the explanation, will merge. I'm curious though if the browser wouldn't still complain, even if the certificate is trusted, because it's a self-signed one.

typicode avatar Jul 04 '16 12:07 typicode

@typicode https://www.accuweaver.com/2014/09/19/make-chrome-accept-a-self-signed-certificate-on-osx/ FYI.

floydwch avatar Jul 05 '16 02:07 floydwch

Took some time to do more testing and followed the instructions in the link. But Chrome still won't trust the certificate:

Tried on:

  • Safari: doesn't open https://hotel.dev at all
  • Firefox: complains that the certificate is self-signed
  • curl: doesn't open https://hotel.dev at all (Operation timed out)

typicode avatar Jul 06 '16 16:07 typicode

+1

guo-yu avatar Jul 13 '16 07:07 guo-yu

The fix I believe is to create a root CA and add it to your keychain, hotel could then generate certificates from the root CA and use a different certificate per server.

When the user specifies its own personal generated root CA, hotel can work with SSL

  • https://help.github.com/enterprise/11.10.340/admin/articles/using-self-signed-ssl-certificates/

JanStevens avatar Aug 03 '16 06:08 JanStevens

Hi @typicode I think this is a very good starting point for emulating secure SSL environment, I did notice sometimes my JavaScript part suffers from degrading privileges (e.g. unable to use the getUserMedia API) if deemed as not secure by the browser. (when there's a red cross in the address bar) And it seems like Chrome is pushing SSL further at this moment, and I have to go along with it to not have trouble in the future.

So I ended up implementing this small utility ( https://github.com/layerssss/devhttps ), to dynamically sign SSL cert for each new domain, using it along pow.cx. I'm happy to implement this logic as a patch in hotel. Do you want me to go further on this making a PR?

layerssss avatar Aug 28 '16 03:08 layerssss

@layerssss thank you for the help and sharing your project :+1: . It looks great but seems to rely on openssl which would limit its usage to OS X/Linux and hotel needs to work on Windows too.

As an alternative to generating certificates locally using openssl, I think https://letsencrypt.org/ could do the trick. Need to do some tests.

BTW, I would be interested in reproducing your getUserMedia error or any error that happens when the lock is red. What should I do? I'm asking this because until now, for me the only issue with the red lock was that you needed to add an exception to your browser.

typicode avatar Aug 30 '16 10:08 typicode

There are binaries for windows and you can install openssl on windows. https://slproweb.com/products/Win32OpenSSL.html

You cannot use letsencrypt for local dev domains since they use a bot which has to verify that you are the owner of the domain. The bot will never be able to reach your local dev domain.

The suggested extension by @layerssss looks promising, maybe we can start with a HowTo-Wiki get them both working together? Then we can look at integrating them or provide it as an optional plugin / extension

JanStevens avatar Aug 30 '16 11:08 JanStevens

I've not played much with let's encrypt so maybe it's not possible. But also found this project (https://github.com/Daplie/letsencrypt-express) that seems to do it, so I think I'll first experiment with it.

Also, even if it's possible to install OpenSSL on Windows, it's really something I want to avoid as it would introduce an extra step for Windows user.

typicode avatar Aug 30 '16 21:08 typicode

@typicode This one ( https://github.com/Daplie/letsencrypt-express ) is pretty neat!

And I quickly looked into its dependency tree, and the underlying library https://github.com/Daplie/node-letsencrypt , they are pretty neat and pure js. At the bottom it's using pkijs and/or rsa-compat to handle the certification stuff. They are both pure-js so, worry-free on Windows.

But for "let's encrypt" itself, I think it wouldn't suit this situation, because we can not "claim" any .dev domain from the public "let's encrypt" server.

So I think a possible approach could be using pkijs to generate and sign certificates on the fly (still using a dynamic self-signed CA certificate, so this CA is supposed to be manually marked as trusted)

Thanks for being interested in the getUserMedia issue, I can't reproduce it any more, as soon as I click the "continue" in the browser it will be working. So it's not a critical (blocking) issue. But it would be much fancier to see the lock being green and in good shape . 🔒

layerssss avatar Aug 31 '16 01:08 layerssss

@typicode Looks like these changes haven't been merged yet. IMHO this PR looks exactly like what you want.

I had some issues to globally install @floydwch fork, but I could verify that it's only an issue of using the right common name.

Backup your certs, just in case.

‣ cd /Users/blindgaenger/.nvm/versions/node/v4.4.3/lib/node_modules/hotel/lib/daemon/certs
‣ mv server.crt server.crt.bak
‣ mv server.key server.key.bak

Create an own certificate with Common Name as fully qualified domain name of the app.

‣ openssl req -new -newkey rsa:2048 -sha256 -days 365 -nodes -x509 -keyout server.key -out server.crt
Generating a 2048 bit RSA private key
...+++
..........................................................+++
writing new private key to 'server.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:foo-app.dev
Email Address []:

Note that the only non default value is foo-app.dev as the FQDN of my name.

Open Keychain and add server.crt with Always Trust in Keychain. Now check in Chrome.

‣ hotel stop
‣ hotel start
‣ open -a "Google Chrome" https://foo-app.dev

Of course this is not permanent solution and works for that single app only. But that's what the PR is about, right? 😄

BTW letsencrypt is awesome and you should integrate it as default. But the use-case for an own certificate will still exist.

blindgaenger avatar Sep 11 '16 05:09 blindgaenger

I've rebased this on top of current master and am now using this in my own dev env! I can open a new PR if agreed upon, but I don't want to hijack the current conversation to a new PR yet.

Sounds like @layerssss has some good ideas to further improve SSL configuration, but this is nice quick change.

freewil avatar Feb 08 '17 23:02 freewil

@freewil @typicode Is this something we can again try to rebase/push? Would be a great change :)

bpicolo avatar Mar 17 '17 19:03 bpicolo

I've been looking into this a bit and also looked on how this has been solved elsewhere. I personally don't see how letsencrypt can help here, I believe self-signed cert are the only way to go ¯_(ツ)_/¯.

I don't think this PR is enough, what catched my interest in hotel is the promise of a great and worry-free DX, this PR doesn't doesn't deliver on that. That said using this shipped root certificate is a no no!

The best approach I've witnessed were in tools like tunnelss, powprox or puma-dev.

They all do pretty much the same, in short:

  1. Locally generates a unique CA certification on the first run.
  2. Install that CA cert in the keychain e.g 1, e.g 2
  3. That CA cert is then used to dynamically create certificate(s) for the apps (, on the fly, in memory).

See puma-dev readme & tunnelss readme

puma-dev also has been able to remove its dependency on openssl https://github.com/puma/puma-dev/commit/5eba1d621a2958eb101484faad7c57e5d11532e6 Maybe as per @layerssss suggestion, pkijs and rsa-compat could be used to achieve that.

nrako avatar Mar 19 '17 18:03 nrako

@typicode Updates?

m1guelpf avatar Jun 14 '18 18:06 m1guelpf