feature/conn25: add packet filter allow functions
That will be able to be plugged into the hooks in wgengine/filter/filter.go to let connector packets flow. Fixes tailscale/corp#37144 Fixes tailscale/corp#37145 Signed-off-by: Fran Bull <fran@tailscale.com>
This commit is contained in:
@@ -27,6 +27,7 @@ import (
|
||||
"tailscale.com/ipn/ipnext"
|
||||
"tailscale.com/ipn/ipnlocal"
|
||||
"tailscale.com/net/dns"
|
||||
"tailscale.com/net/packet"
|
||||
"tailscale.com/net/tsaddr"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/types/appctype"
|
||||
@@ -499,6 +500,26 @@ func (c *client) ClientTransitIPForMagicIP(magicIP netip.Addr) (netip.Addr, erro
|
||||
return netip.Addr{}, ErrUnmappedMagicIP
|
||||
}
|
||||
|
||||
// linkLocalAllow returns true if the provided packet with a link-local Dst address has a
|
||||
// Dst that is one of our transit IPs, and false otherwise.
|
||||
// Tailscale's wireguard filters drop link-local unicast packets (see [wgengine/filter/filter.go])
|
||||
// but conn25 uses link-local addresses for transit IPs.
|
||||
// Let the filter know if this is one of our addresses and should be allowed.
|
||||
func (c *client) linkLocalAllow(p packet.Parsed) (bool, string) {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
ok := c.isKnownTransitIP(p.Dst.Addr())
|
||||
if ok {
|
||||
return true, packetFilterAllowReason
|
||||
}
|
||||
return false, ""
|
||||
}
|
||||
|
||||
func (c *client) isKnownTransitIP(tip netip.Addr) bool {
|
||||
_, ok := c.assignments.lookupByTransitIP(tip)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (c *client) isConfigured() bool {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
@@ -863,6 +884,20 @@ func (c *connector) ConnectorRealIPForTransitIPConnection(srcIP netip.Addr, tran
|
||||
return netip.Addr{}, ErrUnmappedSrcAndTransitIP
|
||||
}
|
||||
|
||||
const packetFilterAllowReason = "app connector transit IP"
|
||||
|
||||
// packetFilterAllow returns true if the provided packet has a Src that maps to a peer
|
||||
// that has a transit IP with us that is the packet Dst, and false otherwise.
|
||||
func (c *connector) packetFilterAllow(p packet.Parsed) (bool, string) {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
_, ok := c.lookupBySrcIPAndTransitIP(p.Src.Addr(), p.Dst.Addr())
|
||||
if ok {
|
||||
return true, packetFilterAllowReason
|
||||
}
|
||||
return false, ""
|
||||
}
|
||||
|
||||
func (c *connector) lookupBySrcIPAndTransitIP(srcIP, transitIP netip.Addr) (appAddr, bool) {
|
||||
m, ok := c.transitIPs[srcIP]
|
||||
if !ok || m == nil {
|
||||
@@ -899,9 +934,10 @@ type domainDst struct {
|
||||
}
|
||||
|
||||
// addrAssignments is the collection of addrs assigned by this client
|
||||
// supporting lookup by magicip or domain+dst
|
||||
// supporting lookup by magic IP, transit IP or domain+dst
|
||||
type addrAssignments struct {
|
||||
byMagicIP map[netip.Addr]addrs
|
||||
byTransitIP map[netip.Addr]addrs
|
||||
byDomainDst map[domainDst]addrs
|
||||
}
|
||||
|
||||
@@ -915,7 +951,11 @@ func (a *addrAssignments) insert(as addrs) error {
|
||||
if _, ok := a.byDomainDst[ddst]; ok {
|
||||
return errors.New("byDomainDst key exists")
|
||||
}
|
||||
if _, ok := a.byTransitIP[as.transit]; ok {
|
||||
return errors.New("byTransitIP key exists")
|
||||
}
|
||||
mak.Set(&a.byMagicIP, as.magic, as)
|
||||
mak.Set(&a.byTransitIP, as.transit, as)
|
||||
mak.Set(&a.byDomainDst, ddst, as)
|
||||
return nil
|
||||
}
|
||||
@@ -929,3 +969,8 @@ func (a *addrAssignments) lookupByMagicIP(mip netip.Addr) (addrs, bool) {
|
||||
v, ok := a.byMagicIP[mip]
|
||||
return v, ok
|
||||
}
|
||||
|
||||
func (a *addrAssignments) lookupByTransitIP(tip netip.Addr) (addrs, bool) {
|
||||
v, ok := a.byTransitIP[tip]
|
||||
return v, ok
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user