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

SSL support #17

Closed
joewalnes opened this issue Dec 15, 2013 · 38 comments
Closed

SSL support #17

joewalnes opened this issue Dec 15, 2013 · 38 comments
Labels

Comments

@joewalnes
Copy link
Owner

Support https and wss.

@ghost
Copy link

ghost commented Jan 23, 2014

I second this.

I've just discovered websocketd, and I really like this idea. This issue, however, is a deal breaker for the app I was planning to use it on. I hope this will be implemented soon.

@joewalnes
Copy link
Owner Author

WebEnchanter, if you need SSL support right now you can use an SSL enabled reverse proxy in front of websocketd, such as stunnel, HAProxy or Nginx.

@ghost
Copy link

ghost commented Jan 23, 2014

Thanks Joe. Never thought of that. Awesome!

@biafra
Copy link

biafra commented Jan 23, 2014

It's working really well with nginx.

@ghost
Copy link

ghost commented Jan 23, 2014

@biafra what's your set up like? For some reason I can't seem to make it work on nginx.

nginx version: nginx/1.4.3

Here is my location block:

  location /comet {
        proxy_pass              http://localhost:8080/;
        proxy_http_version      1.1;
        proxy_set_header        Upgrade $http_upgrade;
        proxy_set_header        Connection "upgrade";
        proxy_set_header        Host $host;
    }

Then in count.html I'm using:

var ws = new WebSocket('wss://localhost/comet/'); 

Am I missing something?

@ghost
Copy link

ghost commented Jan 23, 2014

Also are you using it in production? Is websocketd production ready?

@biafra
Copy link

biafra commented Jan 23, 2014

Same as you. I've just added "proxy_buffering off;" to that location.

You already have a certificate and configured the ssl entries right ?
Something along this lines:

    ssl on;
    ssl_certificate /etc/nginx/ssl/server.crt;
    ssl_certificate_key /etc/nginx/ssl/server.key;

    ssl_session_timeout 5m;
    ssl_protocols       SSLv3 TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers

AES128-SHA:AES256-SHA:RC4-SHA:DES-CBC3-SHA:RC4-MD5;
ssl_prefer_server_ciphers on;

Ah, with safari IOS secure websockets won't work if are not using a valid
certificate. If you are using one generated by you it won't work.

On Thu, Jan 23, 2014 at 3:09 PM, WebEnchanter notifications@github.comwrote:

@biafra https://github.com/biafra what's your set up like? For some
reason I can't seem to make it work on nginx.

nginx version: nginx/1.4.3

Here is my location block:

location /comet {
proxy_pass http://localhost:8080/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}

Then in count.html I'm using:

var ws = new WebSocket('wss://localhost/comet/');

Am I missing something?


Reply to this email directly or view it on GitHubhttps://github.com//issues/17#issuecomment-33131521
.

@ghost
Copy link

ghost commented Jan 23, 2014

OK. I'm using a self signed certificate on localhost for testing. I guess that's where the problem is. Tried adding proxy_buffering off; to that block too and still can't get it to work.

I tried with Opera and Chrome on Arch Linux.

@biafra
Copy link

biafra commented Jan 23, 2014

Check here for compatible browsers that support wss http://en.wikipedia.org/wiki/WebSocket#Browser_implementation

@ghost
Copy link

ghost commented Jan 23, 2014

Thanks. According to that link, both of the browsers I'm using should support wss. Will try with a commercial certificate.

@ghost
Copy link

ghost commented Jan 23, 2014

It seems like the issue is the proxy itself. I have tried with a valid certificate and it doesn't work either. I also get the same result on a non-secure connection using ws://. In both cases all I'm getting is 'DISCONNECT'.

Without using nginx as a proxy, however, it's working fine.

@biafra
Copy link

biafra commented Jan 24, 2014

I thought you have already tested without SSL. Rereading you comment I think you don't have the usual reverse proxy configuration. I've got this:

    location /websocket {
            proxy_pass      http://127.0.0.1:8080;
            include         /etc/nginx/proxy.conf;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            #proxy_read_timeout 86400;
            proxy_buffering off;
    }

Where proxy.conf has at least these lines (you can add them directly on your location scope):

    proxy_redirect          off;
    proxy_set_header        Host            $host;
    proxy_set_header        X-Real-IP       $remote_addr;
    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;

@joewalnes
Copy link
Owner Author

Hey @biafra - this is really useful. It would be great if you could write this up as short tutorial for the websocketd wiki.

Thanks
-Joe

@ghost
Copy link

ghost commented Jan 24, 2014

@biafra When I initially tried it I didn't test proxing without SSL.

I have updated my location block to include the lines that were missing:

    proxy_redirect        off;
    proxy_set_header        X-Real-IP       $remote_addr;
    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;

and I've upgraded my nginx to 1.4.4 but I still get the same result.

It seems there is something wrong with my environment.

I have tested my setup with http://websocketstest.com. Under "Environment" there is:

HTTP Proxy                        No 

I will try to Google a solution to this and let you know my results.

@ghost
Copy link

ghost commented Jan 24, 2014

You can see the result of my test at http://websocketstest.com/result/288844

@biafra
Copy link

biafra commented Jan 24, 2014

@WebEnchanter That "HTTP Proxy No" is just saying your browser is not using a proxy. I've just tested my gateway with "Opera/9.80 (Windows NT 6.1) Presto/2.12.388 Version/12.12" and it works.

@joewalnes I'll try to write down something but can promise when.

@asergeyev
Copy link
Collaborator

Is there reason why you all don't like opening TLS sockets in golang program?

Reverse proxy way is insecure by definition (UNIX domain sockets are secure to the point that would be sufficient here since golang memory handling is very hard to work with fully securely but websocketd does not support them) and IMO there is benefit to secure things properly, even when there is performance cost.

My proposal would be to add --tls to the options list to create ssl-only service but that leads to need of running two separate go daemons if you need both secure and insecure service.

@asergeyev
Copy link
Collaborator

Ok, not as easy as I said ...
maybe websocketd may use some sort of new flags to set listening IP/port/cert/key combination... Probably worth looking at other tools config options and copycat them.

@joewalnes
Copy link
Owner Author

Alex, this open issue is to do precisely what you say - to add native SSL support to websocketd. The rest of the discussion is about workarounds until this issue is implemented.

The cmd line options I'd like to add are:

--ssl (enable ssl)
--sslcert=... (public cert file)
--sslkey=... (private key file)
--sslca=... (optional, if using a custom CA)

@asergeyev
Copy link
Collaborator

So your choice is for "you either using SSL or no", right?
I will add this sometime this week... Need to check how golang behaves with password protected keys.

CA is not something that people use separately at server side anymore. It caused confusion betweeen two things - CA that server checks on certs that users send and CA that points to authority that signed server's certificate. To avoid confusion the second one is put along with server's cert in single pem file, many cert authorities even send it to you this way. Self-generated ones have to be concatenated (see comment here http://golang.org/pkg/net/http/#ListenAndServeTLS)

As I see things so far, there is no "access control" in websocketd where checking client's SSL cert with CA could be necessary so I'll not think of it :)

@joewalnes
Copy link
Owner Author

So your choice is for "you either using SSL or no", right?

That's a good question. I was thinking of it as a single option, but now websocketd also supports binding to multiple host/ports it may make more sense to do it on a per instance basis. On the other hand, that scenario seems pretty rare. I'm tempted to go for simplicity.

Interesting about the CA. For internal apps, I've always been explicitly defining a CA file used for both client and server certs, but I see that it's not necessary. Ok forget about that option.

Regarding access control, it would be:

  • does the SSL handshake work (i.e. find a common CA in the chain the both server and client agree on)
  • underlying user script can perform additional checking if it needed to something based on client cert

In order for the underlying user scripts to know about the SSL session, this information should be passed as environment variables in a similar manner to a traditional CGI server. See http://httpd.apache.org/docs/2.2/mod/mod_ssl.html

@asergeyev
Copy link
Collaborator

Quickly gets complicated :) I'll do few passes in a branch and we'll talk :)

@asergeyev
Copy link
Collaborator

Well... Strike first commit.. Here is change for review before I'll send pull request:
https://github.com/asergeyev/websocketd/compare/ssl

I'd like to know your initial opinion and thoughts on where it should move.

SSL_* variables would be one thing.
thinking about CA support for user auth is quite another journey.
you might have another ideas.

@joewalnes
Copy link
Owner Author

Looks great so far.

Looks good to be checked in. The custom CA support and SSL* variables can be follow up features.

One really teeny tiny nitpick: in config.go, use "websocketd" instead of "WebsocketD".

@asergeyev
Copy link
Collaborator

There is significant digging required for supporting encrypted private key PEMs. I decided to give up on it for now. I agree with putting this point as somewhat like "SSL support preview". You also can put some thinking into future SSL-related enhancements.

@asergeyev
Copy link
Collaborator

Another additional pursuit is that ciphers should be configurable to avoid high cost of handshakes...

Right now I see my system use ECDHE-RSA-AES256-SHA which could be easiely downgraded to something else. Looks like many frontends now stich with ECDHE-RSA-AES128-GCM-SHA256 and IMO backends could go lower depending on problems TLS is trying to solve.

@asergeyev
Copy link
Collaborator

I wanted to get rid of having another global config element, SSL and replace it to use req.TLS. Please see #48 I created and closed later since we never discussed it. Not sure if it makes things better but it's consistent with cgi module.

@joewalnes joewalnes changed the title SSL support SSL Have a question? Let's talk! support May 23, 2014
@joewalnes joewalnes changed the title SSL Have a question? Let's talk! support SSL May 23, 2014
@joewalnes joewalnes changed the title SSL SSL support May 23, 2014
@piwi82
Copy link

piwi82 commented Jun 19, 2014

Is SSL WebSocket working for someone with websocketd ?
wss://domain.tld returns WebSocket error #1006 "Abnormal closure".

@asergeyev
Copy link
Collaborator

What version do you use? Also what kind of flags in command line to start websocketd.

@piwi82
Copy link

piwi82 commented Jun 19, 2014

I use version 0.2.9.
websocketd is started with the following command :

./websocketd
    --port=19443
    --ssl
    --sslcert="/pathToCrt/server.crt"
    --sslkey="/pathToKey/server.key"
    ./server.php

@asergeyev
Copy link
Collaborator

You then need wss://domain.tld:19443/

Also note that if you trying it in browser with self-signed cert it might not work until you accepted this cert by using https://domain.tld:19443/ and saved security exception (you might also use --devconsole option to play with wss:// address and --loglevel debug to see bunch of stuff about internal things)

Let me know if you did all that before and it still does not work...

@piwi82
Copy link

piwi82 commented Jun 19, 2014

Yes, I use ws://domain.tld:19443 to connect to websocketd.
Accepting the certificate using https did the trick, reverse-proxying websocketd through nginx also works.
Thanks a lot for your help :-)

@asergeyev
Copy link
Collaborator

Awesome. I glad someone uses ssl and can let me know if it misbehaves :)

@piwi82
Copy link

piwi82 commented Jun 23, 2014

SSL works flawlessly.
Why websocketd does not run as a daemon ?
I am trying to daemonize websocketd on a Synology NAS (and I should open another issue).

@asergeyev
Copy link
Collaborator

What linux-family does it run? Is there upstart?

I'd recommend to use ustart or runit or other process monitor instead of daemonizing... There are certain problems and solutions but I'd like to see if it's really a pain (I don't know if godaemon would be cross-platform and cannot really think of using it without that https://vividcortex.com/blog/2013/08/27/godaemon-a-library-to-daemonize-go-apps/ )

@piwi82
Copy link

piwi82 commented Jun 25, 2014

Synology uses a custom version of Linux based on Busybox.
There is no tool to daemonize a process, but I think websocketd should start as a daemon instead of line interactive.
All this has nothing to do with SSL, maybe we should open a new issue ?

@asergeyev
Copy link
Collaborator

yeah. Let's try to explore what we can do there.

On Wed, Jun 25, 2014 at 9:12 AM, Piwi notifications@github.com wrote:

Synology uses a custom version of Linux based on Busybox.
There is no tool to daemonize a process, but I think websocketd should
start as a daemon instead of line interactive.
All this has nothing to do with SSL, maybe we should open a new issue ?


Reply to this email directly or view it on GitHub
#17 (comment).

@asergeyev
Copy link
Collaborator

I want to close this one. When we will explore SSL features they better to be in new issues.

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

No branches or pull requests

4 participants