ipn/ipnlocal: also use LetsEncrypt-baked-in roots for cert validation

We previously baked in the LetsEncrypt x509 root CA for our tlsdial
package.

This moves that out into a new "bakedroots" package and is now also
shared by ipn/ipnlocal's cert validation code (validCertPEM) that
decides whether it's time to fetch a new cert.

Otherwise, a machine without LetsEncrypt roots locally in its system
roots is unable to use tailscale cert/serve and fetch certs.

Fixes #14690

Change-Id: Ic88b3bdaabe25d56b9ff07ada56a27e3f11d7159
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
Brad Fitzpatrick
2025-01-21 15:30:55 -08:00
committed by Brad Fitzpatrick
parent e12b2a7267
commit 150cd30b1d
9 changed files with 164 additions and 110 deletions

View File

@@ -4,37 +4,22 @@
package tlsdial
import (
"crypto/x509"
"io"
"net"
"net/http"
"os"
"os/exec"
"path/filepath"
"reflect"
"runtime"
"sync/atomic"
"testing"
"tailscale.com/health"
"tailscale.com/net/bakedroots"
)
func resetOnce() {
rv := reflect.ValueOf(&bakedInRootsOnce).Elem()
rv.Set(reflect.Zero(rv.Type()))
}
func TestBakedInRoots(t *testing.T) {
resetOnce()
p := bakedInRoots()
got := p.Subjects()
if len(got) != 1 {
t.Errorf("subjects = %v; want 1", len(got))
}
}
func TestFallbackRootWorks(t *testing.T) {
defer resetOnce()
defer bakedroots.ResetForTest(t, nil)
const debug = false
if runtime.GOOS != "linux" {
@@ -69,14 +54,7 @@ func TestFallbackRootWorks(t *testing.T) {
if err != nil {
t.Fatal(err)
}
resetOnce()
bakedInRootsOnce.Do(func() {
p := x509.NewCertPool()
if !p.AppendCertsFromPEM(caPEM) {
t.Fatal("failed to add")
}
bakedInRootsOnce.p = p
})
bakedroots.ResetForTest(t, caPEM)
ln, err := net.Listen("tcp", "127.0.0.1:0")
if err != nil {