mirror of
				https://github.com/tailscale/tailscale.git
				synced 2025-10-27 06:11:43 +01:00 
			
		
		
		
	I'm not saying it works, but it compiles. Updates #5794 Change-Id: I2f3c99732e67fe57a05edb25b758d083417f083e Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
		
			
				
	
	
		
			125 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			125 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Copyright (c) Tailscale Inc & AUTHORS
 | |
| // SPDX-License-Identifier: BSD-3-Clause
 | |
| 
 | |
| //go:build !windows && !plan9
 | |
| 
 | |
| package vms
 | |
| 
 | |
| import (
 | |
| 	"context"
 | |
| 	"testing"
 | |
| 	"time"
 | |
| 
 | |
| 	"github.com/pkg/sftp"
 | |
| 	expect "github.com/tailscale/goexpect"
 | |
| )
 | |
| 
 | |
| func TestRunUbuntu1804(t *testing.T) {
 | |
| 	testOneDistribution(t, 0, Distros[0])
 | |
| }
 | |
| 
 | |
| func TestRunUbuntu2004(t *testing.T) {
 | |
| 	testOneDistribution(t, 1, Distros[1])
 | |
| }
 | |
| 
 | |
| func TestRunNixos2111(t *testing.T) {
 | |
| 	t.Parallel()
 | |
| 	testOneDistribution(t, 2, Distros[2])
 | |
| }
 | |
| 
 | |
| // TestMITMProxy is a smoke test for derphttp through a MITM proxy.
 | |
| // Encountering such proxies is unfortunately commonplace in more
 | |
| // traditional enterprise networks.
 | |
| //
 | |
| // We invoke tailscale netcheck because the networking check is done
 | |
| // by tailscale rather than tailscaled, making it easier to configure
 | |
| // the proxy.
 | |
| //
 | |
| // To provide the actual MITM server, we use squid.
 | |
| func TestMITMProxy(t *testing.T) {
 | |
| 	t.Parallel()
 | |
| 	setupTests(t)
 | |
| 	distro := Distros[2] // nixos-21.11
 | |
| 
 | |
| 	if distroRex.Unwrap().MatchString(distro.Name) {
 | |
| 		t.Logf("%s matches %s", distro.Name, distroRex.Unwrap())
 | |
| 	} else {
 | |
| 		t.Skip("regex not matched")
 | |
| 	}
 | |
| 
 | |
| 	ctx, done := context.WithCancel(context.Background())
 | |
| 	t.Cleanup(done)
 | |
| 
 | |
| 	h := newHarness(t)
 | |
| 
 | |
| 	err := ramsem.sem.Acquire(ctx, int64(distro.MemoryMegs))
 | |
| 	if err != nil {
 | |
| 		t.Fatalf("can't acquire ram semaphore: %v", err)
 | |
| 	}
 | |
| 	t.Cleanup(func() { ramsem.sem.Release(int64(distro.MemoryMegs)) })
 | |
| 
 | |
| 	vm := h.mkVM(t, 2, distro, h.pubKey, h.loginServerURL, t.TempDir())
 | |
| 	vm.waitStartup(t)
 | |
| 
 | |
| 	ipm := h.waitForIPMap(t, vm, distro)
 | |
| 	_, cli := h.setupSSHShell(t, distro, ipm)
 | |
| 
 | |
| 	sftpCli, err := sftp.NewClient(cli)
 | |
| 	if err != nil {
 | |
| 		t.Fatalf("can't connect over sftp to copy binaries: %v", err)
 | |
| 	}
 | |
| 	defer sftpCli.Close()
 | |
| 
 | |
| 	// Initialize a squid installation.
 | |
| 	//
 | |
| 	// A few things of note here:
 | |
| 	// - The first thing we do is append the nsslcrtd_program stanza to the config.
 | |
| 	//   This must be an absolute path and is based on the nix path of the squid derivation,
 | |
| 	//   so we compute and write it out here.
 | |
| 	// - Squid expects a pre-initialized directory layout, so we create that in /tmp/squid then
 | |
| 	//   invoke squid with -z to have it fill in the rest.
 | |
| 	// - Doing a meddler-in-the-middle attack requires using some fake keys, so we create
 | |
| 	//   them using openssl and then use the security_file_certgen tool to setup squids' ssl_db.
 | |
| 	// - There were some perms issues, so i yeeted 0777. Its only a test anyway
 | |
| 	copyFile(t, sftpCli, "squid.conf", "/tmp/squid.conf")
 | |
| 	runTestCommands(t, 30*time.Second, cli, []expect.Batcher{
 | |
| 		&expect.BSnd{S: "echo -e \"\\nsslcrtd_program $(nix eval --raw nixpkgs.squid)/libexec/security_file_certgen -s /tmp/squid/ssl_db -M 4MB\\n\" >> /tmp/squid.conf\n"},
 | |
| 		&expect.BSnd{S: "mkdir -p /tmp/squid/{cache,core}\n"},
 | |
| 		&expect.BSnd{S: "openssl req -batch -new -newkey rsa:4096 -sha256 -days 3650 -nodes -x509 -keyout /tmp/squid/myca-mitm.pem -out /tmp/squid/myca-mitm.pem\n"},
 | |
| 		&expect.BExp{R: `writing new private key to '/tmp/squid/myca-mitm.pem'`},
 | |
| 		&expect.BSnd{S: "$(nix eval --raw nixpkgs.squid)/libexec/security_file_certgen -c -s /tmp/squid/ssl_db -M 4MB\n"},
 | |
| 		&expect.BExp{R: `Done`},
 | |
| 		&expect.BSnd{S: "sudo chmod -R 0777 /tmp/squid\n"},
 | |
| 		&expect.BSnd{S: "squid --foreground -YCs -z -f /tmp/squid.conf\n"},
 | |
| 		&expect.BSnd{S: "echo Success.\n"},
 | |
| 		&expect.BExp{R: `Success.`},
 | |
| 	})
 | |
| 
 | |
| 	// Start the squid server.
 | |
| 	runTestCommands(t, 10*time.Second, cli, []expect.Batcher{
 | |
| 		&expect.BSnd{S: "daemonize -v -c /tmp/squid $(nix eval --raw nixpkgs.squid)/bin/squid --foreground -YCs -f /tmp/squid.conf\n"}, // start daemon
 | |
| 		// NOTE(tom): Writing to /dev/tcp/* is bash magic, not a file. This
 | |
| 		//            eldritchian incantation lets us wait till squid is up.
 | |
| 		&expect.BSnd{S: "while ! timeout 5 bash -c 'echo > /dev/tcp/localhost/3128'; do sleep 1; done\n"},
 | |
| 		&expect.BSnd{S: "echo Success.\n"},
 | |
| 		&expect.BExp{R: `Success.`},
 | |
| 	})
 | |
| 
 | |
| 	// Uncomment to help debugging this test if it fails.
 | |
| 	//
 | |
| 	// runTestCommands(t, 30 * time.Second, cli, []expect.Batcher{
 | |
| 	// 	&expect.BSnd{S: "sudo ifconfig\n"},
 | |
| 	// 	&expect.BSnd{S: "sudo ip link\n"},
 | |
| 	// 	&expect.BSnd{S: "sudo ip route\n"},
 | |
| 	// 	&expect.BSnd{S: "ps -aux\n"},
 | |
| 	// 	&expect.BSnd{S: "netstat -a\n"},
 | |
| 	// 	&expect.BSnd{S: "cat /tmp/squid/access.log && cat /tmp/squid/cache.log && cat /tmp/squid.conf && echo Success.\n"},
 | |
| 	// 	&expect.BExp{R: `Success.`},
 | |
| 	// })
 | |
| 
 | |
| 	runTestCommands(t, 30*time.Second, cli, []expect.Batcher{
 | |
| 		&expect.BSnd{S: "SSL_CERT_FILE=/tmp/squid/myca-mitm.pem HTTPS_PROXY=http://127.0.0.1:3128 tailscale netcheck\n"},
 | |
| 		&expect.BExp{R: `IPv4: yes`},
 | |
| 	})
 | |
| }
 |