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
net/http: decide how users should use SetSessionTicketKeys with ServeTLS, etc #22018
Comments
CC @tombergan |
@tombergan thanks for the info! |
That would be an option. I don't know if any programs rely on Server.TLSConfig not being mutated -- it's certainly possible. I also don't know why it was originally decided that using the same tls.Config from multiple places should be allowed in the first place, especially given that a tls.Config can be mutated with methods like /cc @bradfitz |
Ugh.
I'm sure if we start mutating it, we'll get new data race reports. I don't think that's an option. If anything, we probably need to either provide a mechanism (new API? new heuristic?) to not clone, or we need to add new API to get the current (cloned) TLS config.
You're assuming there was ever a decision and we didn't just end up here by accident. I think the general mutability of *tls.Config happened gradually over time. I mean, here was go1's API surface here:
|
hey @bradfitz , thanks for taking the time to chime in! :)
Sounds reasonable.
IMHO having a heuristic to decide whether to clone sounds like it could further complicate the issue: it would be even less obvious if our passed-in To make the separation between configuration and runtime clearer, this new method could return an interface like the following, instead of a type LiveTLSConfig interface {
Clone() *tls.Config
SetSessionTicketKeys(keys [][32]byte)
} making it very explicit which operations are sane and safe in a "live"
The suggestion above would be one way to start addressing this semantic drift in the API, without braking current code. If it sounds workable at all to you, I'd take a shot at implementing it. Otherwise, if you think this issue doesn't warrant increasing the API surface, I'd prepare a patch to at least clarify the docs about this gotcha. |
Change https://golang.org/cl/86415 mentions this issue: |
It's super late in the Go 1.10 cycle so I just mailed docs for now. In the docs I mentioned that the workaround to use SetSessionTicketKeys is to use http.Server.Serve instead, using the tls.Listen Listener instead. We can consider this more for Go 1.11. |
Updates #22018 Change-Id: I8a85324e9d53dd4d279ed05cdb93f50d55cf767b Reviewed-on: https://go-review.googlesource.com/86415 Reviewed-by: Ian Lance Taylor <iant@golang.org>
I meet the same kind of issue with the server := httptest.NewUnstartedServer(h)
err := http2.ConfigureServer(server.Config, nil)
if err != nil {
t.Fatal(err)
}
// Copy the configured TLS of the *http.Server to the one used by StartTLS
server.TLS = server.Config.TLSConfig
server.StartTLS() |
Sorry, I thought this was just a documentation bug (we already did some docs) so I pushed it off until later in the release. Now I see we might want to do more. I've removed the Documentation label and retitled for Go 1.12. /cc @FiloSottile |
Short version:
Using😉
tls.Config.SetSessionTicketKeys
does not work withhttp.Server.ServeTLS
(and all methods that build on it, likeListenAndServeTLS
).Problem arises because
tls.Config
gets cloned insideServeTLS
and there seems to be no way to reference the new one from "outside". If this behavior can't be changed, at least a mention in the docs might be nice!Long version:
What version of Go are you using (
go version
)?1.9 (but problem seems to be present starting with 1.5)
Does this issue reproduce with the latest release?
yes
What operating system and processor architecture are you using (
go env
)?What did you do?
Attempt to use
tls.Config.SetSessionTicketKeys
on a running server, which is explicitly mentioned as possible in the docs:And then checked to see if session-resumption works with:
What did you expect to see?
What did you see instead?
Session was reused in all scenarios, consistent with what would be expected because of the
tls.Config
cloning mentioned in the "short" explanation above.Why is this a problem?
Because there is no mention in the docs (or did I miss something?) that using
ServeTLS
and friends will cause your reference totls.Config
to become "useless", in the sense that it doesn't reflect the running server's state. Workaround would be to create your ownnet.Listener
, but that means a lot of boilerplate code, e.g. replicatingtcpKeepAliveListener
, etc.I think I understand why the clone might be necessary (I imagine it has to do with not changing it because it might be reused), but I can't think of a reason to not update the pointer in the
http.Server
struct to point to the new clone. Am I missing something obvious?But even if I am, it would be nice to mention this "gotcha" in the docs (I'd be happy to prepare a small PR for that if there are no objections)
The text was updated successfully, but these errors were encountered: