mirror of
https://github.com/juanfont/headscale.git
synced 2024-12-02 11:43:05 +00:00
Add acl autogroup member and autogroup self
This commit is contained in:
parent
0089ceaf1d
commit
3ffae8ac20
1 changed files with 171 additions and 6 deletions
|
@ -68,6 +68,24 @@ func theInternet() *netipx.IPSet {
|
||||||
return theInternetSet
|
return theInternetSet
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// vinhjaxt
|
||||||
|
var allTheIps *netipx.IPSet
|
||||||
|
|
||||||
|
func getAllTheIps() *netipx.IPSet {
|
||||||
|
if allTheIps != nil {
|
||||||
|
return allTheIps
|
||||||
|
}
|
||||||
|
|
||||||
|
var build netipx.IPSetBuilder
|
||||||
|
build.AddPrefix(netip.MustParsePrefix("::/0"))
|
||||||
|
build.AddPrefix(netip.MustParsePrefix("0.0.0.0/0"))
|
||||||
|
|
||||||
|
allTheIps, _ := build.IPSet()
|
||||||
|
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
|
||||||
|
@ -169,13 +187,51 @@ func (pol *ACLPolicy) CompileFilterRules(
|
||||||
|
|
||||||
var rules []tailcfg.FilterRule
|
var rules []tailcfg.FilterRule
|
||||||
|
|
||||||
for index, acl := range pol.ACLs {
|
// vinhjaxt
|
||||||
|
polACLs := pol.ACLs
|
||||||
|
for index := 0; index < len(polACLs); index++ {
|
||||||
|
acl := polACLs[index]
|
||||||
|
aclDestinations := acl.Destinations
|
||||||
|
|
||||||
if acl.Action != "accept" {
|
if acl.Action != "accept" {
|
||||||
return nil, ErrInvalidAction
|
return nil, ErrInvalidAction
|
||||||
}
|
}
|
||||||
|
|
||||||
var srcIPs []string
|
var srcIPs []string
|
||||||
for srcIndex, src := range acl.Sources {
|
for srcIndex, src := range acl.Sources {
|
||||||
|
// vinhjaxt
|
||||||
|
if strings.HasPrefix(src, "autogroup:member") {
|
||||||
|
// split all autogroup:self and others
|
||||||
|
var oldDst []string
|
||||||
|
var newDst []string
|
||||||
|
|
||||||
|
for _, dst := range aclDestinations {
|
||||||
|
if strings.HasPrefix(dst, "autogroup:self") {
|
||||||
|
newDst = append(newDst, dst)
|
||||||
|
} else {
|
||||||
|
oldDst = append(oldDst, dst)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(oldDst) == 0 {
|
||||||
|
// all moved to new, only need to change source
|
||||||
|
src = "autogroup:self"
|
||||||
|
} else if len(newDst) != 0 {
|
||||||
|
// apart moved to new
|
||||||
|
|
||||||
|
aclDestinations = oldDst
|
||||||
|
|
||||||
|
splitAcl := ACL{
|
||||||
|
Action: acl.Action,
|
||||||
|
Sources: []string{"autogroup:self"},
|
||||||
|
Destinations: newDst,
|
||||||
|
}
|
||||||
|
polACLs = append(polACLs, 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 {
|
||||||
return nil, fmt.Errorf("parsing policy, acl index: %d->%d: %w", index, srcIndex, err)
|
return nil, fmt.Errorf("parsing policy, acl index: %d->%d: %w", index, srcIndex, err)
|
||||||
|
@ -189,12 +245,19 @@ func (pol *ACLPolicy) CompileFilterRules(
|
||||||
}
|
}
|
||||||
|
|
||||||
destPorts := []tailcfg.NetPortRange{}
|
destPorts := []tailcfg.NetPortRange{}
|
||||||
for _, dest := range acl.Destinations {
|
for _, dest := range aclDestinations {
|
||||||
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, "autogroup:self") {
|
||||||
|
if len(acl.Sources) != 1 || !(acl.Sources[0] == "autogroup:self" || acl.Sources[0] == "autogroup:member") {
|
||||||
|
return nil, errors.New(`dst "autogroup:self" only works with one src "autogroup:member" or "autogroup:self"`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
expanded, err := pol.ExpandAlias(
|
expanded, err := pol.ExpandAlias(
|
||||||
nodes,
|
nodes,
|
||||||
alias,
|
alias,
|
||||||
|
@ -309,9 +372,21 @@ func (pol *ACLPolicy) CompileSSHPolicy(
|
||||||
AllowLocalPortForwarding: false,
|
AllowLocalPortForwarding: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
for index, sshACL := range pol.SSHs {
|
// vinhjaxt
|
||||||
|
polSSHs := pol.SSHs
|
||||||
|
for index := 0; index < len(polSSHs); index++ {
|
||||||
|
sshACL := polSSHs[index]
|
||||||
|
sshACLDestinations := sshACL.Destinations
|
||||||
|
|
||||||
var dest netipx.IPSetBuilder
|
var dest netipx.IPSetBuilder
|
||||||
for _, src := range sshACL.Destinations {
|
for _, src := range sshACLDestinations {
|
||||||
|
// vinhjaxt
|
||||||
|
if strings.HasPrefix(src, "autogroup:self") {
|
||||||
|
if len(sshACL.Sources) != 1 || !(sshACL.Sources[0] == "autogroup:self" || sshACL.Sources[0] == "autogroup:member") {
|
||||||
|
return nil, errors.New(`dst "autogroup:self" only works with one src "autogroup:member" or "autogroup:self"`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
expanded, err := pol.ExpandAlias(append(peers, node), src)
|
expanded, err := pol.ExpandAlias(append(peers, node), src)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -361,6 +436,41 @@ func (pol *ACLPolicy) CompileSSHPolicy(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// vinhjaxt
|
||||||
|
if strings.HasPrefix(rawSrc, "autogroup:member") {
|
||||||
|
// split all autogroup:self and others
|
||||||
|
var oldDst []string
|
||||||
|
var newDst []string
|
||||||
|
|
||||||
|
for _, dst := range sshACLDestinations {
|
||||||
|
if strings.HasPrefix(dst, "autogroup:self") {
|
||||||
|
newDst = append(newDst, dst)
|
||||||
|
} else {
|
||||||
|
oldDst = append(oldDst, dst)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(oldDst) == 0 {
|
||||||
|
// all moved to new, only need to change source
|
||||||
|
rawSrc = "autogroup:self"
|
||||||
|
} else if len(newDst) != 0 {
|
||||||
|
// apart moved to new
|
||||||
|
|
||||||
|
sshACLDestinations = oldDst
|
||||||
|
|
||||||
|
splitAcl := SSH{
|
||||||
|
Action: sshACL.Action,
|
||||||
|
Sources: []string{"autogroup:self"},
|
||||||
|
Destinations: newDst,
|
||||||
|
Users: sshACL.Users,
|
||||||
|
CheckPeriod: sshACL.CheckPeriod,
|
||||||
|
}
|
||||||
|
polSSHs = append(polSSHs, splitAcl)
|
||||||
|
// Don't do pol.SSHs = polSSHs, race condition
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// !vinhjaxt
|
||||||
|
|
||||||
expandedSrcs, err := pol.ExpandAlias(
|
expandedSrcs, err := pol.ExpandAlias(
|
||||||
peers,
|
peers,
|
||||||
rawSrc,
|
rawSrc,
|
||||||
|
@ -561,7 +671,8 @@ func (pol *ACLPolicy) ExpandAlias(
|
||||||
}
|
}
|
||||||
|
|
||||||
if isAutoGroup(alias) {
|
if isAutoGroup(alias) {
|
||||||
return expandAutoGroup(alias)
|
// vinhjaxt
|
||||||
|
return expandAutoGroup(pol, alias, nodes)
|
||||||
}
|
}
|
||||||
|
|
||||||
// if alias is a user
|
// if alias is a user
|
||||||
|
@ -880,11 +991,65 @@ func (pol *ACLPolicy) expandIPsFromIPPrefix(
|
||||||
return build.IPSet()
|
return build.IPSet()
|
||||||
}
|
}
|
||||||
|
|
||||||
func expandAutoGroup(alias string) (*netipx.IPSet, error) {
|
// vinhjaxt
|
||||||
|
func expandAutoGroup(pol *ACLPolicy, alias string, nodes types.Nodes) (*netipx.IPSet, error) {
|
||||||
switch {
|
switch {
|
||||||
case strings.HasPrefix(alias, "autogroup:internet"):
|
case strings.HasPrefix(alias, "autogroup:internet"):
|
||||||
return theInternet(), nil
|
return theInternet(), nil
|
||||||
|
|
||||||
|
// vinhjaxt
|
||||||
|
case strings.HasPrefix(alias, "autogroup:self"):
|
||||||
|
// all user's devices, not tagged devices
|
||||||
|
{
|
||||||
|
var build netipx.IPSetBuilder
|
||||||
|
if len(nodes) == 0 {
|
||||||
|
return build.IPSet()
|
||||||
|
}
|
||||||
|
|
||||||
|
currentNode := nodes[len(nodes)-1] // /mapper/mapper.go#L544
|
||||||
|
for _, node := range nodes {
|
||||||
|
if node.User.Name == currentNode.User.Name {
|
||||||
|
// same user name
|
||||||
|
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 {
|
||||||
|
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, "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"):
|
||||||
|
// all ips
|
||||||
|
return getAllTheIps(), nil
|
||||||
|
// !vinhjaxt
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("unknown autogroup %q", alias)
|
return nil, fmt.Errorf("unknown autogroup %q", alias)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue