mirror of
https://github.com/juanfont/headscale.git
synced 2026-11-04 04:34:07 +09:00
policyutil: send a router no capability for its subnet
via-grant-v84 and v86 show SaaS sending none. Updates #3626
This commit is contained in:
1 parent
3fdedefbf9
commit
aa7b2ab404
2 files changed
+12
-46
No files matched your search
@@ -131,7 +131,9 @@ func destinationNeedsOwnAddressExpansion(
|
||||
// [tailcfg.CapGrant] entries whose Dsts match the given node's IPs. When a
|
||||
// broad prefix (e.g. 100.64.0.0/10 from dst:*) contains a node's IP, it is
|
||||
// narrowed to the node's specific /32 or /128 prefix. Returns nil if
|
||||
// no [tailcfg.CapGrant] entries are relevant to this node.
|
||||
// no [tailcfg.CapGrant] entries are relevant to this node. A destination the
|
||||
// node only routes is not relevant: via-grant-v84 and v86 show SaaS sending a
|
||||
// router no capability for its subnet.
|
||||
func reduceCapGrantRule(
|
||||
node types.NodeView,
|
||||
rule tailcfg.FilterRule,
|
||||
@@ -139,7 +141,6 @@ func reduceCapGrantRule(
|
||||
var capGrants []tailcfg.CapGrant
|
||||
|
||||
nodeIPs := node.IPs()
|
||||
subnetRoutes := node.SubnetRoutes()
|
||||
|
||||
for _, cg := range rule.CapGrant {
|
||||
// Collect the node's IPs that fall within any of this
|
||||
@@ -164,27 +165,9 @@ func reduceCapGrantRule(
|
||||
}
|
||||
}
|
||||
|
||||
// Asymmetric on purpose: the IP-match loop above narrows broad
|
||||
// prefixes to node-specific /32 or /128 so peers receive only
|
||||
// the minimum routing surface. The route-match loop below
|
||||
// preserves the original prefix so the subnet-serving node
|
||||
// receives the full CapGrant scope. [types.NodeView.SubnetRoutes]
|
||||
// excludes both unapproved and exit routes, matching Tailscale
|
||||
// SaaS behavior.
|
||||
for _, dst := range cg.Dsts {
|
||||
for _, subnetRoute := range subnetRoutes {
|
||||
if dst.Overlaps(subnetRoute) {
|
||||
// For route overlaps, keep the original prefix.
|
||||
matchingDsts = append(matchingDsts, dst)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(matchingDsts) > 0 {
|
||||
// A Dst can be appended twice when a broad prefix both
|
||||
// contains a node IP and overlaps one of its approved
|
||||
// subnet routes. Sort + Compact dedups; [netip.Prefix] is
|
||||
// comparable so Compact works with ==.
|
||||
// Several Dsts can narrow to the same node IP. Sort + Compact
|
||||
// dedups; [netip.Prefix] is comparable so Compact works with ==.
|
||||
slices.SortFunc(matchingDsts, netip.Prefix.Compare)
|
||||
matchingDsts = slices.Compact(matchingDsts)
|
||||
|
||||
|
||||
@@ -1072,25 +1072,9 @@ func TestReduceFilterRulesCapGrant(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
want: []tailcfg.FilterRule{
|
||||
{
|
||||
SrcIPs: []string{"*"},
|
||||
CapGrant: []tailcfg.CapGrant{
|
||||
{
|
||||
Dsts: []netip.Prefix{
|
||||
// 10.0.0.0/8 doesn't contain node's
|
||||
// CGNAT IP (100.64.0.1), so no IP
|
||||
// narrowing. Only route overlap kept
|
||||
// as original prefix.
|
||||
netip.MustParsePrefix("10.0.0.0/8"),
|
||||
},
|
||||
CapMap: tailcfg.PeerCapMap{
|
||||
"tailscale.com/cap/relay-target": nil,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
// 10.0.0.0/8 doesn't contain the node's CGNAT IP (100.64.0.1),
|
||||
// and routing part of it delivers no capability.
|
||||
want: []tailcfg.FilterRule{},
|
||||
},
|
||||
{
|
||||
name: "capgrant-exit-route-skipped",
|
||||
@@ -1264,10 +1248,9 @@ func TestReduceFilterRulesCapGrant(t *testing.T) {
|
||||
want: []tailcfg.FilterRule{},
|
||||
},
|
||||
{
|
||||
// A broad prefix that both contains the node IP (/32 narrow)
|
||||
// and overlaps one of its approved subnet routes (route
|
||||
// preserved) would otherwise be emitted twice.
|
||||
name: "capgrant-ip-and-route-overlap-dedup",
|
||||
// Broad prefixes that contain the node IP narrow to the same
|
||||
// /32, and routing them keeps nothing more.
|
||||
name: "capgrant-broad-dsts-narrow-once",
|
||||
node: &types.Node{
|
||||
IPv4: ap("100.64.0.1"),
|
||||
IPv6: ap("fd7a:115c:a1e0::1"),
|
||||
@@ -1287,6 +1270,7 @@ func TestReduceFilterRulesCapGrant(t *testing.T) {
|
||||
{
|
||||
Dsts: []netip.Prefix{
|
||||
netip.MustParsePrefix("100.64.0.0/24"),
|
||||
netip.MustParsePrefix("100.64.0.0/16"),
|
||||
},
|
||||
CapMap: tailcfg.PeerCapMap{
|
||||
"tailscale.com/cap/relay-target": nil,
|
||||
@@ -1302,7 +1286,6 @@ func TestReduceFilterRulesCapGrant(t *testing.T) {
|
||||
{
|
||||
Dsts: []netip.Prefix{
|
||||
netip.MustParsePrefix("100.64.0.1/32"),
|
||||
netip.MustParsePrefix("100.64.0.0/24"),
|
||||
},
|
||||
CapMap: tailcfg.PeerCapMap{
|
||||
"tailscale.com/cap/relay-target": nil,
|
||||
|
||||
Reference in new issue
Block a user