mirror of
https://github.com/tailscale/tailscale.git
synced 2026-05-05 12:16:44 +02:00
control/controlhttp: send expected control public key in upgrade request
So we can do key rotation later and have small windows of overlapping valid server keys. Updates #3488 Change-Id: Ib5c7f2006a797a069e3f55d37f5d41f533e82f71 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
parent
61cdcf4082
commit
3928ea206e
@ -50,6 +50,10 @@ const (
|
||||
// payload, to save an RTT.
|
||||
handshakeHeaderName = "X-Tailscale-Handshake"
|
||||
|
||||
// serverPubHeaderName is the HTTP request header that
|
||||
// says the expected public key of the control plane.
|
||||
serverPubHeaderName = "X-Tailscale-Control-Public"
|
||||
|
||||
// serverUpgradePath is where the server-side HTTP handler to
|
||||
// to do the protocol switch is located.
|
||||
serverUpgradePath = "/ts2021"
|
||||
@ -194,6 +198,7 @@ func (a *dialParams) tryURL(u *url.URL, init []byte) (net.Conn, error) {
|
||||
"Upgrade": []string{upgradeHeaderValue},
|
||||
"Connection": []string{"upgrade"},
|
||||
handshakeHeaderName: []string{base64.StdEncoding.EncodeToString(init)},
|
||||
serverPubHeaderName: []string{a.controlKey.String()},
|
||||
},
|
||||
}
|
||||
req = req.WithContext(ctx)
|
||||
|
||||
@ -44,6 +44,18 @@ func AcceptHTTP(ctx context.Context, w http.ResponseWriter, r *http.Request, pri
|
||||
return nil, fmt.Errorf("decoding base64 handshake header: %v", err)
|
||||
}
|
||||
|
||||
if wantPub := r.Header.Get(serverPubHeaderName); wantPub != "" {
|
||||
// If the client declared the public key they expect to speak to,
|
||||
// check it.
|
||||
// TODO: replace the 'private' parameter with a func/interface
|
||||
// that looks up the private key as a function of the public key
|
||||
// to see if we have a currently in-rotation key that's valid.
|
||||
if private.Public().String() != wantPub {
|
||||
http.Error(w, "requested server key unavailable", http.StatusServiceUnavailable)
|
||||
return nil, errors.New("client requested unavailble server key")
|
||||
}
|
||||
}
|
||||
|
||||
hijacker, ok := w.(http.Hijacker)
|
||||
if !ok {
|
||||
http.Error(w, "make request over HTTP/1", http.StatusBadRequest)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user