tstest/natlab: add ACME cert vmtest
This adds a fake vnet ACME service, TXT-backed SetDNS support, and a VM test that fetches a certificate with tailscale cert, serves it with tailscale serve, and verifies HTTPS from a second node. This adds coverage motivated by #19915. Updates #13038 Change-Id: Ie1e53409509337d81c8fbceb63f59f3dfbd48207 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
committed by
Brad Fitzpatrick
parent
84ffcd2759
commit
26864f1302
@@ -93,6 +93,7 @@ type Env struct {
|
||||
allOnline bool // mark every peer as Online=true in MapResponses
|
||||
peerRelayGrants bool // grant peer-relay capabilities on the wildcard packet filter
|
||||
selfSignedDERPCertPinning bool // serve test DERP map with sha256-raw cert pins
|
||||
fakeACME bool // point tailscaled at vnet's fake ACME server
|
||||
|
||||
// Shared resource initialization (sync.Once for things multiple nodes share).
|
||||
vnetOnce sync.Once
|
||||
@@ -394,6 +395,12 @@ func SelfSignedDERPCertPinning() EnvOption {
|
||||
return envOptFunc(func(e *Env) { e.selfSignedDERPCertPinning = true })
|
||||
}
|
||||
|
||||
// FakeACME returns an [EnvOption] that points nodes at vnet's in-process ACME
|
||||
// CA and configures the test control server to advertise MagicDNS cert domains.
|
||||
func FakeACME() EnvOption {
|
||||
return envOptFunc(func(e *Env) { e.fakeACME = true })
|
||||
}
|
||||
|
||||
// AddNetwork creates a new virtual network. Arguments follow the same pattern as
|
||||
// vnet.Config.AddNetwork (string IPs, NAT types, NetworkService values).
|
||||
func (e *Env) AddNetwork(opts ...any) *vnet.Network {
|
||||
@@ -463,6 +470,12 @@ func (e *Env) AddNode(name string, opts ...any) *Node {
|
||||
vnetOpts = append(vnetOpts, o)
|
||||
}
|
||||
}
|
||||
if e.fakeACME {
|
||||
vnetOpts = append(vnetOpts, vnet.TailscaledEnv{
|
||||
Key: "TS_DEBUG_ACME_DIRECTORY_URL",
|
||||
Value: "http://acme.example/directory",
|
||||
})
|
||||
}
|
||||
|
||||
// macOS VMs require a macOS arm64 host (Apple Virtualization.framework via
|
||||
// tailmac). Skip the test now rather than letting it proceed through the
|
||||
@@ -810,6 +823,12 @@ func (e *Env) ControlServer() *testcontrol.Server {
|
||||
return e.server.ControlServer()
|
||||
}
|
||||
|
||||
// FakeACMERootPEM returns the root certificate for vnet's fake ACME CA.
|
||||
func (e *Env) FakeACMERootPEM() []byte {
|
||||
e.initVnet()
|
||||
return e.server.FakeACMERootPEM()
|
||||
}
|
||||
|
||||
// BringUpMullvadWGServer brings up a userspace WireGuard server on n,
|
||||
// configured as a single-peer "Mullvad-style" exit-node target. The
|
||||
// server runs inside n's TTA process on a Linux TUN named "wg0".
|
||||
@@ -1229,6 +1248,7 @@ func (e *Env) SSHExec(n *Node, cmd string) (string, error) {
|
||||
"-o", "StrictHostKeyChecking=no",
|
||||
"-o", "UserKnownHostsFile=/dev/null",
|
||||
"-o", "ConnectTimeout=5",
|
||||
"-o", "LogLevel=ERROR",
|
||||
"-i", "/tmp/vmtest_key",
|
||||
"-p", fmt.Sprintf("%d", n.sshPort),
|
||||
"root@127.0.0.1",
|
||||
@@ -1445,6 +1465,14 @@ func (e *Env) initVnet() {
|
||||
if e.selfSignedDERPCertPinning {
|
||||
e.server.ControlServer().DERPMap = e.buildSelfSignedDERPMap()
|
||||
}
|
||||
if e.fakeACME {
|
||||
cs := e.server.ControlServer()
|
||||
cs.MagicDNSDomain = "tailnet.test"
|
||||
if cs.DNSConfig == nil {
|
||||
cs.DNSConfig = new(tailcfg.DNSConfig)
|
||||
}
|
||||
cs.DNSConfig.Proxied = true
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user