Server Name Indication: SSL for multiple hosts #364

Closed
mworrell opened this Issue Jun 18, 2012 · 52 comments

Projects

None yet

7 participants

@mworrell
Member

Is it possible to use the Server Name Indication with the Erlang SSL libraries?

http://en.wikipedia.org/wiki/Server_Name_Indication

This could enable SSL for any host (and most user agents).

@mworrell
Member
@mworrell
Member

A branch of otp with sni enhancements is maintained here: https://github.com/klyr/otp/commits/sni_clean?

@mworrell
Member

Mailed Julien Barbot again about the integration of his patch in Erlang/OTP.

@mmzeeman
Member

+1 this is a MUST HAVE patch for Erlang IMHO.

@arjan
Member
arjan commented Sep 25, 2013

Seems it is scheduled for R17?
https://github.com/klyr/otp/commits/r17_ssl_sni

@mworrell
Member

Great news in R16B03:

OTP-11460  Add SSL Server Name Indication (SNI) client support. Thanks
      to Julien Barbot.
@mworrell
Member

Though it seems to be client support only for now, have to investigate if server support is also hiding in there.

@ddossot
ddossot commented Jun 23, 2014

Any progress on this? It doesn't seem server-side SNI-support has made its way in R17, but I may be wrong.

@mworrell
Member

Regrettably you are not wrong.

I contacted @klyr Julien Barbot last december and back then he told me he was still working on getting the server side of SNI into OTP.

@ddossot
ddossot commented Jun 24, 2014

Thanks @mworrell, I wish I could have been wrong 😢

@klyr
klyr commented Jun 26, 2014

Hi,
I began working on this patch a long time ago, but I cannot find the time to finish it. Integrating SNI extension in the current code is not so trivial, and things are changing/ being refactored quite often.

Please feel free to comment the current (not working) state of the patch on the following branch https://github.com/klyr/otp/tree/r17_ssl_sni_server.
Maybe it will motivate me to finish this many-years-pending-patch :)

@mworrell
Member

@klyr thanks for chiming in! I will have a look and encourage the team to have a look as well.

I think server-side SNI is very important for the use of Erlang in web applications.

@jhg
jhg commented Aug 7, 2014

@klyr I think like @mworrell and server-side SNI is very important, not only for web applications, also for servers that need security with TLS and support more of one domain, for cloud applications, etc. I would like write websockets secure for multiple domain for notification with comunication with web framework using tails (rabbitmq) but it's impossible in this moment without SNI.

@mworrell
Member
mworrell commented Aug 8, 2014

@jhg Indeed, that is why we have to take a collective look at @klyr's work and see if we can get it working on the GitHub source version of Erlang/OTP. If so, then we can request a merge of this important feature.

@mworrell mworrell added this to the Wish list milestone Apr 22, 2015
@mworrell
Member

SNI has been added to Erlang 18

http://www.erlang.org/doc/man/ssl.html
erlang/otp#656

We might want to consider to move the 1.0 to 18 for added SNI support.
We also need to check if Elli can use this.

@mworrell mworrell modified the milestone: Release 1.0, Wish list Aug 18, 2015
@mmzeeman
Member

Checked out SNI on R18, and indeed it has server side SNI. 🍰

There are two ways to configure it. The nice thing is that the SSL implementation can now be pushed to zotonic core because the certificates of the different sites will be requested dynamically.

For R16 and R17 the old mod_ssl implementation should stay in place.

@mmzeeman
Member

Maybe we should wait for 18.1 before implementing this.

@mworrell
Member
mworrell commented Dec 3, 2015

Assuming SNI indeed made it onto 18.x, I think it is nice to try to combine the SSL/SNI changes with Elli/Cowboy replacement of Mochiweb and this https://letsencrypt.org/2015/11/12/public-beta-timing.html

@ddeboer
Member
ddeboer commented Jan 22, 2016

Good idea! We then get out-of-the-box TLS support for all Zotonic sites, without the need to get your own certificates. And if it works well, we could even disable HTTP by default and enforce TLS on all sites. That results in better privacy and higher-ranking sites in Google. The performance penalty for TLS is becoming smaller and smaller anyway.

@mmzeeman
Member

There is currently a performance penalty, but this will go away once erlang uses openssl's engine api. This api allows the use of hardware accelerated crypto primitives available on almost all cpu's. I've measured this with a proof of concept nif which i sent to the otp team. The effect is quite dramatic, about a 10x speedup of low level crypto operations. There where some discussions about the api and backward compatibility, so it is not yet available. Once it is there the ssl performance will be comparable to other web-server-proxy-things.

@mworrell
Member

Actually, I think that the performance will be higher, as there is no extra data being shuttled between the proxy and the server.

In the real world (tm) (c) we see that even the current inefficient SSL implementation is sufficiently fast for most sites.

@mworrell
Member

Proposal:

  • Use cowboy and SNI
  • Generate self signed certificates for all sites without a certificate
  • Enable SSL for all sites per default (optional, but required for admin etc)
  • Place the certificates in some other place than the current per-site ssl directory (maybe in ~/.zotonic/certs/?) Give the self signed ones a different name, so that we don't overwrite other certs

