Skip to content

Commit

Permalink
add autogroup:internet, fix reduce filter rules (#1917)
Browse files Browse the repository at this point in the history
  • Loading branch information
kradalby authored Apr 30, 2024
1 parent ff427cc commit 87e2ae4
Show file tree
Hide file tree
Showing 3 changed files with 619 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ after improving the test harness as part of adopting [#1460](https://github.com/
- Add support for deleting api keys [#1702](https://github.com/juanfont/headscale/pull/1702)
- Add command to backfill IP addresses for nodes missing IPs from configured prefixes. [#1869](https://github.com/juanfont/headscale/pull/1869)
- Log available update as warning [#1877](https://github.com/juanfont/headscale/pull/1877)
- Add `autogroup:internet` to Policy [#1917](https://github.com/juanfont/headscale/pull/1917)

## 0.22.3 (2023-05-12)

Expand Down
61 changes: 56 additions & 5 deletions hscontrol/policy/acls.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,38 @@ const (
expectedTokenItems = 2
)

var theInternetSet *netipx.IPSet

// theInternet returns the IPSet for the Internet.
// https://www.youtube.com/watch?v=iDbyYGrswtg
func theInternet() *netipx.IPSet {
if theInternetSet != nil {
return theInternetSet
}

var internetBuilder netipx.IPSetBuilder
internetBuilder.AddPrefix(netip.MustParsePrefix("2000::/3"))
internetBuilder.AddPrefix(netip.MustParsePrefix("0.0.0.0/0"))

// Delete Private network addresses
// https://datatracker.ietf.org/doc/html/rfc1918
internetBuilder.RemovePrefix(netip.MustParsePrefix("fc00::/7"))
internetBuilder.RemovePrefix(netip.MustParsePrefix("10.0.0.0/8"))
internetBuilder.RemovePrefix(netip.MustParsePrefix("172.16.0.0/12"))
internetBuilder.RemovePrefix(netip.MustParsePrefix("192.168.0.0/16"))

// Delete Tailscale networks
internetBuilder.RemovePrefix(netip.MustParsePrefix("fd7a:115c:a1e0::/48"))
internetBuilder.RemovePrefix(netip.MustParsePrefix("100.64.0.0/10"))

// Delete "cant find DHCP networks"
internetBuilder.RemovePrefix(netip.MustParsePrefix("fe80::/10")) // link-loca
internetBuilder.RemovePrefix(netip.MustParsePrefix("169.254.0.0/16"))

theInternetSet, _ := internetBuilder.IPSet()
return theInternetSet
}

// For some reason golang.org/x/net/internal/iana is an internal package.
const (
protocolICMP = 1 // Internet Control Message
Expand Down Expand Up @@ -221,28 +253,28 @@ func ReduceFilterRules(node *types.Node, rules []tailcfg.FilterRule) []tailcfg.F
// record if the rule is actually relevant for the given node.
dests := []tailcfg.NetPortRange{}

DEST_LOOP:
for _, dest := range rule.DstPorts {
expanded, err := util.ParseIPSet(dest.IP, nil)
// Fail closed, if we cant parse it, then we should not allow
// access.
if err != nil {
continue
continue DEST_LOOP
}

if node.InIPSet(expanded) {
dests = append(dests, dest)
continue DEST_LOOP
}

// If the node exposes routes, ensure they are note removed
// when the filters are reduced.
if node.Hostinfo != nil {
// TODO(kradalby): Evaluate if we should only keep
// the routes if the route is enabled. This will
// require database access in this part of the code.
if len(node.Hostinfo.RoutableIPs) > 0 {
for _, routableIP := range node.Hostinfo.RoutableIPs {
if expanded.ContainsPrefix(routableIP) {
if expanded.OverlapsPrefix(routableIP) {
dests = append(dests, dest)
continue DEST_LOOP
}
}
}
Expand Down Expand Up @@ -517,6 +549,7 @@ func (pol *ACLPolicy) expandSource(
// - a host
// - an ip
// - a cidr
// - an autogroup
// and transform these in IPAddresses.
func (pol *ACLPolicy) ExpandAlias(
nodes types.Nodes,
Expand All @@ -542,6 +575,10 @@ func (pol *ACLPolicy) ExpandAlias(
return pol.expandIPsFromTag(alias, nodes)
}

if isAutoGroup(alias) {
return expandAutoGroup(alias)
}

// if alias is a user
if ips, err := pol.expandIPsFromUser(alias, nodes); ips != nil {
return ips, err
Expand Down Expand Up @@ -862,6 +899,16 @@ func (pol *ACLPolicy) expandIPsFromIPPrefix(
return build.IPSet()
}

func expandAutoGroup(alias string) (*netipx.IPSet, error) {
switch {
case strings.HasPrefix(alias, "autogroup:internet"):
return theInternet(), nil

default:
return nil, fmt.Errorf("unknown autogroup %q", alias)
}
}

func isWildcard(str string) bool {
return str == "*"
}
Expand All @@ -874,6 +921,10 @@ func isTag(str string) bool {
return strings.HasPrefix(str, "tag:")
}

func isAutoGroup(str string) bool {
return strings.HasPrefix(str, "autogroup:")
}

// TagsOfNode will return the tags of the current node.
// Invalid tags are tags added by a user on a node, and that user doesn't have authority to add this tag.
// Valid tags are tags added by a user that is allowed in the ACL policy to add this tag.
Expand Down
Loading

0 comments on commit 87e2ae4

Please sign in to comment.