mirror of
https://github.com/tailscale/tailscale.git
synced 2025-03-23 17:51:05 +00:00
tstest/integration/vms: test DNS configuration
This uses a neat little tool to dump the output of DNS queries to standard out. This is the first end-to-end test of DNS that runs against actual linux systems. The /etc/resolv.conf test may look superflous, however this will help for correlating system state if one of the DNS tests fails. Signed-off-by: Christine Dodrill <xe@tailscale.com>
This commit is contained in:
parent
00b3c1c042
commit
0b9e938152
@ -43,6 +43,7 @@ type Server struct {
|
||||
DERPMap *tailcfg.DERPMap // nil means to use prod DERP map
|
||||
RequireAuth bool
|
||||
Verbose bool
|
||||
DNSConfig *tailcfg.DNSConfig // nil means no DNS config
|
||||
|
||||
// ExplicitBaseURL or HTTPTestServer must be set.
|
||||
ExplicitBaseURL string // e.g. "http://127.0.0.1:1234" with no trailing URL
|
||||
@ -453,6 +454,7 @@ func (s *Server) serveRegister(w http.ResponseWriter, r *http.Request, mkey tail
|
||||
MachineAuthorized: machineAuthorized,
|
||||
Addresses: allowedIPs,
|
||||
AllowedIPs: allowedIPs,
|
||||
Hostinfo: *req.Hostinfo,
|
||||
}
|
||||
requireAuth := s.RequireAuth
|
||||
if requireAuth && s.nodeKeyAuthed[req.NodeKey] {
|
||||
@ -691,6 +693,7 @@ func (s *Server) MapResponse(req *tailcfg.MapRequest) (res *tailcfg.MapResponse,
|
||||
Debug: &tailcfg.Debug{
|
||||
DisableUPnP: "true",
|
||||
},
|
||||
DNSConfig: s.DNSConfig,
|
||||
}
|
||||
for _, p := range s.AllNodes() {
|
||||
if p.StableID != node.StableID {
|
||||
|
55
tstest/integration/vms/dns_tester.go
Normal file
55
tstest/integration/vms/dns_tester.go
Normal file
@ -0,0 +1,55 @@
|
||||
// Copyright (c) 2021 Tailscale Inc & AUTHORS All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build ignore
|
||||
|
||||
// Command dns_tester exists in order to perform tests of our DNS
|
||||
// configuration stack. This was written because the state of DNS
|
||||
// in our target environments is so diverse that we need a little tool
|
||||
// to do this test for us.
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"net"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
target := flag.Arg(0)
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
errCount := 0
|
||||
wait := 25 * time.Millisecond
|
||||
for range make([]struct{}, 5) {
|
||||
err := lookup(ctx, target)
|
||||
if err != nil {
|
||||
errCount++
|
||||
time.Sleep(wait)
|
||||
wait = wait * 2
|
||||
continue
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
func lookup(ctx context.Context, target string) error {
|
||||
ctx, cancel := context.WithTimeout(ctx, time.Second)
|
||||
defer cancel()
|
||||
|
||||
hosts, err := net.LookupHost(target)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
json.NewEncoder(os.Stdout).Encode(hosts)
|
||||
return nil
|
||||
}
|
@ -26,8 +26,10 @@ import (
|
||||
"golang.org/x/crypto/ssh"
|
||||
"golang.org/x/net/proxy"
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/tstest/integration"
|
||||
"tailscale.com/tstest/integration/testcontrol"
|
||||
"tailscale.com/types/dnstype"
|
||||
)
|
||||
|
||||
type Harness struct {
|
||||
@ -55,7 +57,17 @@ func newHarness(t *testing.T) *Harness {
|
||||
})
|
||||
t.Logf("host:port: %s", ln.Addr())
|
||||
|
||||
cs := &testcontrol.Server{}
|
||||
cs := &testcontrol.Server{
|
||||
DNSConfig: &tailcfg.DNSConfig{
|
||||
// TODO: this is wrong.
|
||||
// It is also only one of many configurations.
|
||||
// Figure out how to scale it up.
|
||||
Resolvers: []dnstype.Resolver{{Addr: "100.100.100.100"}, {Addr: "8.8.8.8"}},
|
||||
Domains: []string{"record"},
|
||||
Proxied: true,
|
||||
ExtraRecords: []tailcfg.DNSRecord{{Name: "extratest.record", Type: "A", Value: "1.2.3.4"}},
|
||||
},
|
||||
}
|
||||
|
||||
derpMap := integration.RunDERPAndSTUN(t, t.Logf, bindHost)
|
||||
cs.DERPMap = derpMap
|
||||
|
@ -624,6 +624,48 @@ func (h *Harness) testDistro(t *testing.T, d Distro, ipm ipMapping) {
|
||||
t.Fatalf("wanted %q from vm, got: %q", securePassword, msg)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("dns-test", func(t *testing.T) {
|
||||
t.Run("etc-resolv-conf", func(t *testing.T) {
|
||||
sess := getSession(t, cli)
|
||||
sess.Stdout = logger.FuncWriter(t.Logf)
|
||||
sess.Stderr = logger.FuncWriter(t.Errorf)
|
||||
if err := sess.Run("cat /etc/resolv.conf"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
})
|
||||
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
t.Fatalf("can't get working directory: %v", err)
|
||||
}
|
||||
dir := t.TempDir()
|
||||
run(t, cwd, "go", "build", "-o", filepath.Join(dir, "dns_tester"), "./dns_tester.go")
|
||||
|
||||
sftpCli, err := sftp.NewClient(cli)
|
||||
if err != nil {
|
||||
t.Fatalf("can't connect over sftp to copy binaries: %v", err)
|
||||
}
|
||||
defer sftpCli.Close()
|
||||
|
||||
copyFile(t, sftpCli, filepath.Join(dir, "dns_tester"), "/dns_tester")
|
||||
|
||||
for _, record := range []string{"extratest.record", "extratest"} {
|
||||
t.Run(record, func(t *testing.T) {
|
||||
sess := getSession(t, cli)
|
||||
sess.Stderr = logger.FuncWriter(t.Errorf)
|
||||
msg, err := sess.Output("/dns_tester " + record)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
msg = bytes.TrimSpace(msg)
|
||||
if want := []byte("1.2.3.4"); !bytes.Contains(msg, want) {
|
||||
t.Fatalf("got: %q, want: %q", msg, want)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func runTestCommands(t *testing.T, timeout time.Duration, cli *ssh.Client, batch []expect.Batcher) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user