diff --git a/ipn/ipnlocal/local.go b/ipn/ipnlocal/local.go index 73fa56c18..de3bb1268 100644 --- a/ipn/ipnlocal/local.go +++ b/ipn/ipnlocal/local.go @@ -6891,13 +6891,16 @@ func (b *LocalBackend) ShouldInterceptTCPPort(port uint16) bool { // ShouldInterceptVIPServiceTCPPort reports whether the given TCP port number // to a VIP service should be intercepted by Tailscaled and handled in-process. func (b *LocalBackend) ShouldInterceptVIPServiceTCPPort(ap netip.AddrPort) bool { + fmt.Println(" ShouldInterceptVIPServiceTCPPort: called for", ap) if !buildfeatures.HasServe { return false } f := b.shouldInterceptVIPServicesTCPPortAtomic.Load() if f == nil { + fmt.Println(" ShouldInterceptVIPServiceTCPPort: no intercepts configured, returning false") return false } + fmt.Println(" ShouldInterceptVIPServiceTCPPort: returning", f(ap)) return f(ap) } diff --git a/ipn/ipnlocal/serve.go b/ipn/ipnlocal/serve.go index 69a68f66e..2c05a41db 100644 --- a/ipn/ipnlocal/serve.go +++ b/ipn/ipnlocal/serve.go @@ -419,16 +419,20 @@ func (b *LocalBackend) HandleIngressTCPConn(ingressPeer tailcfg.NodeView, target sc := b.serveConfig b.mu.Unlock() + fmt.Println(" handleIngress: target:", target) + // TODO(maisem,bradfitz): make this not alloc for every conn. logf := logger.WithPrefix(b.logf, "handleIngress: ") if !sc.Valid() { + fmt.Println(" handleIngress: no serveConfig") logf("got ingress conn w/o serveConfig; rejecting") sendRST() return } if !sc.HasFunnelForTarget(target) { + fmt.Println(" handleIngress: no funnel config") logf("got ingress conn for unconfigured %q; rejecting", target) sendRST() return @@ -436,12 +440,14 @@ func (b *LocalBackend) HandleIngressTCPConn(ingressPeer tailcfg.NodeView, target host, port, err := net.SplitHostPort(string(target)) if err != nil { + fmt.Println(" handleIngress: bag target 1") logf("got ingress conn for bad target %q; rejecting", target) sendRST() return } port16, err := strconv.ParseUint(port, 10, 16) if err != nil { + fmt.Println(" handleIngress: bad target 2") logf("got ingress conn for bad target %q; rejecting", target) sendRST() return @@ -452,9 +458,11 @@ func (b *LocalBackend) HandleIngressTCPConn(ingressPeer tailcfg.NodeView, target if handler != nil { c, ok := getConnOrReset() if !ok { + fmt.Println(" handleIngress: getTCPHandlerForFunnelFlow: getConn error") logf("getConn didn't complete from %v to port %v", srcAddr, dport) return } + fmt.Println(" handleIngress: getTCPHandlerForFunnelFlow: handling") handler(c) return } @@ -464,15 +472,18 @@ func (b *LocalBackend) HandleIngressTCPConn(ingressPeer tailcfg.NodeView, target IngressPeer: ingressPeer, }) if handler == nil { + fmt.Println(" handleIngress: no TCP handler for serve") logf("[unexpected] no matching ingress serve handler for %v to port %v", srcAddr, dport) sendRST() return } c, ok := getConnOrReset() if !ok { + fmt.Println(" handleIngress: getConnOrReset err") logf("getConn didn't complete from %v to port %v", srcAddr, dport) return } + fmt.Println(" handleIngress: handling") handler(c) } @@ -1379,6 +1390,8 @@ func handleServeIngress(ph PeerAPIHandler, w http.ResponseWriter, r *http.Reques h := ph.(*peerAPIHandler) metricIngressCalls.Add(1) + fmt.Println(" handleServeIngress called") + // http.Errors only useful if hitting endpoint manually // otherwise rely on log lines when debugging ingress connections // as connection is hijacked for bidi and is encrypted tls @@ -1409,11 +1422,14 @@ func handleServeIngress(ph PeerAPIHandler, w http.ResponseWriter, r *http.Reques return } target := ipn.HostPort(r.Header.Get("Tailscale-Ingress-Target")) + fmt.Println(" handleServeIngress: target:", target) if target == "" { + fmt.Println(" handleServeIngress: target not set") bad("Tailscale-Ingress-Target header not set") return } if _, _, err := net.SplitHostPort(string(target)); err != nil { + fmt.Println(" handleServeIngress: target invalid") bad("Tailscale-Ingress-Target header invalid; want host:port") return } @@ -1552,6 +1568,7 @@ func (b *LocalBackend) setVIPServicesTCPPortsInterceptedLocked(svcPorts map[tail b.shouldInterceptVIPServicesTCPPortAtomic.Store(func(netip.AddrPort) bool { return false }) return } + fmt.Println(" setVIPServicesTCPPortsInterceptedLocked: hostname:", b.currentNode().Self().Hostinfo().Hostname()) nm := b.currentNode().NetMap() if nm == nil { b.logf("can't set intercept function for Service TCP Ports, netMap is nil") @@ -1559,6 +1576,7 @@ func (b *LocalBackend) setVIPServicesTCPPortsInterceptedLocked(svcPorts map[tail } vipServiceIPMap := nm.GetVIPServiceIPMap() if len(vipServiceIPMap) == 0 { + fmt.Println(" setVIPServicesTCPPortsInterceptedLocked: no VIP service IP map, not setting intercepted ports") // No approved VIP Services return } @@ -1568,8 +1586,10 @@ func (b *LocalBackend) setVIPServicesTCPPortsInterceptedLocked(svcPorts map[tail for svcName, ports := range svcPorts { addrs, ok := vipServiceIPMap[svcName] if !ok { + fmt.Println(" setVIPServicesTCPPortsInterceptedLocked: no VIP service map entry for", svcName) continue } + fmt.Println(" setVIPServicesTCPPortsInterceptedLocked: generating intercept function for", svcName) interceptFn := generateInterceptTCPPortFunc(ports) for _, addr := range addrs { svcAddrPorts[addr] = interceptFn diff --git a/ipn/localapi/localapi.go b/ipn/localapi/localapi.go index 7f249fe53..c355167fa 100644 --- a/ipn/localapi/localapi.go +++ b/ipn/localapi/localapi.go @@ -984,6 +984,7 @@ func (h *Handler) serveLogout(w http.ResponseWriter, r *http.Request) { } func (h *Handler) servePrefs(w http.ResponseWriter, r *http.Request) { + fmt.Println(" servePrefs") if !h.PermitRead { http.Error(w, "prefs access denied", http.StatusForbidden) return @@ -991,6 +992,7 @@ func (h *Handler) servePrefs(w http.ResponseWriter, r *http.Request) { var prefs ipn.PrefsView switch r.Method { case httpm.PATCH: + fmt.Println(" servePrefs: PATCH") if !h.PermitWrite { http.Error(w, "prefs write access denied", http.StatusForbidden) return diff --git a/wgengine/netstack/netstack.go b/wgengine/netstack/netstack.go index c2b5d8a32..0f6cfbce0 100644 --- a/wgengine/netstack/netstack.go +++ b/wgengine/netstack/netstack.go @@ -1066,6 +1066,9 @@ func (ns *Impl) shouldProcessInbound(p *packet.Parsed, t *tstun.Wrapper) bool { isLocal := ns.isLocalIP(dstIP) isService := ns.isVIPServiceIP(dstIP) + fmt.Println(" shouldProcessInbound: called for target", dstIP) + fmt.Println(" shouldProcessInbound: isService:", isService) + // Handle TCP connection to the Tailscale IP(s) in some cases: if ns.lb != nil && p.IPProto == ipproto.TCP && isLocal { var peerAPIPort uint16 @@ -1095,6 +1098,7 @@ func (ns *Impl) shouldProcessInbound(p *packet.Parsed, t *tstun.Wrapper) bool { // An assumption holds for this to work: when tun mode is on for a service, // its tcp and web are not set. This is enforced in b.setServeConfigLocked. if ns.lb.ShouldInterceptVIPServiceTCPPort(p.Dst) { + fmt.Println(" shouldProcessInbound: intercepting packet for Service") return true } } @@ -1188,6 +1192,8 @@ func (ns *Impl) injectInbound(p *packet.Parsed, t *tstun.Wrapper, gro *gro.GRO) return filter.DropSilently, gro } + fmt.Println(" wgengine/netstack.injectInbound: for", p.Dst) + if !ns.shouldProcessInbound(p, t) { // Let the host network stack (if any) deal with it. return filter.Accept, gro