Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Let's Encrypt SSL Certificates #133

Closed
hn0pw opened this issue Dec 20, 2016 · 21 comments
Closed

Let's Encrypt SSL Certificates #133

hn0pw opened this issue Dec 20, 2016 · 21 comments

Comments

@hn0pw
Copy link

hn0pw commented Dec 20, 2016

Maybe it's possible to integrate the following to get automatically ssl certificates from Let's Encrypt.

Resources:
https://godoc.org/golang.org/x/crypto
https://godoc.org/golang.org/x/crypto/acme/autocert

Sample Integration Diff (Not tested):

diff --git a/libcentrifugo/server/httpserver/handlers.go b/libcentrifugo/server/httpserver/handlers.go
index 9105bb2..3753370 100644
--- a/libcentrifugo/server/httpserver/handlers.go
+++ b/libcentrifugo/server/httpserver/handlers.go
@@ -21,6 +21,8 @@ import (
        "github.com/gorilla/websocket"
        "github.com/igm/sockjs-go/sockjs"
        "github.com/rakyll/statik/fs"
+
+       "golang.org/x/crypto/acme/autocert"
 )
 
 // HandlerFlag is a bit mask of handlers that must be enabled in mux.
@@ -82,7 +84,19 @@ var DefaultMuxOptions = MuxOptions{
 func listenHTTP(mux http.Handler, addr string, useSSL bool, sslCert, sslKey string, wg *sync.WaitGroup) {
        defer wg.Done()
        if useSSL {
-               if err := http.ListenAndServeTLS(addr, sslCert, sslKey, mux); err != nil {
+               certManager := autocert.Manager{
+                       Prompt:     autocert.AcceptTOS,
+                       HostPolicy: autocert.HostWhitelist("ws.sample.com"), //your domain here
+                       Cache:      autocert.DirCache("certs"),              //folder for storing certificates
+               }
+               server := &http.Server{
+                       Addr: addr,
+                       Handler: mux,
+                       TLSConfig: &tls.Config{
+                               GetCertificate: certManager.GetCertificate,
+                       },
+               }
+               if err := server.ListenAndServeTLS("", ""); err != nil { //key and cert are comming from Let's Encrypt
                        logger.FATAL.Fatalln("ListenAndServe:", err)
                }
        } else {

I'm using this already in a other go server and it's working.

@FZambia
Copy link
Member

FZambia commented Dec 20, 2016

Hello! Yeah, why not, I'll look at this soon. Thanks for suggestion

@hn0pw
Copy link
Author

hn0pw commented Dec 21, 2016

Hi, awesome! Thank you!
If you need a tester, i can do that...

@FZambia
Copy link
Member

FZambia commented Dec 22, 2016

@ramon-ga just added code into autocert branch, you'll need to add into config file:

{
  ...  
  "ssl_autocert": true,
  "ssl_autocert_host_whitelist": "www.example.com",
  "ssl_autocert_cache_dir": "/tmp/certs",
  "ssl_autocert_email": "user@example.com"
}

Email is optional, ssl_autocert_host_whitelist and ssl_autocert_cache_dir optional too but recommended (for security and performance as said here). ssl_autocert_host_whitelist can be comma-separated list of hosts.

Could you test it with real domain?

@hn0pw
Copy link
Author

hn0pw commented Dec 23, 2016

Hi, wow you're very fast! I had some time set it up on a test server and can confirm it's working!
The first call on the server is a little bit slow, but after that it works like a charm!

Thank you very much for your work!


Some Details about the test:

Server: Ubuntu 16.04 / go version go1.6.2 linux/amd64
Javascript Client: sockjs-client v1.0.3 / centrifuge.min.js v?
PHP API Client: phpcent 1.0.4 / php 5.5.9-1ubuntu4.20
(with php 5.6.2 on mac osx not working: tls: no cipher suite supported by both client and server)

Build centrifugo:

apt-get install golang
git clone https://github.com/centrifugal/centrifugo.git
cd centrifugo/
git checkout autocert
export GOPATH=$HOME/go
go get ./...
go build
mkdir /root/certs-test

Config updated with:

{
  ...  
  "ssl_autocert": true,
  "ssl_autocert_host_whitelist": "ws-autocert-test.xxxx.xx,ws2-autocert-test.xxxx.xx",
  "ssl_autocert_cache_dir": "/root/certs-test"
}
  1. Test Run
    ===================
root@centrifugo-test-letsencrypt-cert:~/centrifugo# ./centrifugo -p 443 --ssl
[I]: 2016/12/23 10:37:30 Config path: /root/centrifugo/config.json
[I]: 2016/12/23 10:37:30 Centrifugo version: 
[I]: 2016/12/23 10:37:30 Process PID: 9640
[I]: 2016/12/23 10:37:30 Engine: In memory – single node only
[I]: 2016/12/23 10:37:30 GOMAXPROCS: 2
[I]: 2016/12/23 10:37:30 Starting http server
[I]: 2016/12/23 10:37:30 SockJS url: //cdn.jsdelivr.net/sockjs/1.1/sockjs.min.js
[I]: 2016/12/23 10:37:30 Start serving raw websocket, SockJS, API, admin endpoints on :443
[F]: 2016/12/23 10:37:30 ListenAndServe: open : no such file or directory
  1. Test Run after update code
    ===================
# update package downloaded from github
cp libcentrifugo/server/httpserver/config.go $GOPATH/src/github.com/centrifugal/centrifugo/libcentrifugo/server/httpserver/config.go
cp libcentrifugo/server/httpserver/handlers.go $GOPATH/src/github.com/centrifugal/centrifugo/libcentrifugo/server/httpserver/handlers.go
go build -a
root@centrifugo-test-letsencrypt-cert:~/centrifugo# ./centrifugo -p 443 -d
[I]: 2016/12/23 11:17:28 Config path: /root/centrifugo/config.json
[I]: 2016/12/23 11:17:28 Centrifugo version: 
[I]: 2016/12/23 11:17:28 Process PID: 14591
[I]: 2016/12/23 11:17:28 Engine: In memory – single node only
[I]: 2016/12/23 11:17:28 GOMAXPROCS: 2
[W]: 2016/12/23 11:17:28 Running in DEBUG mode
[I]: 2016/12/23 11:17:28 Starting http server
[I]: 2016/12/23 11:17:28 SockJS url: //cdn.jsdelivr.net/sockjs/1.1/sockjs.min.js
[I]: 2016/12/23 11:17:28 Start serving raw websocket, SockJS, API, admin, debug endpoints on :443

@FZambia
Copy link
Member

FZambia commented Dec 23, 2016

Great, thanks for testing!

Then it will be part of v1.6.1 - I think I'll release it very soon as there are several small fixes already in master.

@hn0pw
Copy link
Author

hn0pw commented Dec 23, 2016

Great! As soon as the release is done, i'm setup it up on the production server.
Thanks again 👍

@FZambia
Copy link
Member

FZambia commented Dec 25, 2016

v1.6.1 released

@FZambia FZambia closed this as completed Dec 25, 2016
@manson
Copy link

manson commented Jan 2, 2017

Will Let's Encrypt automatic certificates renew when they are about to expire?

@FZambia
Copy link
Member

FZambia commented Jan 3, 2017

@manson yes, they should (1 week before expiration)

@banks
Copy link
Member

banks commented Jan 3, 2017 via email

@FZambia
Copy link
Member

FZambia commented Jan 3, 2017

@banks here it is, looking in their limit docs it seems that renew requests does not count rate limit and they have 1 week sliding window for limits. So we have to be very unlucky to hit the limit. Let's make it 2 weeks to remove that probability?

@manson
Copy link

manson commented Jan 3, 2017

Should it be jscent serverside library updated to work with https? Currently I've managed to run centrifugo with lets encrypt certificates, admin UI works fine (except it complains on unsecured fonts downloading) but my serverside code cannot connect to centrifugo with exception:
{ [RequestError: Request failed with an error] name: 'RequestError', message: 'Request failed with an error', url: 'https://mysite:8000/api/', error: [Error: UNABLE_TO_VERIFY_LEAF_SIGNATURE], statusCode: null, body: null }

What have I missed?

@FZambia
Copy link
Member

FZambia commented Jan 3, 2017

@manson it already works with valid HTTPS certificates (you can make sure trying to send request to our demo instance: https://centrifugo.herokuapp.com/). Please, look at this SO answer. Also I see 8000 port in your request url - is it ok?

We also can add strictSSL option (see this issue) but maybe there is a secure way to fix this?

@FZambia
Copy link
Member

FZambia commented Jan 3, 2017

except it complains on unsecured fonts downloading

could you tell which fonts?

@manson
Copy link

manson commented Jan 3, 2017

@FZambia Thats great you have no problem connecting jscent node library to your server, but I cannot check it out because of my node library unable to connect to your site without secret key. I want to remind that from browser and my browser application part I manage to connect to my centrifugo instance in ssl mode. Just node unable to connect.

I've checked links you supplied. Both are related to switching off security so I dont get it what in this case is ssl, sertificates and so on for? Or I dont get something?

Also I see 8000 port in your request url - is it ok? - what is wrong with this? I've started centrifugo standalone instance with lets encrypt certificates. It started at the same default ports. Is something wrong with it? Althow I started it on production server (just because of certificates bound to servers domain), currently I use it just to test it how I can use it. And cannot get it work in this mode. Without ssl it works fine - I even rewrote subscriptions engine for Meteor.js using centrifugo to reduse memory consumption and rise concurrent connections (meteor subscriptions are too memory greedy)

as for fonts. This what I see in browser console when opening centrifugo admin UI:
`Mixed Content: The page at 'https://mysite:8000/#/' was loaded over HTTPS, but requested an insecure font 'http://themes.googleusercontent.com/static/fonts/rosarivo/v1/OGdIq-p0tOtBN2VMVvO9W_esZW2xOQ-xsNqO47m55DA.woff'. This request has been blocked; the content must be served over HTTPS.

bundle.js:2121Mixed Content: The page at 'https://mysite:8000/#/' was loaded over HTTPS, but requested an insecure font 'http://themes.googleusercontent.com/static/fonts/inconsolata/v5/BjAYBlHtW3CJxDcjzrnZCIbN6UDyHWBl620a-IRfuBk.woff'. This request has been blocked; the content must be served over HTTPS.`

@FZambia
Copy link
Member

FZambia commented Jan 3, 2017

@manson this is our public demo: it's secret key is secret :)

More specifically about SO answer: could you try to inject CA certificates using ssl-root-cas module as suggested in one of answers?

About port: I have never done it myself, but see this - so maybe you have to run Centrifugo on standard 443 port and the problem will go away?

So please try options above.

I think it's worth adding strictSSL option anyway for self-signed certificate cases in development for example.

Thanks for font warning: this is a bit strange - we have not use any of those fonts explicitly - i.e. I grepped over files and have not found them.. Also I have no such warning on our https instances. Maybe they are coming from one of browser extensions (in Chrome you can try to load a page in incognito mode as most extensions disabled in that mode)?

@manson
Copy link

manson commented Jan 3, 2017

@FZambia Ok. I managed to connect to your instance with secret key. At least now I had no exceptions on my serverside code. Although my browser client right after connection gets disconnected, I assume it ok at least for this issue. Will try with ports playing but if this is the case its not very well bc I plan to use the webserver ssl processing. I.e. 433 port will be my webserver port, so they may conflict... I'm getting into a mess with all this. Separatelly I understand how it should work but not in common, under the one server roof.
So please try this, I think it's worth adding strictSSL option anyway for self-signed certificate cases in development for example. - I've gotten letsencrypt certificates and want to make them to work but will check it anyway, thanks

Thanks for font warning: this is a bit strange - hmmm... maybe this is some kind of chrome plugin plays a dirty game :-) Cannot check right now. Anyway thank you!

@FZambia
Copy link
Member

FZambia commented Jan 3, 2017

@manson ok, keep me posted, please.

Meanwhile I released jscent library 0.1.2 with support for strictSSL: false - but hope you will get it work without disabling SSL check entirely..

@manson
Copy link

manson commented Jan 3, 2017

@FZambia Excuse me, I have another question but dont know where to ask it. Its not an issue just a question. Why dont you want to do a serverside subscription? I mean in jscent library? I have a usecases where clients may directly communicate each other but server intercepts messages (bc its subscribed to channel) and sometimes it may log info or make some actions according to data in channel. Usefull for some kind of pseudo-distributed applications. At least the lack of this is a bit uncomfortable....

For updated jscent- thanks a lot! Will try

@FZambia
Copy link
Member

FZambia commented Jan 3, 2017

@manson it's theoretically possible and maybe it's possible to adapt our browser client to work server-side too - but I just have no resources to develop and support clients for all backend languages. There is already a way to do some callback action just calling it from client (browser) side via AJAX call for example.

Btw you can ask questions in our chat on Gitter - https://gitter.im/centrifugal/centrifugo

@manson
Copy link

manson commented Jan 3, 2017

@FZambia I see. Thank you! Centrifugo is a great tool! :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants