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

x/net/websocket: chrome wss doesn't work with go-lang https/tls server #6121

Closed
xoba opened this issue Aug 12, 2013 · 14 comments
Closed

x/net/websocket: chrome wss doesn't work with go-lang https/tls server #6121

xoba opened this issue Aug 12, 2013 · 14 comments
Milestone

Comments

@xoba
Copy link
Contributor

@xoba xoba commented Aug 12, 2013

What steps will reproduce the problem?
If possible, include a link to a program on play.golang.org.

0. see http://play.golang.org/p/FM79CQOQT1 for my test code "ws.go", which
runs fine on a real machine but not in play environment because of websockets
1. "go run ws.go"
2. in a browser, visit unsecure url "http://localhost:8080"; ---
this is insecure version, you should see echo messages once per second
3. in a browser, visit secure url "https://localhost:8090"; ---
    this is secure version, depending on browser type, you should see same output as insecure version, or error; note
      that you will have to accept the untrusted certificate below and/or security exception manually when prompted.

What is the expected output?
list of log events in browser: "open", then multiple "message"
events once per second

What do you see instead?
for wss in chrome (my version is 28.0.1500.95), we see error and premature close events
(i.e., wss fails), whereas firefox and opera work fine. note that wss in chrome seems to
work fine with other non-golang https/tls servers. for insecure websockets (ws), all
three work fine: chrome, firefox, & opera.

Which compiler are you using (5g, 6g, 8g, gccgo)?
i run the test code as "go run ws.go"

Which operating system are you using?
http://linuxmint.com/ 64-bit v15

Which version are you using?  (run 'go version')
go version devel +d7db8c804ffa Mon Aug 12 13:03:50 2013 +1000 linux/amd64

Please provide any additional information below.
code at http://play.golang.org/p/FM79CQOQT1 is attached

Attachments:

  1. ws.go (5559 bytes)
@robpike
Copy link
Contributor

@robpike robpike commented Aug 13, 2013

Comment 1:

No idea even who's responsible for this. It's possibly a chrome bug.

Labels changed: added priority-later, removed priority-triage, go1.2maybe.

@robpike
Copy link
Contributor

@robpike robpike commented Aug 13, 2013

Comment 2:

Status changed to Accepted.

@xoba
Copy link
Contributor Author

@xoba xoba commented Aug 13, 2013

Comment 3:

this updated version of ws.go (attached) now works in chrome browser with secure
websockets! with one important caveat, however: 
it embeds a node.js tls proxy server, which handles the tls on the frontend, proxying
the secure sockets to insecure ones (plain http) on the go-lang backend.
so for whatever reason, it seems the root issue is chrome-vs-golang tls, not secure
websockets per se.
node.js-to-chrome connections here are TLS 1.1, whereas the original go-lang-only ones
were SSL 3.0 with an additional warning about possibly outdated server code on chrome's
connection detail popup.
so for now, this is my workaround.

Attachments:

  1. ws.go (5758 bytes)
@mb0
Copy link

@mb0 mb0 commented Aug 28, 2013

Comment 4:

i have the same problem with wss: in chrome. it worked fine until revision 47ec7a68b1a2.
https://code.google.com/p/go/source/detail?r=47ec7a68b1a2b01cd9d6a4ea6d4f4042ea377eb7&name=default
the other problem after this revision is that client certificate authentication also
fails in chrome.
i would like to provide more info, but i have no idea where to start.
@mb0
Copy link

@mb0 mb0 commented Aug 28, 2013

Comment 5:

i found a workaround. if i disable the ECDHE-ECDSA ciphers in chromium, both secure
websockets (wss:) and client certificate authentication work again:
$ chromium-browser --cipher-suite-blacklist=0xc007,0xc009,0xc00a
i got the cipher ids from crypt/tls/cipher_suites.go
TLS_ECDHE_ECDSA_WITH_RC4_128_SHA     uint16 = 0xc007
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA uint16 = 0xc009
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA uint16 = 0xc00a
@gopherbot
Copy link

@gopherbot gopherbot commented Aug 28, 2013

Comment 6 by ben.lubar:

I've added a workaround to my program that disables the malfunctioning ciphers.
Something similar could work for other programs, so I'll post the commit here:
BenLubar/Rnoadm@45e1006
@andybalholm
Copy link
Contributor

@andybalholm andybalholm commented Aug 29, 2013

Comment 7:

I'm having a the same problem, but not with websockets. Running a MITM HTTPS proxy, I
get a lot of errors related to ECDHE_ECDSA when Chrome connects to Google sites through
my proxy. The problem seems to be that somehow a cipher suite using ECDSA is being
chosen even though my server certificate has an RSA private key—and therefore it can't
do ECDSA.
If I disable the ECDHE_ECDSA cipher suites in  crypto/tls/cipher_suites.go, the errors
go away. But the real solution would be for the function that picks the cipher suite to
take the type of server certificate into account.
@xoba
Copy link
Contributor Author

@xoba xoba commented Aug 29, 2013

Comment 8:

using this workaround provided by ben, works for me now -- thanks! i'm really curious
what should be fixed though --- golang or chromium browser or both?
TLSConfig: &tls.Config{
      // BUG: https://golang.org/issue/6121
      CipherSuites: []uint16{
        tls.TLS_RSA_WITH_RC4_128_SHA,
        tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA,
        tls.TLS_RSA_WITH_AES_128_CBC_SHA,
        tls.TLS_RSA_WITH_AES_256_CBC_SHA,
      },
    }
@rsc
Copy link
Contributor

@rsc rsc commented Nov 27, 2013

Comment 9:

Labels changed: added go1.3maybe.

@rsc
Copy link
Contributor

@rsc rsc commented Dec 4, 2013

Comment 10:

Labels changed: added release-none, removed go1.3maybe.

@rsc
Copy link
Contributor

@rsc rsc commented Dec 4, 2013

Comment 11:

Labels changed: added repo-net.

@xoba xoba added accepted labels Dec 4, 2013
@mikioh mikioh changed the title go.net/websocket: chrome wss doesn't work with go-lang https/tls server x/net/websocket: chrome wss doesn't work with go-lang https/tls server Dec 23, 2014
@mikioh mikioh added repo-net and removed repo-net labels Dec 23, 2014
@mikioh mikioh changed the title x/net/websocket: chrome wss doesn't work with go-lang https/tls server websocket: chrome wss doesn't work with go-lang https/tls server Jan 4, 2015
@mikioh
Copy link
Contributor

@mikioh mikioh commented Jan 15, 2015

Nowadays looks like it's okay. I just tried with Chrome Version 39.0.2171.99 (64-bit), Go 1.4 and current x/net subrepo, and didn't see any failures.

@mikioh mikioh closed this Jan 15, 2015
@integrii
Copy link

@integrii integrii commented Jul 4, 2015

I don't think its completely fixed, or it is broken again in the same way. This is still happening for me on go version 1.4.2 x64. Safari (version 9.0) works, but Firefox (version 39.0) and Chrome do not (version 43 on OSX). It also appears that javax.websocket gets a 403.

I get this error in Chrome:

WebSocket connection to 'wss://my.domain.com:8000/copyTest' failed: Error during WebSocket handshake: Unexpected response code: 403

Nothing is produced at the go terminal, unless i hit it with javax.websocket - which produces this:

http: TLS handshake error from 127.0.0.1:44249: tls: first record does not look like a TLS handshake

In Safari I get the expected result in the javascript console:

[Log] sent data:test (testClient.html, line 31)
[Log] got data:test (testClient.html, line 19)

in Firefox I get a 403 similar to Chrome and the console shows this:

GET 
https://my.domain.com:8000/rideTracking [HTTP/1.1 403 Forbidden 3ms]
"got error:" error { target: WebSocket, isTrusted: true, currentTarget: WebSocket, eventPhase: 2, bubbles: false, cancelable: false, defaultPrevented: false, timeStamp: 1435967773819792, originalTarget: WebSocket, explicitOriginalTarget: WebSocket, NONE: 0 } testClient.html:22:5
"got close:" close { target: WebSocket, isTrusted: true, wasClean: false, code: 1006, reason: "", currentTarget: WebSocket, eventPhase: 2, bubbles: false, cancelable: false, defaultPrevented: false, timeStamp: 1435967773821310 } testClient.html:25:5

Here is some go code to serve TLS websockets. sub in your own cert.key and cert.pem files.

package main

import (
    "golang.org/x/net/websocket"
    "io"
    "log"
    "net/http"
)

func copyTest(ws *websocket.Conn) {
    io.Copy(ws, ws)
}

func main() {

    // setup http handler
    http.Handle("/copyTest", websocket.Handler(copyTest))

    // start secure websocket server
    log.Println("Listening for secure websocket connections on localhost port 8000...")
    if err := http.ListenAndServeTLS(":8000", "cert.pem", "cert.key", nil); err != nil {
        panic("ListenAndServeTLS Error: " + err.Error())
    }
}

Here is a javascript client. Sub in the proper domain name for your cert instead of localhost and connect using it. Results will be written to the javascript console.

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>Websocket connector</title>
        <script src="http://code.jquery.com/jquery-compat-git.js">
        </script>
    </head>
    <body>
            <input id="name" type="text" />
            <button id="sendBtn">send</a>

        <script>
            var ws = new WebSocket("wss://localhost:8000/copyTest");

            ws.onmessage = function(e) {
                console.log("got data:" + e.data);
            };
            ws.onerror = function(e) {
                console.log("got error:", e);
            };
            ws.onclose = function(e) {
                console.log("got close:", e);
            };

            $('#sendBtn').click(function(){
                var data = $('#name').val();
                ws.send(data);
                console.log("sent data:" + data);
            });
        </script>
    </body>
</html>
@mikioh
Copy link
Contributor

@mikioh mikioh commented Jul 4, 2015

@integrii,

Please open a new issue.

@mikioh mikioh changed the title websocket: chrome wss doesn't work with go-lang https/tls server x/net/websocket: chrome wss doesn't work with go-lang https/tls server Jul 4, 2015
@mikioh mikioh modified the milestone: Unreleased Jul 30, 2015
@golang golang locked and limited conversation to collaborators Aug 5, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
8 participants
You can’t perform that action at this time.