ipn,ipn/local: always accept routes for Tailscale Services (cgnat range) (#18173)
Updates #18198 Signed-off-by: chaosinthecrd <tom@tmlabs.co.uk> Co-authored-by: James Tucker <raggi@tailscale.com>
This commit is contained in:
@@ -5383,7 +5383,7 @@ func magicDNSRootDomains(nm *netmap.NetworkMap) []dnsname.FQDN {
|
|||||||
// peerRoutes returns the routerConfig.Routes to access peers.
|
// peerRoutes returns the routerConfig.Routes to access peers.
|
||||||
// If there are over cgnatThreshold CGNAT routes, one big CGNAT route
|
// If there are over cgnatThreshold CGNAT routes, one big CGNAT route
|
||||||
// is used instead.
|
// is used instead.
|
||||||
func peerRoutes(logf logger.Logf, peers []wgcfg.Peer, cgnatThreshold int) (routes []netip.Prefix) {
|
func peerRoutes(logf logger.Logf, peers []wgcfg.Peer, cgnatThreshold int, routeAll bool) (routes []netip.Prefix) {
|
||||||
tsULA := tsaddr.TailscaleULARange()
|
tsULA := tsaddr.TailscaleULARange()
|
||||||
cgNAT := tsaddr.CGNATRange()
|
cgNAT := tsaddr.CGNATRange()
|
||||||
var didULA bool
|
var didULA bool
|
||||||
@@ -5413,7 +5413,7 @@ func peerRoutes(logf logger.Logf, peers []wgcfg.Peer, cgnatThreshold int) (route
|
|||||||
}
|
}
|
||||||
if aip.IsSingleIP() && cgNAT.Contains(aip.Addr()) {
|
if aip.IsSingleIP() && cgNAT.Contains(aip.Addr()) {
|
||||||
cgNATIPs = append(cgNATIPs, aip)
|
cgNATIPs = append(cgNATIPs, aip)
|
||||||
} else {
|
} else if routeAll {
|
||||||
routes = append(routes, aip)
|
routes = append(routes, aip)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5461,7 +5461,7 @@ func (b *LocalBackend) routerConfigLocked(cfg *wgcfg.Config, prefs ipn.PrefsView
|
|||||||
SNATSubnetRoutes: !prefs.NoSNAT(),
|
SNATSubnetRoutes: !prefs.NoSNAT(),
|
||||||
StatefulFiltering: doStatefulFiltering,
|
StatefulFiltering: doStatefulFiltering,
|
||||||
NetfilterMode: prefs.NetfilterMode(),
|
NetfilterMode: prefs.NetfilterMode(),
|
||||||
Routes: peerRoutes(b.logf, cfg.Peers, singleRouteThreshold),
|
Routes: peerRoutes(b.logf, cfg.Peers, singleRouteThreshold, prefs.RouteAll()),
|
||||||
NetfilterKind: netfilterKind,
|
NetfilterKind: netfilterKind,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+103
-1
@@ -306,7 +306,7 @@ func TestPeerRoutes(t *testing.T) {
|
|||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
got := peerRoutes(t.Logf, tt.peers, 2)
|
got := peerRoutes(t.Logf, tt.peers, 2, true)
|
||||||
if !reflect.DeepEqual(got, tt.want) {
|
if !reflect.DeepEqual(got, tt.want) {
|
||||||
t.Errorf("got = %v; want %v", got, tt.want)
|
t.Errorf("got = %v; want %v", got, tt.want)
|
||||||
}
|
}
|
||||||
@@ -7295,3 +7295,105 @@ func TestStripKeysFromPrefs(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRouteAllDisabled(t *testing.T) {
|
||||||
|
pp := netip.MustParsePrefix
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
peers []wgcfg.Peer
|
||||||
|
wantEndpoints []netip.Prefix
|
||||||
|
routeAll bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "route_all_disabled",
|
||||||
|
routeAll: false,
|
||||||
|
peers: []wgcfg.Peer{
|
||||||
|
{
|
||||||
|
AllowedIPs: []netip.Prefix{
|
||||||
|
// if one ip in the Tailscale ULA range is added, the entire range is added to the router config
|
||||||
|
pp("fd7a:115c:a1e0::2501:9b83/128"),
|
||||||
|
pp("100.80.207.38/32"),
|
||||||
|
pp("100.80.207.56/32"),
|
||||||
|
pp("100.80.207.40/32"),
|
||||||
|
pp("100.94.122.93/32"),
|
||||||
|
pp("100.79.141.115/32"),
|
||||||
|
|
||||||
|
// a /28 range will not be added, since this is not a Service IP range (which is always /32, a single IP)
|
||||||
|
pp("100.64.0.0/28"),
|
||||||
|
|
||||||
|
// ips outside the tailscale cgnat/ula range are not added to the router config
|
||||||
|
pp("192.168.0.45/32"),
|
||||||
|
pp("fd7a:115c:b1e0::2501:9b83/128"),
|
||||||
|
pp("fdf8:f966:e27c:0:5:0:0:10/128"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantEndpoints: []netip.Prefix{
|
||||||
|
pp("100.80.207.38/32"),
|
||||||
|
pp("100.80.207.56/32"),
|
||||||
|
pp("100.80.207.40/32"),
|
||||||
|
pp("100.94.122.93/32"),
|
||||||
|
pp("100.79.141.115/32"),
|
||||||
|
pp("fd7a:115c:a1e0::/48"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "route_all_enabled",
|
||||||
|
routeAll: true,
|
||||||
|
peers: []wgcfg.Peer{
|
||||||
|
{
|
||||||
|
AllowedIPs: []netip.Prefix{
|
||||||
|
// if one ip in the Tailscale ULA range is added, the entire range is added to the router config
|
||||||
|
pp("fd7a:115c:a1e0::2501:9b83/128"),
|
||||||
|
pp("100.80.207.38/32"),
|
||||||
|
pp("100.80.207.56/32"),
|
||||||
|
pp("100.80.207.40/32"),
|
||||||
|
pp("100.94.122.93/32"),
|
||||||
|
pp("100.79.141.115/32"),
|
||||||
|
|
||||||
|
// ips outside the tailscale cgnat/ula range are not added to the router config
|
||||||
|
pp("192.168.0.45/32"),
|
||||||
|
pp("fd7a:115c:b1e0::2501:9b83/128"),
|
||||||
|
pp("fdf8:f966:e27c:0:5:0:0:10/128"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantEndpoints: []netip.Prefix{
|
||||||
|
pp("100.80.207.38/32"),
|
||||||
|
pp("100.80.207.56/32"),
|
||||||
|
pp("100.80.207.40/32"),
|
||||||
|
pp("100.94.122.93/32"),
|
||||||
|
pp("100.79.141.115/32"),
|
||||||
|
pp("192.168.0.45/32"),
|
||||||
|
pp("fd7a:115c:a1e0::/48"),
|
||||||
|
pp("fd7a:115c:b1e0::2501:9b83/128"),
|
||||||
|
pp("fdf8:f966:e27c:0:5:0:0:10/128"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
prefs := ipn.Prefs{RouteAll: tt.routeAll}
|
||||||
|
lb := newTestLocalBackend(t)
|
||||||
|
cfg := &wgcfg.Config{
|
||||||
|
Peers: tt.peers,
|
||||||
|
}
|
||||||
|
|
||||||
|
rcfg := lb.routerConfigLocked(cfg, prefs.View(), false)
|
||||||
|
for _, p := range rcfg.Routes {
|
||||||
|
found := false
|
||||||
|
for _, r := range tt.wantEndpoints {
|
||||||
|
if p.Addr() == r.Addr() {
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
t.Errorf("unexpected prefix %q in router config", p.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"tailscale.com/net/tsaddr"
|
||||||
"tailscale.com/tailcfg"
|
"tailscale.com/tailcfg"
|
||||||
"tailscale.com/tka"
|
"tailscale.com/tka"
|
||||||
"tailscale.com/types/key"
|
"tailscale.com/types/key"
|
||||||
@@ -154,8 +155,11 @@ func (nm *NetworkMap) SelfNodeOrZero() tailcfg.NodeView {
|
|||||||
// AnyPeersAdvertiseRoutes reports whether any peer is advertising non-exit node routes.
|
// AnyPeersAdvertiseRoutes reports whether any peer is advertising non-exit node routes.
|
||||||
func (nm *NetworkMap) AnyPeersAdvertiseRoutes() bool {
|
func (nm *NetworkMap) AnyPeersAdvertiseRoutes() bool {
|
||||||
for _, p := range nm.Peers {
|
for _, p := range nm.Peers {
|
||||||
if p.PrimaryRoutes().Len() > 0 {
|
// NOTE: (ChaosInTheCRD) if the peer being advertised is a tailscale ip, we ignore it in this check
|
||||||
return true
|
for _, r := range p.PrimaryRoutes().All() {
|
||||||
|
if !tsaddr.IsTailscaleIP(r.Addr()) || !r.IsSingleIP() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import (
|
|||||||
"net/netip"
|
"net/netip"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"tailscale.com/net/tsaddr"
|
||||||
"tailscale.com/tailcfg"
|
"tailscale.com/tailcfg"
|
||||||
"tailscale.com/types/key"
|
"tailscale.com/types/key"
|
||||||
"tailscale.com/types/logger"
|
"tailscale.com/types/logger"
|
||||||
@@ -33,6 +34,9 @@ func cidrIsSubnet(node tailcfg.NodeView, cidr netip.Prefix) bool {
|
|||||||
if !cidr.IsSingleIP() {
|
if !cidr.IsSingleIP() {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
if tsaddr.IsTailscaleIP(cidr.Addr()) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
for _, selfCIDR := range node.Addresses().All() {
|
for _, selfCIDR := range node.Addresses().All() {
|
||||||
if cidr == selfCIDR {
|
if cidr == selfCIDR {
|
||||||
return false
|
return false
|
||||||
|
|||||||
Reference in New Issue
Block a user