mirror of
				https://github.com/juanfont/headscale.git
				synced 2025-10-28 10:51:44 +01:00 
			
		
		
		
	only send relevant filterrules to nodes
Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
This commit is contained in:
		
							parent
							
								
									1c9c472d2c
								
							
						
					
					
						commit
						bbaed461e1
					
				@ -125,122 +125,6 @@ func TestInvalidTagValidUser(t *testing.T) {
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestPortGroup(t *testing.T) {
 | 
			
		||||
	machine := types.Machine{
 | 
			
		||||
		ID:         0,
 | 
			
		||||
		MachineKey: "foo",
 | 
			
		||||
		NodeKey:    "bar",
 | 
			
		||||
		DiscoKey:   "faa",
 | 
			
		||||
		Hostname:   "testmachine",
 | 
			
		||||
		UserID:     0,
 | 
			
		||||
		User: types.User{
 | 
			
		||||
			Name: "testuser",
 | 
			
		||||
		},
 | 
			
		||||
		RegisterMethod: util.RegisterMethodAuthKey,
 | 
			
		||||
		IPAddresses:    types.MachineAddresses{netip.MustParseAddr("100.64.0.5")},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	acl := []byte(`
 | 
			
		||||
{
 | 
			
		||||
	"groups": {
 | 
			
		||||
		"group:example": [
 | 
			
		||||
			"testuser",
 | 
			
		||||
		],
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	"hosts": {
 | 
			
		||||
		"host-1": "100.100.100.100",
 | 
			
		||||
		"subnet-1": "100.100.101.100/24",
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	"acls": [
 | 
			
		||||
		{
 | 
			
		||||
			"action": "accept",
 | 
			
		||||
			"src": [
 | 
			
		||||
				"group:example",
 | 
			
		||||
			],
 | 
			
		||||
			"dst": [
 | 
			
		||||
				"host-1:*",
 | 
			
		||||
			],
 | 
			
		||||
		},
 | 
			
		||||
	],
 | 
			
		||||
}
 | 
			
		||||
	`)
 | 
			
		||||
	pol, err := policy.LoadACLPolicyFromBytes(acl, "hujson")
 | 
			
		||||
	assert.NoError(t, err)
 | 
			
		||||
 | 
			
		||||
	got, _, err := policy.GenerateFilterRules(pol, &machine, types.Machines{})
 | 
			
		||||
	assert.NoError(t, err)
 | 
			
		||||
 | 
			
		||||
	want := []tailcfg.FilterRule{
 | 
			
		||||
		{
 | 
			
		||||
			SrcIPs: []string{"100.64.0.5/32"},
 | 
			
		||||
			DstPorts: []tailcfg.NetPortRange{
 | 
			
		||||
				{IP: "100.100.100.100/32", Ports: tailcfg.PortRange{Last: 65535}},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if diff := cmp.Diff(want, got); diff != "" {
 | 
			
		||||
		t.Errorf("TestPortGroup() unexpected result (-want +got):\n%s", diff)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestPortUser(t *testing.T) {
 | 
			
		||||
	machine := types.Machine{
 | 
			
		||||
		ID:         0,
 | 
			
		||||
		MachineKey: "12345",
 | 
			
		||||
		NodeKey:    "bar",
 | 
			
		||||
		DiscoKey:   "faa",
 | 
			
		||||
		Hostname:   "testmachine",
 | 
			
		||||
		UserID:     0,
 | 
			
		||||
		User: types.User{
 | 
			
		||||
			Name: "testuser",
 | 
			
		||||
		},
 | 
			
		||||
		RegisterMethod: util.RegisterMethodAuthKey,
 | 
			
		||||
		IPAddresses:    types.MachineAddresses{netip.MustParseAddr("100.64.0.9")},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	acl := []byte(`
 | 
			
		||||
{
 | 
			
		||||
	"hosts": {
 | 
			
		||||
		"host-1": "100.100.100.100",
 | 
			
		||||
		"subnet-1": "100.100.101.100/24",
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	"acls": [
 | 
			
		||||
		{
 | 
			
		||||
			"action": "accept",
 | 
			
		||||
			"src": [
 | 
			
		||||
				"testuser",
 | 
			
		||||
			],
 | 
			
		||||
			"dst": [
 | 
			
		||||
				"host-1:*",
 | 
			
		||||
			],
 | 
			
		||||
		},
 | 
			
		||||
	],
 | 
			
		||||
}
 | 
			
		||||
	`)
 | 
			
		||||
	pol, err := policy.LoadACLPolicyFromBytes(acl, "hujson")
 | 
			
		||||
	assert.NoError(t, err)
 | 
			
		||||
 | 
			
		||||
	got, _, err := policy.GenerateFilterRules(pol, &machine, types.Machines{})
 | 
			
		||||
	assert.NoError(t, err)
 | 
			
		||||
 | 
			
		||||
	want := []tailcfg.FilterRule{
 | 
			
		||||
		{
 | 
			
		||||
			SrcIPs: []string{"100.64.0.9/32"},
 | 
			
		||||
			DstPorts: []tailcfg.NetPortRange{
 | 
			
		||||
				{IP: "100.100.100.100/32", Ports: tailcfg.PortRange{Last: 65535}},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if diff := cmp.Diff(want, got); diff != "" {
 | 
			
		||||
		t.Errorf("TestPortUser() unexpected result (-want +got):\n%s", diff)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// this test should validate that we can expand a group in a TagOWner section and
 | 
			
		||||
// match properly the IP's of the related hosts. The owner is valid and the tag is also valid.
 | 
			
		||||
// the tag is matched in the Destinations section.
 | 
			
		||||
 | 
			
		||||
@ -403,8 +403,8 @@ func Test_fullMapResponse(t *testing.T) {
 | 
			
		||||
				ACLs: []policy.ACL{
 | 
			
		||||
					{
 | 
			
		||||
						Action:       "accept",
 | 
			
		||||
						Sources:      []string{"mini"},
 | 
			
		||||
						Destinations: []string{"100.64.0.2:*"},
 | 
			
		||||
						Sources:      []string{"100.64.0.2"},
 | 
			
		||||
						Destinations: []string{"mini:*"},
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
@ -430,8 +430,9 @@ func Test_fullMapResponse(t *testing.T) {
 | 
			
		||||
				CollectServices: "false",
 | 
			
		||||
				PacketFilter: []tailcfg.FilterRule{
 | 
			
		||||
					{
 | 
			
		||||
						SrcIPs: []string{"100.64.0.1/32", "100.64.0.2/32"},
 | 
			
		||||
						SrcIPs: []string{"100.64.0.2/32"},
 | 
			
		||||
						DstPorts: []tailcfg.NetPortRange{
 | 
			
		||||
							{IP: "100.64.0.1/32", Ports: tailcfg.PortRangeAny},
 | 
			
		||||
							{IP: "100.64.0.2/32", Ports: tailcfg.PortRangeAny},
 | 
			
		||||
						},
 | 
			
		||||
					},
 | 
			
		||||
 | 
			
		||||
@ -177,7 +177,7 @@ func (pol *ACLPolicy) generateFilterRules(
 | 
			
		||||
			srcIPs = append(srcIPs, srcs...)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		protocols, needsWildcard, err := parseProtocol(acl.Protocol)
 | 
			
		||||
		protocols, isWildcard, err := parseProtocol(acl.Protocol)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			log.Error().
 | 
			
		||||
				Msgf("Error parsing ACL %d. protocol unknown %s", index, acl.Protocol)
 | 
			
		||||
@ -185,25 +185,52 @@ func (pol *ACLPolicy) generateFilterRules(
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		destPorts := []tailcfg.NetPortRange{}
 | 
			
		||||
		for destIndex, dest := range acl.Destinations {
 | 
			
		||||
			dests, err := pol.getNetPortRangeFromDestination(
 | 
			
		||||
				dest,
 | 
			
		||||
				machines,
 | 
			
		||||
				needsWildcard,
 | 
			
		||||
			)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				log.Error().
 | 
			
		||||
					Interface("dest", dest).
 | 
			
		||||
					Int("ACL index", index).
 | 
			
		||||
					Int("dest index", destIndex).
 | 
			
		||||
					Msgf("Error parsing ACL")
 | 
			
		||||
		// record if the rule is actually relevant for the given machine.
 | 
			
		||||
		isRelevant := false
 | 
			
		||||
 | 
			
		||||
		destPorts := []tailcfg.NetPortRange{}
 | 
			
		||||
		for _, dest := range acl.Destinations {
 | 
			
		||||
			alias, port, err := parseDestination(dest)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return nil, err
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			expanded, err := pol.ExpandAlias(
 | 
			
		||||
				machines,
 | 
			
		||||
				alias,
 | 
			
		||||
			)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return nil, err
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if machine.IPAddresses.InIPSet(expanded) {
 | 
			
		||||
				isRelevant = true
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			ports, err := expandPorts(port, isWildcard)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return nil, err
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			dests := []tailcfg.NetPortRange{}
 | 
			
		||||
			for _, dest := range expanded.Prefixes() {
 | 
			
		||||
				for _, port := range *ports {
 | 
			
		||||
					pr := tailcfg.NetPortRange{
 | 
			
		||||
						IP:    dest.String(),
 | 
			
		||||
						Ports: port,
 | 
			
		||||
					}
 | 
			
		||||
					dests = append(dests, pr)
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			destPorts = append(destPorts, dests...)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// if the rule does not apply to the machine we are evaluating,
 | 
			
		||||
		// do not add it to the list and continue.
 | 
			
		||||
		if !isRelevant {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		rules = append(rules, tailcfg.FilterRule{
 | 
			
		||||
			SrcIPs:   srcIPs,
 | 
			
		||||
			DstPorts: destPorts,
 | 
			
		||||
@ -368,44 +395,6 @@ func (pol *ACLPolicy) getIPsFromSource(
 | 
			
		||||
	return prefixes, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// getNetPortRangeFromDestination returns a set of tailcfg.NetPortRange
 | 
			
		||||
// which are associated with the dest alias.
 | 
			
		||||
func (pol *ACLPolicy) getNetPortRangeFromDestination(
 | 
			
		||||
	dest string,
 | 
			
		||||
	machines types.Machines,
 | 
			
		||||
	needsWildcard bool,
 | 
			
		||||
) ([]tailcfg.NetPortRange, error) {
 | 
			
		||||
	alias, port, err := parseDestination(dest)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	expanded, err := pol.ExpandAlias(
 | 
			
		||||
		machines,
 | 
			
		||||
		alias,
 | 
			
		||||
	)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	ports, err := expandPorts(port, needsWildcard)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dests := []tailcfg.NetPortRange{}
 | 
			
		||||
	for _, dest := range expanded.Prefixes() {
 | 
			
		||||
		for _, port := range *ports {
 | 
			
		||||
			pr := tailcfg.NetPortRange{
 | 
			
		||||
				IP:    dest.String(),
 | 
			
		||||
				Ports: port,
 | 
			
		||||
			}
 | 
			
		||||
			dests = append(dests, pr)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return dests, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func parseDestination(dest string) (string, string, error) {
 | 
			
		||||
	var tokens []string
 | 
			
		||||
 | 
			
		||||
@ -605,14 +594,14 @@ func excludeCorrectlyTaggedNodes(
 | 
			
		||||
	return out
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func expandPorts(portsStr string, needsWildcard bool) (*[]tailcfg.PortRange, error) {
 | 
			
		||||
func expandPorts(portsStr string, isWild bool) (*[]tailcfg.PortRange, error) {
 | 
			
		||||
	if isWildcard(portsStr) {
 | 
			
		||||
		return &[]tailcfg.PortRange{
 | 
			
		||||
			{First: portRangeBegin, Last: portRangeEnd},
 | 
			
		||||
		}, nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if needsWildcard {
 | 
			
		||||
	if isWild {
 | 
			
		||||
		return nil, ErrWildcardIsNeeded
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -30,42 +30,388 @@ func (s *Suite) TestWrongPath(c *check.C) {
 | 
			
		||||
	c.Assert(err, check.NotNil)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *Suite) TestBrokenHuJson(c *check.C) {
 | 
			
		||||
	acl := []byte(`
 | 
			
		||||
func TestParsing(t *testing.T) {
 | 
			
		||||
	tests := []struct {
 | 
			
		||||
		name    string
 | 
			
		||||
		format  string
 | 
			
		||||
		acl     string
 | 
			
		||||
		want    []tailcfg.FilterRule
 | 
			
		||||
		wantErr bool
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			name:   "invalid-hujson",
 | 
			
		||||
			format: "hujson",
 | 
			
		||||
			acl: `
 | 
			
		||||
{
 | 
			
		||||
	`)
 | 
			
		||||
	_, err := LoadACLPolicyFromBytes(acl, "hujson")
 | 
			
		||||
	c.Assert(err, check.NotNil)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *Suite) TestInvalidPolicyHuson(c *check.C) {
 | 
			
		||||
	acl := []byte(`
 | 
			
		||||
		`,
 | 
			
		||||
			want:    []tailcfg.FilterRule{},
 | 
			
		||||
			wantErr: true,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name:   "valid-hujson-invalid-content",
 | 
			
		||||
			format: "hujson",
 | 
			
		||||
			acl: `
 | 
			
		||||
{
 | 
			
		||||
	"valid_json": true,
 | 
			
		||||
	"but_a_policy_though": false
 | 
			
		||||
}
 | 
			
		||||
	`)
 | 
			
		||||
	_, err := LoadACLPolicyFromBytes(acl, "hujson")
 | 
			
		||||
	c.Assert(err, check.NotNil)
 | 
			
		||||
	c.Assert(err, check.Equals, ErrEmptyPolicy)
 | 
			
		||||
  "valid_json": true,
 | 
			
		||||
  "but_a_policy_though": false
 | 
			
		||||
}
 | 
			
		||||
				`,
 | 
			
		||||
			want:    []tailcfg.FilterRule{},
 | 
			
		||||
			wantErr: true,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name:   "invalid-cidr",
 | 
			
		||||
			format: "hujson",
 | 
			
		||||
			acl: `
 | 
			
		||||
{"example-host-1": "100.100.100.100/42"}
 | 
			
		||||
				`,
 | 
			
		||||
			want:    []tailcfg.FilterRule{},
 | 
			
		||||
			wantErr: true,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name:   "basic-rule",
 | 
			
		||||
			format: "hujson",
 | 
			
		||||
			acl: `
 | 
			
		||||
{
 | 
			
		||||
	"hosts": {
 | 
			
		||||
		"host-1": "100.100.100.100",
 | 
			
		||||
		"subnet-1": "100.100.101.100/24",
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
func (s *Suite) TestParseHosts(c *check.C) {
 | 
			
		||||
	var hosts Hosts
 | 
			
		||||
	err := hosts.UnmarshalJSON(
 | 
			
		||||
		[]byte(
 | 
			
		||||
			`{"example-host-1": "100.100.100.100","example-host-2": "100.100.101.100/24"}`,
 | 
			
		||||
		),
 | 
			
		||||
	)
 | 
			
		||||
	c.Assert(hosts, check.NotNil)
 | 
			
		||||
	c.Assert(err, check.IsNil)
 | 
			
		||||
	"acls": [
 | 
			
		||||
		{
 | 
			
		||||
			"action": "accept",
 | 
			
		||||
			"src": [
 | 
			
		||||
				"subnet-1",
 | 
			
		||||
				"192.168.1.0/24"
 | 
			
		||||
			],
 | 
			
		||||
			"dst": [
 | 
			
		||||
				"*:22,3389",
 | 
			
		||||
				"host-1:*",
 | 
			
		||||
			],
 | 
			
		||||
		},
 | 
			
		||||
	],
 | 
			
		||||
}
 | 
			
		||||
		`,
 | 
			
		||||
			want: []tailcfg.FilterRule{
 | 
			
		||||
				{
 | 
			
		||||
					SrcIPs: []string{"100.100.101.0/24", "192.168.1.0/24"},
 | 
			
		||||
					DstPorts: []tailcfg.NetPortRange{
 | 
			
		||||
						{IP: "0.0.0.0/0", Ports: tailcfg.PortRange{First: 22, Last: 22}},
 | 
			
		||||
						{IP: "0.0.0.0/0", Ports: tailcfg.PortRange{First: 3389, Last: 3389}},
 | 
			
		||||
						{IP: "::/0", Ports: tailcfg.PortRange{First: 22, Last: 22}},
 | 
			
		||||
						{IP: "::/0", Ports: tailcfg.PortRange{First: 3389, Last: 3389}},
 | 
			
		||||
						{IP: "100.100.100.100/32", Ports: tailcfg.PortRangeAny},
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			wantErr: false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name:   "parse-protocol",
 | 
			
		||||
			format: "hujson",
 | 
			
		||||
			acl: `
 | 
			
		||||
{
 | 
			
		||||
	"hosts": {
 | 
			
		||||
		"host-1": "100.100.100.100",
 | 
			
		||||
		"subnet-1": "100.100.101.100/24",
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
func (s *Suite) TestParseInvalidCIDR(c *check.C) {
 | 
			
		||||
	var hosts Hosts
 | 
			
		||||
	err := hosts.UnmarshalJSON([]byte(`{"example-host-1": "100.100.100.100/42"}`))
 | 
			
		||||
	c.Assert(hosts, check.IsNil)
 | 
			
		||||
	c.Assert(err, check.NotNil)
 | 
			
		||||
	"acls": [
 | 
			
		||||
		{
 | 
			
		||||
			"Action": "accept",
 | 
			
		||||
			"src": [
 | 
			
		||||
				"*",
 | 
			
		||||
			],
 | 
			
		||||
			"proto": "tcp",
 | 
			
		||||
			"dst": [
 | 
			
		||||
				"host-1:*",
 | 
			
		||||
			],
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"Action": "accept",
 | 
			
		||||
			"src": [
 | 
			
		||||
				"*",
 | 
			
		||||
			],
 | 
			
		||||
			"proto": "udp",
 | 
			
		||||
			"dst": [
 | 
			
		||||
				"host-1:53",
 | 
			
		||||
			],
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"Action": "accept",
 | 
			
		||||
			"src": [
 | 
			
		||||
				"*",
 | 
			
		||||
			],
 | 
			
		||||
			"proto": "icmp",
 | 
			
		||||
			"dst": [
 | 
			
		||||
				"host-1:*",
 | 
			
		||||
			],
 | 
			
		||||
		},
 | 
			
		||||
	],
 | 
			
		||||
}`,
 | 
			
		||||
			want: []tailcfg.FilterRule{
 | 
			
		||||
				{
 | 
			
		||||
					SrcIPs: []string{"0.0.0.0/0", "::/0"},
 | 
			
		||||
					DstPorts: []tailcfg.NetPortRange{
 | 
			
		||||
						{IP: "100.100.100.100/32", Ports: tailcfg.PortRangeAny},
 | 
			
		||||
					},
 | 
			
		||||
					IPProto: []int{protocolTCP},
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					SrcIPs: []string{"0.0.0.0/0", "::/0"},
 | 
			
		||||
					DstPorts: []tailcfg.NetPortRange{
 | 
			
		||||
						{IP: "100.100.100.100/32", Ports: tailcfg.PortRange{First: 53, Last: 53}},
 | 
			
		||||
					},
 | 
			
		||||
					IPProto: []int{protocolUDP},
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					SrcIPs: []string{"0.0.0.0/0", "::/0"},
 | 
			
		||||
					DstPorts: []tailcfg.NetPortRange{
 | 
			
		||||
						{IP: "100.100.100.100/32", Ports: tailcfg.PortRangeAny},
 | 
			
		||||
					},
 | 
			
		||||
					IPProto: []int{protocolICMP, protocolIPv6ICMP},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			wantErr: false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name:   "port-wildcard",
 | 
			
		||||
			format: "hujson",
 | 
			
		||||
			acl: `
 | 
			
		||||
{
 | 
			
		||||
	"hosts": {
 | 
			
		||||
		"host-1": "100.100.100.100",
 | 
			
		||||
		"subnet-1": "100.100.101.100/24",
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	"acls": [
 | 
			
		||||
		{
 | 
			
		||||
			"Action": "accept",
 | 
			
		||||
			"src": [
 | 
			
		||||
				"*",
 | 
			
		||||
			],
 | 
			
		||||
			"dst": [
 | 
			
		||||
				"host-1:*",
 | 
			
		||||
			],
 | 
			
		||||
		},
 | 
			
		||||
	],
 | 
			
		||||
}
 | 
			
		||||
`,
 | 
			
		||||
			want: []tailcfg.FilterRule{
 | 
			
		||||
				{
 | 
			
		||||
					SrcIPs: []string{"0.0.0.0/0", "::/0"},
 | 
			
		||||
					DstPorts: []tailcfg.NetPortRange{
 | 
			
		||||
						{IP: "100.100.100.100/32", Ports: tailcfg.PortRangeAny},
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			wantErr: false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name:   "port-range",
 | 
			
		||||
			format: "hujson",
 | 
			
		||||
			acl: `
 | 
			
		||||
{
 | 
			
		||||
	"hosts": {
 | 
			
		||||
		"host-1": "100.100.100.100",
 | 
			
		||||
		"subnet-1": "100.100.101.100/24",
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	"acls": [
 | 
			
		||||
		{
 | 
			
		||||
			"action": "accept",
 | 
			
		||||
			"src": [
 | 
			
		||||
				"subnet-1",
 | 
			
		||||
			],
 | 
			
		||||
			"dst": [
 | 
			
		||||
				"host-1:5400-5500",
 | 
			
		||||
			],
 | 
			
		||||
		},
 | 
			
		||||
	],
 | 
			
		||||
}
 | 
			
		||||
`,
 | 
			
		||||
			want: []tailcfg.FilterRule{
 | 
			
		||||
				{
 | 
			
		||||
					SrcIPs: []string{"100.100.101.0/24"},
 | 
			
		||||
					DstPorts: []tailcfg.NetPortRange{
 | 
			
		||||
						{
 | 
			
		||||
							IP:    "100.100.100.100/32",
 | 
			
		||||
							Ports: tailcfg.PortRange{First: 5400, Last: 5500},
 | 
			
		||||
						},
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			wantErr: false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name:   "port-group",
 | 
			
		||||
			format: "hujson",
 | 
			
		||||
			acl: `
 | 
			
		||||
{
 | 
			
		||||
	"groups": {
 | 
			
		||||
		"group:example": [
 | 
			
		||||
			"testuser",
 | 
			
		||||
		],
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	"hosts": {
 | 
			
		||||
		"host-1": "100.100.100.100",
 | 
			
		||||
		"subnet-1": "100.100.101.100/24",
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	"acls": [
 | 
			
		||||
		{
 | 
			
		||||
			"action": "accept",
 | 
			
		||||
			"src": [
 | 
			
		||||
				"group:example",
 | 
			
		||||
			],
 | 
			
		||||
			"dst": [
 | 
			
		||||
				"host-1:*",
 | 
			
		||||
			],
 | 
			
		||||
		},
 | 
			
		||||
	],
 | 
			
		||||
}
 | 
			
		||||
`,
 | 
			
		||||
			want: []tailcfg.FilterRule{
 | 
			
		||||
				{
 | 
			
		||||
					SrcIPs: []string{"200.200.200.200/32"},
 | 
			
		||||
					DstPorts: []tailcfg.NetPortRange{
 | 
			
		||||
						{IP: "100.100.100.100/32", Ports: tailcfg.PortRangeAny},
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			wantErr: false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name:   "port-user",
 | 
			
		||||
			format: "hujson",
 | 
			
		||||
			acl: `
 | 
			
		||||
{
 | 
			
		||||
	"hosts": {
 | 
			
		||||
		"host-1": "100.100.100.100",
 | 
			
		||||
		"subnet-1": "100.100.101.100/24",
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	"acls": [
 | 
			
		||||
		{
 | 
			
		||||
			"action": "accept",
 | 
			
		||||
			"src": [
 | 
			
		||||
				"testuser",
 | 
			
		||||
			],
 | 
			
		||||
			"dst": [
 | 
			
		||||
				"host-1:*",
 | 
			
		||||
			],
 | 
			
		||||
		},
 | 
			
		||||
	],
 | 
			
		||||
}
 | 
			
		||||
`,
 | 
			
		||||
			want: []tailcfg.FilterRule{
 | 
			
		||||
				{
 | 
			
		||||
					SrcIPs: []string{"200.200.200.200/32"},
 | 
			
		||||
					DstPorts: []tailcfg.NetPortRange{
 | 
			
		||||
						{IP: "100.100.100.100/32", Ports: tailcfg.PortRangeAny},
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			wantErr: false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name:   "port-wildcard-yaml",
 | 
			
		||||
			format: "yaml",
 | 
			
		||||
			acl: `
 | 
			
		||||
---
 | 
			
		||||
hosts:
 | 
			
		||||
  host-1: 100.100.100.100/32
 | 
			
		||||
  subnet-1: 100.100.101.100/24
 | 
			
		||||
acls:
 | 
			
		||||
  - action: accept
 | 
			
		||||
    src:
 | 
			
		||||
      - "*"
 | 
			
		||||
    dst:
 | 
			
		||||
      - host-1:*
 | 
			
		||||
`,
 | 
			
		||||
			want: []tailcfg.FilterRule{
 | 
			
		||||
				{
 | 
			
		||||
					SrcIPs: []string{"0.0.0.0/0", "::/0"},
 | 
			
		||||
					DstPorts: []tailcfg.NetPortRange{
 | 
			
		||||
						{IP: "100.100.100.100/32", Ports: tailcfg.PortRangeAny},
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			wantErr: false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name:   "ipv6-yaml",
 | 
			
		||||
			format: "yaml",
 | 
			
		||||
			acl: `
 | 
			
		||||
---
 | 
			
		||||
hosts:
 | 
			
		||||
  host-1: 100.100.100.100/32
 | 
			
		||||
  subnet-1: 100.100.101.100/24
 | 
			
		||||
acls:
 | 
			
		||||
  - action: accept
 | 
			
		||||
    src:
 | 
			
		||||
      - "*"
 | 
			
		||||
    dst:
 | 
			
		||||
      - host-1:*
 | 
			
		||||
`,
 | 
			
		||||
			want: []tailcfg.FilterRule{
 | 
			
		||||
				{
 | 
			
		||||
					SrcIPs: []string{"0.0.0.0/0", "::/0"},
 | 
			
		||||
					DstPorts: []tailcfg.NetPortRange{
 | 
			
		||||
						{IP: "100.100.100.100/32", Ports: tailcfg.PortRangeAny},
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			wantErr: false,
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, tt := range tests {
 | 
			
		||||
		t.Run(tt.name, func(t *testing.T) {
 | 
			
		||||
			pol, err := LoadACLPolicyFromBytes([]byte(tt.acl), tt.format)
 | 
			
		||||
 | 
			
		||||
			if tt.wantErr && err == nil {
 | 
			
		||||
				t.Errorf("parsing() error = %v, wantErr %v", err, tt.wantErr)
 | 
			
		||||
 | 
			
		||||
				return
 | 
			
		||||
			} else if !tt.wantErr && err != nil {
 | 
			
		||||
				t.Errorf("parsing() error = %v, wantErr %v", err, tt.wantErr)
 | 
			
		||||
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			rules, err := pol.generateFilterRules(&types.Machine{
 | 
			
		||||
				IPAddresses: types.MachineAddresses{
 | 
			
		||||
					netip.MustParseAddr("100.100.100.100"),
 | 
			
		||||
				},
 | 
			
		||||
			}, types.Machines{
 | 
			
		||||
				types.Machine{
 | 
			
		||||
					IPAddresses: types.MachineAddresses{
 | 
			
		||||
						netip.MustParseAddr("200.200.200.200"),
 | 
			
		||||
					},
 | 
			
		||||
					User: types.User{
 | 
			
		||||
						Name: "testuser",
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
			})
 | 
			
		||||
 | 
			
		||||
			if (err != nil) != tt.wantErr {
 | 
			
		||||
				t.Errorf("parsing() error = %v, wantErr %v", err, tt.wantErr)
 | 
			
		||||
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if diff := cmp.Diff(tt.want, rules); diff != "" {
 | 
			
		||||
				t.Errorf("parsing() unexpected result (-want +got):\n%s", diff)
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *Suite) TestRuleInvalidGeneration(c *check.C) {
 | 
			
		||||
@ -205,37 +551,6 @@ func (s *Suite) TestRuleInvalidGeneration(c *check.C) {
 | 
			
		||||
	c.Assert(rules, check.IsNil)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *Suite) TestBasicRule(c *check.C) {
 | 
			
		||||
	acl := []byte(`
 | 
			
		||||
{
 | 
			
		||||
	"hosts": {
 | 
			
		||||
		"host-1": "100.100.100.100",
 | 
			
		||||
		"subnet-1": "100.100.101.100/24",
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	"acls": [
 | 
			
		||||
		{
 | 
			
		||||
			"action": "accept",
 | 
			
		||||
			"src": [
 | 
			
		||||
				"subnet-1",
 | 
			
		||||
				"192.168.1.0/24"
 | 
			
		||||
			],
 | 
			
		||||
			"dst": [
 | 
			
		||||
				"*:22,3389",
 | 
			
		||||
				"host-1:*",
 | 
			
		||||
			],
 | 
			
		||||
		},
 | 
			
		||||
	],
 | 
			
		||||
}
 | 
			
		||||
	`)
 | 
			
		||||
	pol, err := LoadACLPolicyFromBytes(acl, "hujson")
 | 
			
		||||
	c.Assert(err, check.IsNil)
 | 
			
		||||
 | 
			
		||||
	rules, err := pol.generateFilterRules(&types.Machine{}, types.Machines{})
 | 
			
		||||
	c.Assert(err, check.IsNil)
 | 
			
		||||
	c.Assert(rules, check.NotNil)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TODO(kradalby): Make tests values safe, independent and descriptive.
 | 
			
		||||
func (s *Suite) TestInvalidAction(c *check.C) {
 | 
			
		||||
	pol := &ACLPolicy{
 | 
			
		||||
@ -286,199 +601,6 @@ func (s *Suite) TestInvalidTagOwners(c *check.C) {
 | 
			
		||||
	c.Assert(errors.Is(err, ErrInvalidTag), check.Equals, true)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *Suite) TestPortRange(c *check.C) {
 | 
			
		||||
	acl := []byte(`
 | 
			
		||||
{
 | 
			
		||||
	"hosts": {
 | 
			
		||||
		"host-1": "100.100.100.100",
 | 
			
		||||
		"subnet-1": "100.100.101.100/24",
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	"acls": [
 | 
			
		||||
		{
 | 
			
		||||
			"action": "accept",
 | 
			
		||||
			"src": [
 | 
			
		||||
				"subnet-1",
 | 
			
		||||
			],
 | 
			
		||||
			"dst": [
 | 
			
		||||
				"host-1:5400-5500",
 | 
			
		||||
			],
 | 
			
		||||
		},
 | 
			
		||||
	],
 | 
			
		||||
}
 | 
			
		||||
	`)
 | 
			
		||||
	pol, err := LoadACLPolicyFromBytes(acl, "hujson")
 | 
			
		||||
	c.Assert(err, check.IsNil)
 | 
			
		||||
	c.Assert(pol, check.NotNil)
 | 
			
		||||
 | 
			
		||||
	rules, err := pol.generateFilterRules(&types.Machine{}, types.Machines{})
 | 
			
		||||
	c.Assert(err, check.IsNil)
 | 
			
		||||
	c.Assert(rules, check.NotNil)
 | 
			
		||||
 | 
			
		||||
	c.Assert(rules, check.HasLen, 1)
 | 
			
		||||
	c.Assert(rules[0].DstPorts, check.HasLen, 1)
 | 
			
		||||
	c.Assert(rules[0].DstPorts[0].Ports.First, check.Equals, uint16(5400))
 | 
			
		||||
	c.Assert(rules[0].DstPorts[0].Ports.Last, check.Equals, uint16(5500))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *Suite) TestProtocolParsing(c *check.C) {
 | 
			
		||||
	acl := []byte(`
 | 
			
		||||
{
 | 
			
		||||
	"hosts": {
 | 
			
		||||
		"host-1": "100.100.100.100",
 | 
			
		||||
		"subnet-1": "100.100.101.100/24",
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	"acls": [
 | 
			
		||||
		{
 | 
			
		||||
			"Action": "accept",
 | 
			
		||||
			"src": [
 | 
			
		||||
				"*",
 | 
			
		||||
			],
 | 
			
		||||
			"proto": "tcp",
 | 
			
		||||
			"dst": [
 | 
			
		||||
				"host-1:*",
 | 
			
		||||
			],
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"Action": "accept",
 | 
			
		||||
			"src": [
 | 
			
		||||
				"*",
 | 
			
		||||
			],
 | 
			
		||||
			"proto": "udp",
 | 
			
		||||
			"dst": [
 | 
			
		||||
				"host-1:53",
 | 
			
		||||
			],
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"Action": "accept",
 | 
			
		||||
			"src": [
 | 
			
		||||
				"*",
 | 
			
		||||
			],
 | 
			
		||||
			"proto": "icmp",
 | 
			
		||||
			"dst": [
 | 
			
		||||
				"host-1:*",
 | 
			
		||||
			],
 | 
			
		||||
		},
 | 
			
		||||
	],
 | 
			
		||||
}
 | 
			
		||||
	`)
 | 
			
		||||
	pol, err := LoadACLPolicyFromBytes(acl, "hujson")
 | 
			
		||||
	c.Assert(err, check.IsNil)
 | 
			
		||||
	c.Assert(pol, check.NotNil)
 | 
			
		||||
 | 
			
		||||
	rules, err := pol.generateFilterRules(&types.Machine{}, types.Machines{})
 | 
			
		||||
	c.Assert(err, check.IsNil)
 | 
			
		||||
	c.Assert(rules, check.NotNil)
 | 
			
		||||
 | 
			
		||||
	c.Assert(rules, check.HasLen, 3)
 | 
			
		||||
	c.Assert(rules[0].IPProto[0], check.Equals, protocolTCP)
 | 
			
		||||
	c.Assert(rules[1].IPProto[0], check.Equals, protocolUDP)
 | 
			
		||||
	c.Assert(rules[2].IPProto[1], check.Equals, protocolIPv6ICMP)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *Suite) TestPortWildcard(c *check.C) {
 | 
			
		||||
	acl := []byte(`
 | 
			
		||||
{
 | 
			
		||||
	"hosts": {
 | 
			
		||||
		"host-1": "100.100.100.100",
 | 
			
		||||
		"subnet-1": "100.100.101.100/24",
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	"acls": [
 | 
			
		||||
		{
 | 
			
		||||
			"Action": "accept",
 | 
			
		||||
			"src": [
 | 
			
		||||
				"*",
 | 
			
		||||
			],
 | 
			
		||||
			"dst": [
 | 
			
		||||
				"host-1:*",
 | 
			
		||||
			],
 | 
			
		||||
		},
 | 
			
		||||
	],
 | 
			
		||||
}
 | 
			
		||||
	`)
 | 
			
		||||
	pol, err := LoadACLPolicyFromBytes(acl, "hujson")
 | 
			
		||||
	c.Assert(err, check.IsNil)
 | 
			
		||||
	c.Assert(pol, check.NotNil)
 | 
			
		||||
 | 
			
		||||
	rules, err := pol.generateFilterRules(&types.Machine{}, types.Machines{})
 | 
			
		||||
	c.Assert(err, check.IsNil)
 | 
			
		||||
	c.Assert(rules, check.NotNil)
 | 
			
		||||
 | 
			
		||||
	c.Assert(rules, check.HasLen, 1)
 | 
			
		||||
	c.Assert(rules[0].DstPorts, check.HasLen, 1)
 | 
			
		||||
	c.Assert(rules[0].DstPorts[0].Ports.First, check.Equals, uint16(0))
 | 
			
		||||
	c.Assert(rules[0].DstPorts[0].Ports.Last, check.Equals, uint16(65535))
 | 
			
		||||
	c.Assert(rules[0].SrcIPs, check.HasLen, 2)
 | 
			
		||||
	c.Assert(rules[0].SrcIPs[0], check.Equals, "0.0.0.0/0")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *Suite) TestPortWildcardYAML(c *check.C) {
 | 
			
		||||
	acl := []byte(`---
 | 
			
		||||
hosts:
 | 
			
		||||
  host-1: 100.100.100.100/32
 | 
			
		||||
  subnet-1: 100.100.101.100/24
 | 
			
		||||
acls:
 | 
			
		||||
  - action: accept
 | 
			
		||||
    src:
 | 
			
		||||
      - "*"
 | 
			
		||||
    dst:
 | 
			
		||||
      - host-1:*`)
 | 
			
		||||
	pol, err := LoadACLPolicyFromBytes(acl, "yaml")
 | 
			
		||||
	c.Assert(err, check.IsNil)
 | 
			
		||||
	c.Assert(pol, check.NotNil)
 | 
			
		||||
 | 
			
		||||
	rules, err := pol.generateFilterRules(&types.Machine{}, types.Machines{})
 | 
			
		||||
	c.Assert(err, check.IsNil)
 | 
			
		||||
	c.Assert(rules, check.NotNil)
 | 
			
		||||
 | 
			
		||||
	c.Assert(rules, check.HasLen, 1)
 | 
			
		||||
	c.Assert(rules[0].DstPorts, check.HasLen, 1)
 | 
			
		||||
	c.Assert(rules[0].DstPorts[0].Ports.First, check.Equals, uint16(0))
 | 
			
		||||
	c.Assert(rules[0].DstPorts[0].Ports.Last, check.Equals, uint16(65535))
 | 
			
		||||
	c.Assert(rules[0].SrcIPs, check.HasLen, 2)
 | 
			
		||||
	c.Assert(rules[0].SrcIPs[0], check.Equals, "0.0.0.0/0")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *Suite) TestBasicIpv6YAML(c *check.C) {
 | 
			
		||||
	acl := []byte(`
 | 
			
		||||
---
 | 
			
		||||
hosts:
 | 
			
		||||
  host-1: 100.100.100.100/32
 | 
			
		||||
  subnet-1: 100.100.101.100/24
 | 
			
		||||
acls:
 | 
			
		||||
  - action: accept
 | 
			
		||||
    src:
 | 
			
		||||
      - "*"
 | 
			
		||||
    dst:
 | 
			
		||||
      - 0.0.0.0/0:*
 | 
			
		||||
      - ::/0:*
 | 
			
		||||
      - fd7a:115c:a1e0::2:22
 | 
			
		||||
`)
 | 
			
		||||
	pol, err := LoadACLPolicyFromBytes(acl, "yaml")
 | 
			
		||||
	c.Assert(err, check.IsNil)
 | 
			
		||||
	c.Assert(pol, check.NotNil)
 | 
			
		||||
 | 
			
		||||
	rules, err := pol.generateFilterRules(&types.Machine{}, types.Machines{})
 | 
			
		||||
	c.Assert(err, check.IsNil)
 | 
			
		||||
	c.Assert(rules, check.NotNil)
 | 
			
		||||
 | 
			
		||||
	c.Assert(rules, check.HasLen, 1)
 | 
			
		||||
	c.Assert(rules[0].DstPorts, check.HasLen, 3)
 | 
			
		||||
	c.Assert(rules[0].DstPorts[0].IP, check.Equals, "0.0.0.0/0")
 | 
			
		||||
	c.Assert(rules[0].DstPorts[0].Ports.First, check.Equals, uint16(0))
 | 
			
		||||
	c.Assert(rules[0].DstPorts[0].Ports.Last, check.Equals, uint16(65535))
 | 
			
		||||
	c.Assert(rules[0].DstPorts[1].IP, check.Equals, "::/0")
 | 
			
		||||
	c.Assert(rules[0].DstPorts[1].Ports.First, check.Equals, uint16(0))
 | 
			
		||||
	c.Assert(rules[0].DstPorts[1].Ports.Last, check.Equals, uint16(65535))
 | 
			
		||||
	c.Assert(rules[0].DstPorts[2].IP, check.Equals, "fd7a:115c:a1e0::2/128")
 | 
			
		||||
	c.Assert(rules[0].DstPorts[2].Ports.First, check.Equals, uint16(22))
 | 
			
		||||
	c.Assert(rules[0].DstPorts[2].Ports.Last, check.Equals, uint16(22))
 | 
			
		||||
	c.Assert(rules[0].SrcIPs, check.HasLen, 2)
 | 
			
		||||
	c.Assert(rules[0].SrcIPs[0], check.Equals, "0.0.0.0/0")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Test_expandGroup(t *testing.T) {
 | 
			
		||||
	type field struct {
 | 
			
		||||
		pol ACLPolicy
 | 
			
		||||
@ -1621,8 +1743,13 @@ func TestACLPolicy_generateFilterRules(t *testing.T) {
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			args: args{
 | 
			
		||||
				machine: types.Machine{},
 | 
			
		||||
				peers:   types.Machines{},
 | 
			
		||||
				machine: types.Machine{
 | 
			
		||||
					IPAddresses: types.MachineAddresses{
 | 
			
		||||
						netip.MustParseAddr("100.64.0.1"),
 | 
			
		||||
						netip.MustParseAddr("fd7a:115c:a1e0:ab12:4843:2222:6273:2221"),
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
				peers: types.Machines{},
 | 
			
		||||
			},
 | 
			
		||||
			want: []tailcfg.FilterRule{
 | 
			
		||||
				{
 | 
			
		||||
@ -1648,7 +1775,64 @@ func TestACLPolicy_generateFilterRules(t *testing.T) {
 | 
			
		||||
			wantErr: false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "host1-can-reach-host2",
 | 
			
		||||
			name: "host1-can-reach-host2-no-rules",
 | 
			
		||||
			field: field{
 | 
			
		||||
				pol: ACLPolicy{
 | 
			
		||||
					ACLs: []ACL{
 | 
			
		||||
						{
 | 
			
		||||
							Action:       "accept",
 | 
			
		||||
							Sources:      []string{"100.64.0.2"},
 | 
			
		||||
							Destinations: []string{"100.64.0.1:*"},
 | 
			
		||||
						},
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			args: args{
 | 
			
		||||
				machine: types.Machine{
 | 
			
		||||
					IPAddresses: types.MachineAddresses{
 | 
			
		||||
						netip.MustParseAddr("100.64.0.1"),
 | 
			
		||||
						netip.MustParseAddr("fd7a:115c:a1e0:ab12:4843:2222:6273:2221"),
 | 
			
		||||
					},
 | 
			
		||||
					User: types.User{Name: "mickael"},
 | 
			
		||||
				},
 | 
			
		||||
				peers: types.Machines{
 | 
			
		||||
					{
 | 
			
		||||
						IPAddresses: types.MachineAddresses{
 | 
			
		||||
							netip.MustParseAddr("100.64.0.2"),
 | 
			
		||||
							netip.MustParseAddr("fd7a:115c:a1e0:ab12:4843:2222:6273:2222"),
 | 
			
		||||
						},
 | 
			
		||||
						User: types.User{Name: "mickael"},
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			want: []tailcfg.FilterRule{
 | 
			
		||||
				{
 | 
			
		||||
					SrcIPs: []string{
 | 
			
		||||
						"100.64.0.2/32",
 | 
			
		||||
						"fd7a:115c:a1e0:ab12:4843:2222:6273:2222/128",
 | 
			
		||||
					},
 | 
			
		||||
					DstPorts: []tailcfg.NetPortRange{
 | 
			
		||||
						{
 | 
			
		||||
							IP: "100.64.0.1/32",
 | 
			
		||||
							Ports: tailcfg.PortRange{
 | 
			
		||||
								First: 0,
 | 
			
		||||
								Last:  65535,
 | 
			
		||||
							},
 | 
			
		||||
						},
 | 
			
		||||
						{
 | 
			
		||||
							IP: "fd7a:115c:a1e0:ab12:4843:2222:6273:2221/128",
 | 
			
		||||
							Ports: tailcfg.PortRange{
 | 
			
		||||
								First: 0,
 | 
			
		||||
								Last:  65535,
 | 
			
		||||
							},
 | 
			
		||||
						},
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			wantErr: false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "host1-can-reach-host2-no-rules",
 | 
			
		||||
			field: field{
 | 
			
		||||
				pol: ACLPolicy{
 | 
			
		||||
					ACLs: []ACL{
 | 
			
		||||
@ -1678,30 +1862,7 @@ func TestACLPolicy_generateFilterRules(t *testing.T) {
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			want: []tailcfg.FilterRule{
 | 
			
		||||
				{
 | 
			
		||||
					SrcIPs: []string{
 | 
			
		||||
						"100.64.0.1/32",
 | 
			
		||||
						"fd7a:115c:a1e0:ab12:4843:2222:6273:2221/128",
 | 
			
		||||
					},
 | 
			
		||||
					DstPorts: []tailcfg.NetPortRange{
 | 
			
		||||
						{
 | 
			
		||||
							IP: "100.64.0.2/32",
 | 
			
		||||
							Ports: tailcfg.PortRange{
 | 
			
		||||
								First: 0,
 | 
			
		||||
								Last:  65535,
 | 
			
		||||
							},
 | 
			
		||||
						},
 | 
			
		||||
						{
 | 
			
		||||
							IP: "fd7a:115c:a1e0:ab12:4843:2222:6273:2222/128",
 | 
			
		||||
							Ports: tailcfg.PortRange{
 | 
			
		||||
								First: 0,
 | 
			
		||||
								Last:  65535,
 | 
			
		||||
							},
 | 
			
		||||
						},
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			want:    []tailcfg.FilterRule{},
 | 
			
		||||
			wantErr: false,
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user