mirror of
https://github.com/tailscale/tailscale.git
synced 2025-04-16 03:31:39 +00:00
tsnet: only intercept TCP flows that have listeners
Previously, it would accept all TCP connections and then close the ones it did not care about. Make it only ever accept the connections that it cares about. Signed-off-by: Maisem Ali <maisem@tailscale.com>
This commit is contained in:
parent
c09578d060
commit
b0cb39cda1
@ -491,7 +491,7 @@ func (s *Server) start() (reterr error) {
|
|||||||
return fmt.Errorf("netstack.Create: %w", err)
|
return fmt.Errorf("netstack.Create: %w", err)
|
||||||
}
|
}
|
||||||
ns.ProcessLocalIPs = true
|
ns.ProcessLocalIPs = true
|
||||||
ns.ForwardTCPIn = s.forwardTCP
|
ns.GetTCPHandlerForFlow = s.getTCPHandlerForFlow
|
||||||
ns.GetUDPHandlerForFlow = s.getUDPHandlerForFlow
|
ns.GetUDPHandlerForFlow = s.getUDPHandlerForFlow
|
||||||
s.netstack = ns
|
s.netstack = ns
|
||||||
s.dialer.UseNetstackForIP = func(ip netip.Addr) bool {
|
s.dialer.UseNetstackForIP = func(ip netip.Addr) bool {
|
||||||
@ -660,20 +660,12 @@ func (s *Server) listenerForDstAddr(netBase string, dst netip.AddrPort) (_ *list
|
|||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) forwardTCP(c net.Conn, port uint16) {
|
func (s *Server) getTCPHandlerForFlow(src, dst netip.AddrPort) (handler func(net.Conn), intercept bool) {
|
||||||
dstStr := c.LocalAddr().String()
|
ln, ok := s.listenerForDstAddr("tcp", dst)
|
||||||
ap, err := netip.ParseAddrPort(dstStr)
|
|
||||||
if err != nil {
|
|
||||||
s.logf("unexpected dst addr %q", dstStr)
|
|
||||||
c.Close()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ln, ok := s.listenerForDstAddr("tcp", ap)
|
|
||||||
if !ok {
|
if !ok {
|
||||||
c.Close()
|
return nil, true // don't handle, don't forward to localhost
|
||||||
return
|
|
||||||
}
|
}
|
||||||
ln.handle(c)
|
return ln.handle, true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) getUDPHandlerForFlow(src, dst netip.AddrPort) (handler func(nettype.ConnPacketConn), intercept bool) {
|
func (s *Server) getUDPHandlerForFlow(src, dst netip.AddrPort) (handler func(nettype.ConnPacketConn), intercept bool) {
|
||||||
|
@ -175,6 +175,11 @@ func TestConn(t *testing.T) {
|
|||||||
if string(got) != want {
|
if string(got) != want {
|
||||||
t.Errorf("got %q, want %q", got, want)
|
t.Errorf("got %q, want %q", got, want)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_, err = s2.Dial(ctx, "tcp", fmt.Sprintf("%s:8082", s1ip)) // some random port
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("unexpected success; should have seen a connection refused error")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestLoopbackLocalAPI(t *testing.T) {
|
func TestLoopbackLocalAPI(t *testing.T) {
|
||||||
|
@ -79,12 +79,18 @@ func init() {
|
|||||||
// and implements wgengine.FakeImpl to act as a userspace network
|
// and implements wgengine.FakeImpl to act as a userspace network
|
||||||
// stack when Tailscale is running in fake mode.
|
// stack when Tailscale is running in fake mode.
|
||||||
type Impl struct {
|
type Impl struct {
|
||||||
// ForwardTCPIn, if non-nil, handles forwarding an inbound TCP connection.
|
// GetTCPHandlerForFlow conditionally handles an incoming TCP flow for the
|
||||||
|
// provided (src/port, dst/port) 4-tuple.
|
||||||
//
|
//
|
||||||
// TODO(bradfitz): convert this to the GetUDPHandlerForFlow pattern below to
|
// A nil value is equivalent to a func returning (nil, false).
|
||||||
// provide mechanism for tsnet to reject a port other than accepting it and
|
//
|
||||||
// closing it.
|
// If func returns intercept=false, the default forwarding behavior (if
|
||||||
ForwardTCPIn func(c net.Conn, port uint16)
|
// ProcessLocalIPs and/or ProcesssSubnetIPs) takes place.
|
||||||
|
//
|
||||||
|
// When intercept=true, the behavior depends on whether the returned handler
|
||||||
|
// is non-nil: if nil, the connection is rejected. If non-nil, handler takes
|
||||||
|
// over the TCP conn.
|
||||||
|
GetTCPHandlerForFlow func(src, dst netip.AddrPort) (handler func(net.Conn), intercept bool)
|
||||||
|
|
||||||
// GetUDPHandlerForFlow conditionally handles an incoming UDP flow for the
|
// GetUDPHandlerForFlow conditionally handles an incoming UDP flow for the
|
||||||
// provided (src/port, dst/port) 4-tuple.
|
// provided (src/port, dst/port) 4-tuple.
|
||||||
@ -795,6 +801,8 @@ func (ns *Impl) acceptTCP(r *tcp.ForwarderRequest) {
|
|||||||
dialIP := netaddrIPFromNetstackIP(reqDetails.LocalAddress)
|
dialIP := netaddrIPFromNetstackIP(reqDetails.LocalAddress)
|
||||||
isTailscaleIP := tsaddr.IsTailscaleIP(dialIP)
|
isTailscaleIP := tsaddr.IsTailscaleIP(dialIP)
|
||||||
|
|
||||||
|
dstAddrPort := netip.AddrPortFrom(dialIP, reqDetails.LocalPort)
|
||||||
|
|
||||||
if viaRange.Contains(dialIP) {
|
if viaRange.Contains(dialIP) {
|
||||||
isTailscaleIP = false
|
isTailscaleIP = false
|
||||||
dialIP = tsaddr.UnmapVia(dialIP)
|
dialIP = tsaddr.UnmapVia(dialIP)
|
||||||
@ -913,14 +921,21 @@ func (ns *Impl) acceptTCP(r *tcp.ForwarderRequest) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ns.ForwardTCPIn != nil {
|
if ns.GetTCPHandlerForFlow != nil {
|
||||||
c := createConn()
|
handler, ok := ns.GetTCPHandlerForFlow(clientRemoteAddrPort, dstAddrPort)
|
||||||
|
if ok {
|
||||||
|
if handler == nil {
|
||||||
|
r.Complete(true)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c := createConn() // will send a RST if it fails
|
||||||
if c == nil {
|
if c == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ns.ForwardTCPIn(c, reqDetails.LocalPort)
|
handler(c)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if isTailscaleIP {
|
if isTailscaleIP {
|
||||||
dialIP = netaddr.IPv4(127, 0, 0, 1)
|
dialIP = netaddr.IPv4(127, 0, 0, 1)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user