From b1cf0a04d6d1ca494ec3774dac48037b8abe792e Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Wed, 26 Jan 2022 12:16:02 -0800 Subject: [PATCH] cmd/derper: provide support for forcing autocert renewals Change-Id: I127a803144ec5ca989823610f1bbd21dc5cfadba Signed-off-by: Brad Fitzpatrick --- cmd/derper/cert.go | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/cmd/derper/cert.go b/cmd/derper/cert.go index 972540397..233371f67 100644 --- a/cmd/derper/cert.go +++ b/cmd/derper/cert.go @@ -10,8 +10,11 @@ import ( "errors" "fmt" "net/http" + "os" "path/filepath" "regexp" + "strings" + "time" "golang.org/x/crypto/acme/autocert" ) @@ -39,6 +42,24 @@ func certProviderByCertMode(mode, dir, hostname string) (certProvider, error) { if hostname == "derp.tailscale.com" { certManager.HostPolicy = prodAutocertHostPolicy certManager.Email = "security@tailscale.com" + if v, err := os.ReadFile("/home/derp/forcerenew.secret"); err == nil { + proto := strings.TrimSpace(string(v)) + am2 := *certManager + am2.RenewBefore = 89 * 24 * time.Hour + defGetCertificate := certManager.TLSConfig().GetCertificate + tlsConf2 := am2.TLSConfig() + getCertificate := func(hi *tls.ClientHelloInfo) (*tls.Certificate, error) { + for _, p := range hi.SupportedProtos { + if p == proto { + return tlsConf2.GetCertificate(hi) + } + } + return defGetCertificate(hi) + } + altConf := certManager.TLSConfig() + altConf.GetCertificate = getCertificate + return altConfig{certManager, altConf}, nil + } } return certManager, nil case "manual": @@ -48,6 +69,14 @@ func certProviderByCertMode(mode, dir, hostname string) (certProvider, error) { } } +// altConfig is a certProvider wrapper that returns an explicit tls.Config. +type altConfig struct { + certProvider + tlsConfig *tls.Config +} + +func (ac altConfig) TLSConfig() *tls.Config { return ac.tlsConfig } + type manualCertManager struct { cert *tls.Certificate hostname string