-
Notifications
You must be signed in to change notification settings - Fork 18k
crypto/tls: handshake fails with EOF #13523
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
Comments
The code you referenced in conn.go is about alertCloseNotify (secure EOF). The comment there makes sense in context. But an EOF during handshake? I don't see how that can be ignored. If you get an EOF during handshake you won't be using that TLS connection. Seems like it failed for a reason. |
I'd double-check the supported cipher suites on the third-party service. We recently tracked down an EOF during TLS handshake that was a result of the remote service not allowing the default cipher suites Go's TLS implementation uses (though explicitly enabling one of the four non-default ciphers did work). curl would be using different ciphers than your Go test case... |
Regardless of whether this is cause of original error, I feel the issue should stand even if just to clean up wording (unless I'm reading it incorrectly). It states that it cannot make io.EOF an error, but on the next line sets it as an error since it would fail the net.Error type assertion. Am I misreading? |
@allgeek good call... adding -v to curl reveals that it's using:
It's still connecting, but with a supported cipher this time. That's not to say it still couldn't be an issue of curl doing something automagically for me (I guess since it works, that's pretty likely). Since opening the issue I've learned that this is what's running on the other side: https://nifi.apache.org/index.html I'm trying to get more information on configuration, but at least I might have a chance of getting something running to test against now. |
It sounds like what's going on is that if you use Go's TLS client to connect to a server that doesn't like any of the client's suggested protocols, the server just hangs up, and the Go client reports just "EOF". It should probably at least say something about being in a handshake. Does it? I don't see the actual output in the original bug report. |
@rsc - Yes, it just reports EOF. Personally, I didn't find the abbreviated error to be all that limiting. It only took me a few minutes to modify crypto/tls and find the line that was returning the error. I was just thrown off by the section in conn.go that I referenced above - but bradfitz cleared that up. I wasn't able to reproduce this on my own - that is I couldn't get a test case (with my own server) where the go client failed and curl succeeded (they either both succeeded or both failed) so this seems to be some weird edge case. Unfortunately I'm unable to find out anything more about the third party server that would help. As far as I'm concerned, I feel like the issue is resolved as well as it can be, although I can see how a more precise error message could help in some cases. |
OK, well it would be good to return unexpected EOF when its truly unexpected. But not a blocker for the release. Leaving open in case someone wants to work on it later. |
I manage a site with very large traffic and using Go 1.8 beta in production. We moved over from a PHP implementation by re-writing everything from scratch in go. We saw a significant drop in our users, and seeing our logs flooding with |
@einthusan, that seems unrelated. This bug was about client-side TLS. I'd move your server-side question to https://golang.org/wiki/Questions for now. I think I'm actually going to close this bug as TimedOut, since it's been a year now (two releases) and there's nothing quite actionable here. Anybody, feel free to reopen either this or another perhaps ideally a new bug with details of client-side TLS problems with Go 1.8beta+. |
@einthusan your site requires SNI support, which will exclude clients that don't send SNI (like IE 8). That could be your problem. I'd look at how you're selecting certificates at handshake time. |
@agl I will look into what SNI is and how to support it... It really sucks that "Go" doesn't have a "true" full-compatability SSL support by default. The entire "being really secure" model is causing all sorts of problems in the wild by not having "99%" support for all browsers out there. |
@einthusan SNI is the server name that some clients send (i.e. the |
@einthusan The behavior depends on the tls.Config you use to run the server. If you set config.Certificates to the certificate for einthusan.tv, then clients not using SNI will be able to connect just fine. If you only set config.GetCertificate, leaving config.Certificates nil, then only SNI clients will work. einthusan.tv is serving using a Let's Encrypt-issued cert. The Go clients I know about that integrate directly into the web server hook in with config.GetCertificate, for decent reasons. That would have the side-effect of requiring SNI. If you were serving HTTPS with PHP before, you should have an old certificate you can drop into config.Certificate. If not, you can probably get one with a command-line Let's Encrypt client and drop it in (but note that it expires in a short time interval, like three months). |
The |
I filed #18785, assuming that einthusan.tv is using golang.org/x/crypto/acme/autocert. Let's move the conversation there. |
Go Version: 1.5.1
OS/Arch: Linux & Darwin/amd64
I'm trying to connect to a web service hosted by a third party using mutual TLS. Here is the simple test case I am trying:
https://play.golang.org/p/wr8x8awD8u
I am able to connect as expected to the same web service with the same parameters for key, cert, etc using curl:
curl --cacert /home/nifi/robtest/nexusproxy/guard_ca.pem --cert /path/to/public_crt.pem --key /path/to/private_key.pem https://some.server.com:8000/some/path
The go test case fails with an EOF error.
Further:
I've traced the error to this line in the tls client handshake:
https://github.com/golang/go/blob/go1.5.1/src/crypto/tls/handshake_client.go#L561
This section https://github.com/golang/go/blob/go1.5.1/src/crypto/tls/conn.go#L541-L546 would seem to suggest that an EOF is expected in some cases but there doesn't appear to be any code to handle such a case.
The text was updated successfully, but these errors were encountered: