diff --git a/hscontrol/policy/acls.go b/hscontrol/policy/acls.go index b4d611f4..675dd46e 100644 --- a/hscontrol/policy/acls.go +++ b/hscontrol/policy/acls.go @@ -385,7 +385,13 @@ func (pol *ACLPolicy) getNetPortRangeFromDestination( maybeIPv6Str := strings.TrimSuffix(dest, ":"+port) log.Trace().Str("maybeIPv6Str", maybeIPv6Str).Msg("") - if maybeIPv6, err := netip.ParseAddr(maybeIPv6Str); err != nil && !maybeIPv6.Is6() { + filteredMaybeIPv6Str := maybeIPv6Str + if strings.Contains(maybeIPv6Str, "/") { + networkParts := strings.Split(maybeIPv6Str, "/") + filteredMaybeIPv6Str = networkParts[0] + } + + if maybeIPv6, err := netip.ParseAddr(filteredMaybeIPv6Str); err != nil && !maybeIPv6.Is6() { log.Trace().Err(err).Msg("trying to parse as IPv6") return nil, fmt.Errorf( diff --git a/hscontrol/policy/acls_test.go b/hscontrol/policy/acls_test.go index 591dcd90..2093d939 100644 --- a/hscontrol/policy/acls_test.go +++ b/hscontrol/policy/acls_test.go @@ -439,6 +439,44 @@ acls: 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.Machines{}, false) + 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 diff --git a/integration/acl_test.go b/integration/acl_test.go index ca184b83..654f557d 100644 --- a/integration/acl_test.go +++ b/integration/acl_test.go @@ -237,6 +237,24 @@ func TestACLHostsInNetMapTable(t *testing.T) { "user2": 3, // ns1 + ns2 (return path) }, }, + "ipv6-acls-1470": { + users: map[string]int{ + "user1": 2, + "user2": 2, + }, + policy: policy.ACLPolicy{ + ACLs: []policy.ACL{ + { + Action: "accept", + Sources: []string{"*"}, + Destinations: []string{"0.0.0.0/0:*", "::/0:*"}, + }, + }, + }, want: map[string]int{ + "user1": 3, // ns1 + ns2 + "user2": 3, // ns2 + ns1 + }, + }, } for name, testCase := range tests {