We might also use an automatic DNS check to see if the configured DNS entry resolves using an external DNS server (for example Google's 8.8.8.8) - if so then we can automatically start using letsencrypt for the certificate.

BTW can Erlang ssl use in-memory certificates? If so then we could also store certificates in the database ... (could be encrypted)

@mmzeeman
Member

The documentation say's it can handle DER encoded certificates and keys. This is the binary version of the PEM encoded files. Basically the decoded base64 parts. So yes, it is possible to store certs and keys in the database.

@mmzeeman
Member

SNI has moved into the core for our master branch. I would like to add SNI support to the 0.x branch and change the milestone to 0.17.

This may require a bit of configuration during upgrading though. When mod_ssl was in use on multiple sites you will have to change your servers port settings and enable mod_ssl_self_signed. Both are not very hard, but a point of attention when upgrading.mod_ssl_self_signed uses the same certificate and key locations as mod_ssl previously did so that is not a big issue. Configuring usage and changing port is only needed when you previously had multiple ssl sites.

What do you think? Move to milestone 0.17 or not?

@ddeboer
Member
ddeboer commented May 24, 2016 edited

What do you think? Move to milestone 0.17 or not?

How much work would be involved cherry picking #1274 into 0.x? If it’s something that we can get done before next Monday (when we enter stabilisation for 0.17.0) I’m fine with moving it to the 0.17 milestone.

@mmzeeman
Member

Technically not much. Just one small easy to fix source conflict, and one documentation conflict. I can do it tomorrow.

I need to add something to the release notes to make upgrading easier.

@ddeboer
Member
ddeboer commented May 25, 2016

@mmzeeman Please do!

I changed the milestone to 0.17.

@ddeboer ddeboer modified the milestone: 0.17, 1.0 May 25, 2016
@mworrell
Member

So we move to Erlang 18+ only?

@ddeboer
Member
ddeboer commented May 25, 2016

Oh wait, the SNI requires Erlang 18+? In that case, no: let’s not do that in the 0.x branch.

@mworrell
Member

Or place a conditional and a clear error if 17 or older (and then disable SSL)

@ddeboer
Member
ddeboer commented May 25, 2016 edited

But that means current 0.x users that are on Erlang < 18 will lose SSL functionality, doesn’t it?

@mmzeeman
Member
mmzeeman commented May 25, 2016 edited

Well, for SSL support you need 18.1+ anyway.

Chrome 50 crashes stock R16 when setting op a network connection and 17 has a memory leak in its ssl code which was fixed in 18.1.

@mworrell
Member

@mmzeeman does the new code still use mod_ssl? Maybe mod_ssl can refuse starting with a fatal error if Erlang < 18.1

@mmzeeman
Member
mmzeeman commented May 25, 2016 edited

No, the ssl listeners are moved to zotonic_sup so are now supervised. Mod_ssl's role is doing ssl dispatch rule management and redirection.

@mworrell
Member
mworrell commented May 25, 2016 edited

We could wrap the SSL listeners in a check for < 18.1 and add a similar check with fatal error to mod_ssl. This would allow people to keep running on older Erlang versions iff they are behind ssl proxies.

This only for 0.x - master will be 18.1+ only.

@mmzeeman
Member

I could add a no_ssl flag and don't start the ssl listeners. That way you can still use 0.x on 16 and 17, but without ssl support. In some cases ssl to the external internet is managed by ha_proxy or ngnix anyway. The downside is that this can leave the site vulnerable on the internal network.

@mworrell
Member

That is ok - mostly we are running ha_proxy (and friends) on the same machine.

@arjan
Member
arjan commented May 25, 2016

You could do this with a -ifdef() and then use rebar's platform_define to disable SSL on < 18.

@mmzeeman
Member

So, not very hard to do. Do we want a no_ssl option for master too?

@ddeboer
Member
ddeboer commented May 25, 2016

@mmzeeman Is there any significant cost to starting the SSL listeners? Master runs on Erlang 18+, so pre 18 compatibility is no issue there.

@mworrell
Member

I think it is good to have SSL on by default -- so I prefer only for 0.x
(And when we have letsencrypt integrated then we can always run on SSL)

@mmzeeman
Member

@ddeboer No, it just starts two (IPv4 and IPv6) listeners to accept traffic. The part that takes long like key generation is handled in support modules. If these modules are not running setting up the connection will fail and the connection will be dropped.

@ddeboer
Member
ddeboer commented May 25, 2016 edited

In that case, let’s add no_ssl on 0.x only, where we need it for Erlang < 18 support.

@mmzeeman
Member

Ok 👍

@mmzeeman
Member

@arjan There seems to be a duplicate way to set compile options. One via rebar.config, and one via zotonic_compile.erl. Which one is the preferred way? For z:m() to work you need it on zotonic_compile but the sources directly in src are compiled by rebar and not via zotonic_compile.

@arjan
Member
arjan commented May 25, 2016

Yes but on 0.x src/ is still compiled by zotonic_compile.
Quite hairy situation if you ask me. Maybe zotonic_compile should parse rebar.config.

@mmzeeman
Member

I can easily pick up the platform_defines in zotonic_config via -ifdefs and add a comment to rebar.config that the define should be added to zotonic_compile too. We just have three options.

@arjan
Member
arjan commented May 26, 2016

Yes you mean those platform_defines_r16up() functions? I guess you'd have to add a platform_defines_r18up one..

@mmzeeman
Member

Yeah those. I added one, but that option was, of course, not defined during compilation of zotonic_sup.erl which is compiled by rebar with the platform define options. Later on zotonic_compile is used but it doesn't recompile zotonic_sup. It does this only when the source is changed.

Op 26 mei 2016 om 09:32 heeft Arjan Scherpenisse notifications@github.com het volgende geschreven:

Yes you mean those platform_defines_r16up() functions? I guess you'd have to add a platform_defines_r18up one..


You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub

@ddeboer
Member
ddeboer commented Jun 6, 2016 edited

Can we consider this issue as done?

@mmzeeman
Member
mmzeeman commented Jun 6, 2016

Yes, it is integrated into master and the stable branch.

@mmzeeman mmzeeman closed this Jun 6, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment