From 3904e4d1751845dc038d7ecd53fe57cb64f14898 Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Fri, 23 Aug 2024 11:27:42 -0700 Subject: [PATCH] cmd/tta, tstest/natlab/vnet: remove unneeded port 124 log hack, add log buffer The natlab Test Agent (tta) still had its old log streaming hack in place where it dialed out to anything on TCP port 124 and those logs were streamed to the host running the tests. But we'd since added gokrazy syslog streaming support, which made that redundant. So remove all the port 124 stuff. And then make sure we log to stderr so gokrazy logs it to syslog. Also, keep the first 1MB of logs in memory in tta too, exported via localhost:8034/logs for interactive debugging. That was very useful during debugging when I added IPv6 support. (which is coming in future PRs) Updates #13038 Change-Id: Ieed904a704410b9031d5fd5f014a73412348fa7f Signed-off-by: Brad Fitzpatrick --- cmd/tta/tta.go | 40 +++++++++++++++---- .../natlabapp/builddir/tailscale.com/go.sum | 4 ++ tstest/natlab/vnet/vnet.go | 25 ++---------- 3 files changed, 40 insertions(+), 29 deletions(-) diff --git a/cmd/tta/tta.go b/cmd/tta/tta.go index 6a676b0d2..a14f6efa8 100644 --- a/cmd/tta/tta.go +++ b/cmd/tta/tta.go @@ -11,6 +11,7 @@ package main import ( + "bytes" "context" "errors" "flag" @@ -70,6 +71,9 @@ func (rt *localClientRoundTripper) RoundTrip(req *http.Request) (*http.Response, } func main() { + var logBuf logBuffer + log.SetOutput(io.MultiWriter(os.Stderr, &logBuf)) + if distro.Get() == distro.Gokrazy { if !hostinfo.IsNATLabGuestVM() { // "Exiting immediately with status code 0 when the @@ -90,11 +94,6 @@ func main() { } } - logc, err := net.Dial("tcp", "9.9.9.9:124") - if err == nil { - log.SetOutput(logc) - } - log.Printf("Tailscale Test Agent running.") gokRP := httputil.NewSingleHostReverseProxy(must.Get(url.Parse("http://gokrazy"))) @@ -163,11 +162,17 @@ func main() { serveCmd(w, "tailscale", "up", "--login-server=http://control.tailscale") }) ttaMux.HandleFunc("/fw", addFirewallHandler) - + ttaMux.HandleFunc("/logs", func(w http.ResponseWriter, r *http.Request) { + logBuf.mu.Lock() + defer logBuf.mu.Unlock() + w.Header().Set("Content-Type", "text/plain; charset=utf-8") + w.Write(logBuf.buf.Bytes()) + }) go hs.Serve(chanListener(conns)) // For doing agent operations locally from gokrazy: - // (e.g. with "wget -O - localhost:8123/fw") + // (e.g. with "wget -O - localhost:8123/fw" or "wget -O - localhost:8123/logs" + // to get early tta logs before the port 124 connection is established) go func() { err := http.ListenAndServe("127.0.0.1:8123", &ttaMux) if err != nil { @@ -236,3 +241,24 @@ func addFirewallHandler(w http.ResponseWriter, r *http.Request) { } var addFirewall func() error // set by fw_linux.go + +// logBuffer is a bytes.Buffer that is safe for concurrent use +// intended to capture early logs from the process, even if +// gokrazy's syslog streaming isn't working or yet working. +// It only captures the first 1MB of logs, as that's considered +// plenty for early debugging. At runtime, it's assumed that +// syslog log streaming is working. +type logBuffer struct { + mu sync.Mutex + buf bytes.Buffer +} + +func (lb *logBuffer) Write(p []byte) (n int, err error) { + lb.mu.Lock() + defer lb.mu.Unlock() + const maxSize = 1 << 20 // more than plenty; see type comment + if lb.buf.Len() > maxSize { + return len(p), nil + } + return lb.buf.Write(p) +} diff --git a/gokrazy/natlabapp/builddir/tailscale.com/go.sum b/gokrazy/natlabapp/builddir/tailscale.com/go.sum index 6660fa9a6..9123439ed 100644 --- a/gokrazy/natlabapp/builddir/tailscale.com/go.sum +++ b/gokrazy/natlabapp/builddir/tailscale.com/go.sum @@ -68,6 +68,8 @@ github.com/hdevalence/ed25519consensus v0.2.0 h1:37ICyZqdyj0lAZ8P4D1d1id3HqbbG1N github.com/hdevalence/ed25519consensus v0.2.0/go.mod h1:w3BHWjwJbFU29IRHL1Iqkw3sus+7FctEyM4RqDxYNzo= github.com/illarion/gonotify v1.0.1 h1:F1d+0Fgbq/sDWjj/r66ekjDG+IDeecQKUFH4wNwsoio= github.com/illarion/gonotify v1.0.1/go.mod h1:zt5pmDofZpU1f8aqlK0+95eQhoEAn/d4G4B/FjVW4jE= +github.com/illarion/gonotify/v2 v2.0.2 h1:oDH5yvxq9oiQGWUeut42uShcWzOy/hsT9E7pvO95+kQ= +github.com/illarion/gonotify/v2 v2.0.2/go.mod h1:38oIJTgFqupkEydkkClkbL6i5lXV/bxdH9do5TALPEE= github.com/insomniacslk/dhcp v0.0.0-20231206064809-8c70d406f6d2 h1:9K06NfxkBh25x56yVhWWlKFE8YpicaSfHwoV8SFbueA= github.com/insomniacslk/dhcp v0.0.0-20231206064809-8c70d406f6d2/go.mod h1:3A9PQ1cunSDF/1rbTq99Ts4pVnycWg+vlPkfeD2NLFI= github.com/jellydator/ttlcache/v3 v3.1.0 h1:0gPFG0IHHP6xyUyXq+JaD8fwkDCqgqwohXNJBcYE71g= @@ -120,6 +122,8 @@ github.com/tailscale/hujson v0.0.0-20221223112325-20486734a56a h1:SJy1Pu0eH1C29X github.com/tailscale/hujson v0.0.0-20221223112325-20486734a56a/go.mod h1:DFSS3NAGHthKo1gTlmEcSBiZrRJXi28rLNd/1udP1c8= github.com/tailscale/netlink v1.1.1-0.20211101221916-cabfb018fe85 h1:zrsUcqrG2uQSPhaUPjUQwozcRdDdSxxqhNgNZ3drZFk= github.com/tailscale/netlink v1.1.1-0.20211101221916-cabfb018fe85/go.mod h1:NzVQi3Mleb+qzq8VmcWpSkcSYxXIg0DkI6XDzpVkhJ0= +github.com/tailscale/netlink v1.1.1-0.20240822203006-4d49adab4de7 h1:uFsXVBE9Qr4ZoF094vE6iYTLDl0qCiKzYXlL6UeWObU= +github.com/tailscale/netlink v1.1.1-0.20240822203006-4d49adab4de7/go.mod h1:NzVQi3Mleb+qzq8VmcWpSkcSYxXIg0DkI6XDzpVkhJ0= github.com/tailscale/peercred v0.0.0-20240214030740-b535050b2aa4 h1:Gz0rz40FvFVLTBk/K8UNAenb36EbDSnh+q7Z9ldcC8w= github.com/tailscale/peercred v0.0.0-20240214030740-b535050b2aa4/go.mod h1:phI29ccmHQBc+wvroosENp1IF9195449VDnFDhJ4rJU= github.com/tailscale/web-client-prebuilt v0.0.0-20240226180453-5db17b287bf1 h1:tdUdyPqJ0C97SJfjB9tW6EylTtreyee9C44de+UBG0g= diff --git a/tstest/natlab/vnet/vnet.go b/tstest/natlab/vnet/vnet.go index 4569180bc..d8696206b 100644 --- a/tstest/natlab/vnet/vnet.go +++ b/tstest/natlab/vnet/vnet.go @@ -276,27 +276,6 @@ func (n *network) acceptTCP(r *tcp.ForwarderRequest) { return } - if destPort == 124 { - node, ok := n.nodesByIP[clientRemoteIP] - if !ok { - log.Printf("no node for TCP 124 connection from %v", clientRemoteIP) - r.Complete(true) - return - } - r.Complete(false) - tc := gonet.NewTCPConn(&wq, ep) - - go func() { - defer tc.Close() - bs := bufio.NewScanner(tc) - for bs.Scan() { - line := bs.Text() - log.Printf("LOG from %v: %s", node, line) - } - }() - return - } - if destPort == 8008 && destIP == fakeTestAgentIP { r.Complete(false) tc := gonet.NewTCPConn(&wq, ep) @@ -1278,7 +1257,9 @@ func (s *Server) shouldInterceptTCP(pkt gopacket.Packet) bool { if !ok { return false } - if tcp.DstPort == 123 || tcp.DstPort == 124 { + if tcp.DstPort == 123 { + // Test port for TCP interception. Not really useful, but cute for + // demos. return true } dstIP, _ := netip.AddrFromSlice(ipv4.DstIP.To4())