chore(policy): ACL code cleanups and lint fixes

This commit is contained in:
Gabe Cook 2024-10-12 02:48:13 -05:00
parent 3ffae8ac20
commit 2732e7a017
No known key found for this signature in database
GPG key ID: 3197318BDE319B8D

View file

@ -28,12 +28,22 @@ var (
ErrInvalidTag = errors.New("invalid tag") ErrInvalidTag = errors.New("invalid tag")
ErrInvalidPortFormat = errors.New("invalid port format") ErrInvalidPortFormat = errors.New("invalid port format")
ErrWildcardIsNeeded = errors.New("wildcard as port is required for the protocol") ErrWildcardIsNeeded = errors.New("wildcard as port is required for the protocol")
ErrUnknownAutogroup = errors.New("unknown autogroup")
ErrAutogroupSelf = errors.New(`dst "autogroup:self" only works with one src "autogroup:member" or "autogroup:self"`)
) )
const ( const (
portRangeBegin = 0 portRangeBegin = 0
portRangeEnd = 65535 portRangeEnd = 65535
expectedTokenItems = 2 expectedTokenItems = 2
autogroupPrefix = "autogroup:"
autogroupInternet = "autogroup:internet"
autogroupSelf = "autogroup:self"
autogroupMember = "autogroup:member"
autogroupTagged = "autogroup:tagged"
autogroupNonRoot = "autogroup:nonroot"
autogroupDangerAll = "autogroup:danger-all"
) )
var theInternetSet *netipx.IPSet var theInternetSet *netipx.IPSet
@ -68,12 +78,11 @@ func theInternet() *netipx.IPSet {
return theInternetSet return theInternetSet
} }
// vinhjaxt var allIPSet *netipx.IPSet
var allTheIps *netipx.IPSet
func getAllTheIps() *netipx.IPSet { func allIPs() *netipx.IPSet {
if allTheIps != nil { if allIPSet != nil {
return allTheIps return allIPSet
} }
var build netipx.IPSetBuilder var build netipx.IPSetBuilder
@ -81,11 +90,10 @@ func getAllTheIps() *netipx.IPSet {
build.AddPrefix(netip.MustParsePrefix("0.0.0.0/0")) build.AddPrefix(netip.MustParsePrefix("0.0.0.0/0"))
allTheIps, _ := build.IPSet() allTheIps, _ := build.IPSet()
return allTheIps return allTheIps
} }
// !vinhjaxt
// For some reason golang.org/x/net/internal/iana is an internal package. // For some reason golang.org/x/net/internal/iana is an internal package.
const ( const (
protocolICMP = 1 // Internet Control Message protocolICMP = 1 // Internet Control Message
@ -187,11 +195,10 @@ func (pol *ACLPolicy) CompileFilterRules(
var rules []tailcfg.FilterRule var rules []tailcfg.FilterRule
// vinhjaxt acls := pol.ACLs
polACLs := pol.ACLs for index := 0; index < len(acls); index++ {
for index := 0; index < len(polACLs); index++ { acl := acls[index]
acl := polACLs[index] destinations := acl.Destinations
aclDestinations := acl.Destinations
if acl.Action != "accept" { if acl.Action != "accept" {
return nil, ErrInvalidAction return nil, ErrInvalidAction
@ -199,38 +206,36 @@ func (pol *ACLPolicy) CompileFilterRules(
var srcIPs []string var srcIPs []string
for srcIndex, src := range acl.Sources { for srcIndex, src := range acl.Sources {
// vinhjaxt if strings.HasPrefix(src, autogroupMember) {
if strings.HasPrefix(src, "autogroup:member") {
// split all autogroup:self and others // split all autogroup:self and others
var oldDst []string var oldDst []string
var newDst []string var newDst []string
for _, dst := range aclDestinations { for _, dst := range destinations {
if strings.HasPrefix(dst, "autogroup:self") { if strings.HasPrefix(dst, autogroupSelf) {
newDst = append(newDst, dst) newDst = append(newDst, dst)
} else { } else {
oldDst = append(oldDst, dst) oldDst = append(oldDst, dst)
} }
} }
if len(oldDst) == 0 { switch {
case len(oldDst) == 0:
// all moved to new, only need to change source // all moved to new, only need to change source
src = "autogroup:self" src = autogroupSelf
} else if len(newDst) != 0 { case len(newDst) != 0:
// apart moved to new // apart moved to new
aclDestinations = oldDst destinations = oldDst
splitAcl := ACL{ splitACL := ACL{
Action: acl.Action, Action: acl.Action,
Sources: []string{"autogroup:self"}, Sources: []string{autogroupSelf},
Destinations: newDst, Destinations: newDst,
} }
polACLs = append(polACLs, splitAcl) acls = append(acls, splitACL)
// Don't do pol.ACLs = polACLs, race condition
} }
} }
// !vinhjaxt
srcs, err := pol.expandSource(src, nodes) srcs, err := pol.expandSource(src, nodes)
if err != nil { if err != nil {
@ -245,16 +250,15 @@ func (pol *ACLPolicy) CompileFilterRules(
} }
destPorts := []tailcfg.NetPortRange{} destPorts := []tailcfg.NetPortRange{}
for _, dest := range aclDestinations { for _, dest := range destinations {
alias, port, err := parseDestination(dest) alias, port, err := parseDestination(dest)
if err != nil { if err != nil {
return nil, err return nil, err
} }
// vinhjaxt if strings.HasPrefix(alias, autogroupSelf) {
if strings.HasPrefix(alias, "autogroup:self") { if len(acl.Sources) != 1 || acl.Sources[0] != autogroupSelf && acl.Sources[0] != autogroupMember {
if len(acl.Sources) != 1 || !(acl.Sources[0] == "autogroup:self" || acl.Sources[0] == "autogroup:member") { return nil, ErrAutogroupSelf
return nil, errors.New(`dst "autogroup:self" only works with one src "autogroup:member" or "autogroup:self"`)
} }
} }
@ -372,18 +376,16 @@ func (pol *ACLPolicy) CompileSSHPolicy(
AllowLocalPortForwarding: false, AllowLocalPortForwarding: false,
} }
// vinhjaxt sshs := pol.SSHs
polSSHs := pol.SSHs for index := 0; index < len(sshs); index++ {
for index := 0; index < len(polSSHs); index++ { sshACL := sshs[index]
sshACL := polSSHs[index] destinations := sshACL.Destinations
sshACLDestinations := sshACL.Destinations
var dest netipx.IPSetBuilder var dest netipx.IPSetBuilder
for _, src := range sshACLDestinations { for _, src := range destinations {
// vinhjaxt if strings.HasPrefix(src, autogroupSelf) {
if strings.HasPrefix(src, "autogroup:self") { if len(sshACL.Sources) != 1 || sshACL.Sources[0] != autogroupSelf && sshACL.Sources[0] != autogroupMember {
if len(sshACL.Sources) != 1 || !(sshACL.Sources[0] == "autogroup:self" || sshACL.Sources[0] == "autogroup:member") { return nil, ErrAutogroupSelf
return nil, errors.New(`dst "autogroup:self" only works with one src "autogroup:member" or "autogroup:self"`)
} }
} }
@ -436,40 +438,38 @@ func (pol *ACLPolicy) CompileSSHPolicy(
}) })
} }
} else { } else {
// vinhjaxt if strings.HasPrefix(rawSrc, autogroupMember) {
if strings.HasPrefix(rawSrc, "autogroup:member") {
// split all autogroup:self and others // split all autogroup:self and others
var oldDst []string var oldDst []string
var newDst []string var newDst []string
for _, dst := range sshACLDestinations { for _, dst := range destinations {
if strings.HasPrefix(dst, "autogroup:self") { if strings.HasPrefix(dst, autogroupSelf) {
newDst = append(newDst, dst) newDst = append(newDst, dst)
} else { } else {
oldDst = append(oldDst, dst) oldDst = append(oldDst, dst)
} }
} }
if len(oldDst) == 0 { switch {
case len(oldDst) == 0:
// all moved to new, only need to change source // all moved to new, only need to change source
rawSrc = "autogroup:self" rawSrc = autogroupSelf
} else if len(newDst) != 0 { case len(newDst) != 0:
// apart moved to new // apart moved to new
sshACLDestinations = oldDst destinations = oldDst
splitAcl := SSH{ splitACL := SSH{
Action: sshACL.Action, Action: sshACL.Action,
Sources: []string{"autogroup:self"}, Sources: []string{autogroupSelf},
Destinations: newDst, Destinations: newDst,
Users: sshACL.Users, Users: sshACL.Users,
CheckPeriod: sshACL.CheckPeriod, CheckPeriod: sshACL.CheckPeriod,
} }
polSSHs = append(polSSHs, splitAcl) sshs = append(sshs, splitACL)
// Don't do pol.SSHs = polSSHs, race condition
} }
} }
// !vinhjaxt
expandedSrcs, err := pol.ExpandAlias( expandedSrcs, err := pol.ExpandAlias(
peers, peers,
@ -671,7 +671,6 @@ func (pol *ACLPolicy) ExpandAlias(
} }
if isAutoGroup(alias) { if isAutoGroup(alias) {
// vinhjaxt
return expandAutoGroup(pol, alias, nodes) return expandAutoGroup(pol, alias, nodes)
} }
@ -991,67 +990,60 @@ func (pol *ACLPolicy) expandIPsFromIPPrefix(
return build.IPSet() return build.IPSet()
} }
// vinhjaxt
func expandAutoGroup(pol *ACLPolicy, alias string, nodes types.Nodes) (*netipx.IPSet, error) { func expandAutoGroup(pol *ACLPolicy, alias string, nodes types.Nodes) (*netipx.IPSet, error) {
switch { switch {
case strings.HasPrefix(alias, "autogroup:internet"): case strings.HasPrefix(alias, autogroupInternet):
return theInternet(), nil return theInternet(), nil
// vinhjaxt case strings.HasPrefix(alias, autogroupSelf):
case strings.HasPrefix(alias, "autogroup:self"):
// all user's devices, not tagged devices // all user's devices, not tagged devices
{ var build netipx.IPSetBuilder
var build netipx.IPSetBuilder if len(nodes) != 0 {
if len(nodes) == 0 { currentNode := nodes[len(nodes)-1]
return build.IPSet()
}
currentNode := nodes[len(nodes)-1] // /mapper/mapper.go#L544
for _, node := range nodes { for _, node := range nodes {
if node.User.Name == currentNode.User.Name { if node.User.ID == currentNode.User.ID {
// same user name
node.AppendToIPSet(&build) node.AppendToIPSet(&build)
} }
} }
return build.IPSet()
} }
case strings.HasPrefix(alias, "autogroup:member"):
// all users (not tagged devices)
{
var build netipx.IPSetBuilder
for _, node := range nodes { return build.IPSet()
if len(node.ForcedTags) != 0 { // auto tag
continue case strings.HasPrefix(alias, autogroupMember):
} // all users (not tagged devices)
if tags, _ := pol.TagsOfNode(node); len(tags) != 0 { // valid tag manual add by user (tagOwner) var build netipx.IPSetBuilder
continue
} for _, node := range nodes {
if len(node.ForcedTags) != 0 { // auto tag
continue
}
if tags, _ := pol.TagsOfNode(node); len(tags) != 0 { // valid tag manual add by user (tagOwner)
continue
}
node.AppendToIPSet(&build)
}
return build.IPSet()
case strings.HasPrefix(alias, autogroupTagged):
// all tagged devices
var build netipx.IPSetBuilder
for _, node := range nodes {
if len(node.ForcedTags) != 0 { // auto tag
node.AppendToIPSet(&build)
} else if tags, _ := pol.TagsOfNode(node); len(tags) != 0 { // valid tag manual add by user (tagOwner)
node.AppendToIPSet(&build) node.AppendToIPSet(&build)
} }
return build.IPSet()
}
case strings.HasPrefix(alias, "autogroup:tagged"):
// all tagged devices
{
var build netipx.IPSetBuilder
for _, node := range nodes {
if len(node.ForcedTags) != 0 { // auto tag
node.AppendToIPSet(&build)
} else if tags, _ := pol.TagsOfNode(node); len(tags) != 0 { // valid tag manual add by user (tagOwner)
node.AppendToIPSet(&build)
}
}
return build.IPSet()
} }
case strings.HasPrefix(alias, "autogroup:danger-all"): return build.IPSet()
// all ips
return getAllTheIps(), nil case strings.HasPrefix(alias, autogroupDangerAll):
// !vinhjaxt return allIPs(), nil
default: default:
return nil, fmt.Errorf("unknown autogroup %q", alias) return nil, fmt.Errorf("%w: %q", ErrUnknownAutogroup, alias)
} }
} }
@ -1068,7 +1060,7 @@ func isTag(str string) bool {
} }
func isAutoGroup(str string) bool { func isAutoGroup(str string) bool {
return strings.HasPrefix(str, "autogroup:") return strings.HasPrefix(str, autogroupPrefix)
} }
// TagsOfNode will return the tags of the current node. // TagsOfNode will return the tags of the current node.