|
|
|
|
@ -44,6 +44,7 @@ import ( |
|
|
|
|
"tailscale.com/tsd" |
|
|
|
|
"tailscale.com/tstest" |
|
|
|
|
"tailscale.com/types/dnstype" |
|
|
|
|
"tailscale.com/types/ipproto" |
|
|
|
|
"tailscale.com/types/key" |
|
|
|
|
"tailscale.com/types/logger" |
|
|
|
|
"tailscale.com/types/logid" |
|
|
|
|
@ -60,6 +61,7 @@ import ( |
|
|
|
|
"tailscale.com/util/syspolicy/source" |
|
|
|
|
"tailscale.com/wgengine" |
|
|
|
|
"tailscale.com/wgengine/filter" |
|
|
|
|
"tailscale.com/wgengine/filter/filtertype" |
|
|
|
|
"tailscale.com/wgengine/wgcfg" |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
@ -5206,3 +5208,60 @@ func TestUpdateIngressLocked(t *testing.T) { |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// TestSrcCapPacketFilter tests that LocalBackend handles packet filters with
|
|
|
|
|
// SrcCaps instead of Srcs (IPs)
|
|
|
|
|
func TestSrcCapPacketFilter(t *testing.T) { |
|
|
|
|
lb := newLocalBackendWithTestControl(t, false, func(tb testing.TB, opts controlclient.Options) controlclient.Client { |
|
|
|
|
return newClient(tb, opts) |
|
|
|
|
}) |
|
|
|
|
if err := lb.Start(ipn.Options{}); err != nil { |
|
|
|
|
t.Fatalf("(*LocalBackend).Start(): %v", err) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var k key.NodePublic |
|
|
|
|
must.Do(k.UnmarshalText([]byte("nodekey:5c8f86d5fc70d924e55f02446165a5dae8f822994ad26bcf4b08fd841f9bf261"))) |
|
|
|
|
|
|
|
|
|
controlClient := lb.cc.(*mockControl) |
|
|
|
|
controlClient.send(nil, "", false, &netmap.NetworkMap{ |
|
|
|
|
SelfNode: (&tailcfg.Node{ |
|
|
|
|
Addresses: []netip.Prefix{netip.MustParsePrefix("1.1.1.1/32")}, |
|
|
|
|
}).View(), |
|
|
|
|
Peers: []tailcfg.NodeView{ |
|
|
|
|
(&tailcfg.Node{ |
|
|
|
|
Addresses: []netip.Prefix{netip.MustParsePrefix("2.2.2.2/32")}, |
|
|
|
|
ID: 2, |
|
|
|
|
Key: k, |
|
|
|
|
CapMap: tailcfg.NodeCapMap{"cap-X": nil}, // node 2 has cap
|
|
|
|
|
}).View(), |
|
|
|
|
(&tailcfg.Node{ |
|
|
|
|
Addresses: []netip.Prefix{netip.MustParsePrefix("3.3.3.3/32")}, |
|
|
|
|
ID: 3, |
|
|
|
|
Key: k, |
|
|
|
|
CapMap: tailcfg.NodeCapMap{}, // node 3 does not have the cap
|
|
|
|
|
}).View(), |
|
|
|
|
}, |
|
|
|
|
PacketFilter: []filtertype.Match{{ |
|
|
|
|
IPProto: views.SliceOf([]ipproto.Proto{ipproto.TCP}), |
|
|
|
|
SrcCaps: []tailcfg.NodeCapability{"cap-X"}, // cap in packet filter rule
|
|
|
|
|
Dsts: []filtertype.NetPortRange{{ |
|
|
|
|
Net: netip.MustParsePrefix("1.1.1.1/32"), |
|
|
|
|
Ports: filtertype.PortRange{ |
|
|
|
|
First: 22, |
|
|
|
|
Last: 22, |
|
|
|
|
}, |
|
|
|
|
}}, |
|
|
|
|
}}, |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
f := lb.GetFilterForTest() |
|
|
|
|
res := f.Check(netip.MustParseAddr("2.2.2.2"), netip.MustParseAddr("1.1.1.1"), 22, ipproto.TCP) |
|
|
|
|
if res != filter.Accept { |
|
|
|
|
t.Errorf("Check(2.2.2.2, ...) = %s, want %s", res, filter.Accept) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
res = f.Check(netip.MustParseAddr("3.3.3.3"), netip.MustParseAddr("1.1.1.1"), 22, ipproto.TCP) |
|
|
|
|
if !res.IsDrop() { |
|
|
|
|
t.Error("IsDrop() for node without cap = false, want true") |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|