mirror of
https://github.com/tailscale/tailscale.git
synced 2024-12-04 23:45:34 +00:00
24f322bc43
We were eagerly doing a synchronous renewal of the cert while
trying to serve traffic. Instead of that, just do the cert
renewal in the background and continue serving traffic as long
as the cert is still valid.
This regressed in c1ecae13ab
when
we introduced ARI support and were trying to make the experience
of `tailscale cert` better. However, that ended up regressing
the experience for tsnet as it would not always doing the renewal
synchronously.
Fixes #9783
Signed-off-by: Maisem Ali <maisem@tailscale.com>
53 lines
1.4 KiB
Go
53 lines
1.4 KiB
Go
// Copyright (c) Tailscale Inc & AUTHORS
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
//go:build !ios && !android && !js
|
|
|
|
package localapi
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
"strings"
|
|
|
|
"tailscale.com/ipn/ipnlocal"
|
|
)
|
|
|
|
func (h *Handler) serveCert(w http.ResponseWriter, r *http.Request) {
|
|
if !h.PermitWrite && !h.PermitCert {
|
|
http.Error(w, "cert access denied", http.StatusForbidden)
|
|
return
|
|
}
|
|
domain, ok := strings.CutPrefix(r.URL.Path, "/localapi/v0/cert/")
|
|
if !ok {
|
|
http.Error(w, "internal handler config wired wrong", 500)
|
|
return
|
|
}
|
|
pair, err := h.b.GetCertPEM(r.Context(), domain)
|
|
if err != nil {
|
|
// TODO(bradfitz): 500 is a little lazy here. The errors returned from
|
|
// GetCertPEM (and everywhere) should carry info info to get whether
|
|
// they're 400 vs 403 vs 500 at minimum. And then we should have helpers
|
|
// (in tsweb probably) to return an error that looks at the error value
|
|
// to determine the HTTP status code.
|
|
http.Error(w, fmt.Sprint(err), 500)
|
|
return
|
|
}
|
|
serveKeyPair(w, r, pair)
|
|
}
|
|
|
|
func serveKeyPair(w http.ResponseWriter, r *http.Request, p *ipnlocal.TLSCertKeyPair) {
|
|
w.Header().Set("Content-Type", "text/plain")
|
|
switch r.URL.Query().Get("type") {
|
|
case "", "crt", "cert":
|
|
w.Write(p.CertPEM)
|
|
case "key":
|
|
w.Write(p.KeyPEM)
|
|
case "pair":
|
|
w.Write(p.KeyPEM)
|
|
w.Write(p.CertPEM)
|
|
default:
|
|
http.Error(w, `invalid type; want "cert" (default), "key", or "pair"`, 400)
|
|
}
|
|
}
|