Skip to content

Commit

Permalink
Merge branch 'main' into sanitise-machine-key-url
Browse files Browse the repository at this point in the history
  • Loading branch information
kradalby authored Sep 23, 2022
2 parents 75a8fc8 + a507a04 commit d06ba7b
Show file tree
Hide file tree
Showing 29 changed files with 741 additions and 309 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
- Fix subnet routers with Primary Routes [#811](https://github.com/juanfont/headscale/pull/811)
- Added support for JSON logs [#653](https://github.com/juanfont/headscale/issues/653)
- Sanitise the node key passed to registration url [#823](https://github.com/juanfont/headscale/pull/823)
- Add support for generating pre-auth keys with tags [#767](https://github.com/juanfont/headscale/pull/767)
- Add support for evaluating `autoApprovers` ACL entries when a machine is registered [#763](https://github.com/juanfont/headscale/pull/763)

## 0.16.4 (2022-08-21)

Expand Down
12 changes: 6 additions & 6 deletions acls_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ func (s *Suite) TestValidExpandTagOwnersInSources(c *check.C) {
namespace, err := app.CreateNamespace("user1")
c.Assert(err, check.IsNil)

pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil)
pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil, nil)
c.Assert(err, check.IsNil)

_, err = app.GetMachine("user1", "testmachine")
Expand Down Expand Up @@ -164,7 +164,7 @@ func (s *Suite) TestValidExpandTagOwnersInDestinations(c *check.C) {
namespace, err := app.CreateNamespace("user1")
c.Assert(err, check.IsNil)

pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil)
pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil, nil)
c.Assert(err, check.IsNil)

_, err = app.GetMachine("user1", "testmachine")
Expand Down Expand Up @@ -214,7 +214,7 @@ func (s *Suite) TestInvalidTagValidNamespace(c *check.C) {
namespace, err := app.CreateNamespace("user1")
c.Assert(err, check.IsNil)

pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil)
pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil, nil)
c.Assert(err, check.IsNil)

_, err = app.GetMachine("user1", "testmachine")
Expand Down Expand Up @@ -263,7 +263,7 @@ func (s *Suite) TestValidTagInvalidNamespace(c *check.C) {
namespace, err := app.CreateNamespace("user1")
c.Assert(err, check.IsNil)

pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil)
pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil, nil)
c.Assert(err, check.IsNil)

_, err = app.GetMachine("user1", "webserver")
Expand Down Expand Up @@ -395,7 +395,7 @@ func (s *Suite) TestPortNamespace(c *check.C) {
namespace, err := app.CreateNamespace("testnamespace")
c.Assert(err, check.IsNil)

pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil)
pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil, nil)
c.Assert(err, check.IsNil)

_, err = app.GetMachine("testnamespace", "testmachine")
Expand Down Expand Up @@ -437,7 +437,7 @@ func (s *Suite) TestPortGroup(c *check.C) {
namespace, err := app.CreateNamespace("testnamespace")
c.Assert(err, check.IsNil)

pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil)
pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil, nil)
c.Assert(err, check.IsNil)

_, err = app.GetMachine("testnamespace", "testmachine")
Expand Down
43 changes: 38 additions & 5 deletions acls_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@ import (

// ACLPolicy represents a Tailscale ACL Policy.
type ACLPolicy struct {
Groups Groups `json:"groups" yaml:"groups"`
Hosts Hosts `json:"hosts" yaml:"hosts"`
TagOwners TagOwners `json:"tagOwners" yaml:"tagOwners"`
ACLs []ACL `json:"acls" yaml:"acls"`
Tests []ACLTest `json:"tests" yaml:"tests"`
Groups Groups `json:"groups" yaml:"groups"`
Hosts Hosts `json:"hosts" yaml:"hosts"`
TagOwners TagOwners `json:"tagOwners" yaml:"tagOwners"`
ACLs []ACL `json:"acls" yaml:"acls"`
Tests []ACLTest `json:"tests" yaml:"tests"`
AutoApprovers AutoApprovers `json:"autoApprovers" yaml:"autoApprovers"`
}

// ACL is a basic rule for the ACL Policy.
Expand All @@ -42,6 +43,13 @@ type ACLTest struct {
Deny []string `json:"deny,omitempty" yaml:"deny,omitempty"`
}

// AutoApprovers specify which users (namespaces?), groups or tags have their advertised routes
// or exit node status automatically enabled.
type AutoApprovers struct {
Routes map[string][]string `json:"routes" yaml:"routes"`
ExitNode []string `json:"exitNode" yaml:"exitNode"`
}

// UnmarshalJSON allows to parse the Hosts directly into netip objects.
func (hosts *Hosts) UnmarshalJSON(data []byte) error {
newHosts := Hosts{}
Expand Down Expand Up @@ -100,3 +108,28 @@ func (policy ACLPolicy) IsZero() bool {

return false
}

// Returns the list of autoApproving namespaces, groups or tags for a given IPPrefix.
func (autoApprovers *AutoApprovers) GetRouteApprovers(
prefix netip.Prefix,
) ([]string, error) {
if prefix.Bits() == 0 {
return autoApprovers.ExitNode, nil // 0.0.0.0/0, ::/0 or equivalent
}

approverAliases := []string{}

for autoApprovedPrefix, autoApproverAliases := range autoApprovers.Routes {
autoApprovedPrefix, err := netip.ParsePrefix(autoApprovedPrefix)
if err != nil {
return nil, err
}

if autoApprovedPrefix.Bits() >= prefix.Bits() &&
autoApprovedPrefix.Contains(prefix.Masked().Addr()) {
approverAliases = append(approverAliases, autoApproverAliases...)
}
}

return approverAliases, nil
}
25 changes: 24 additions & 1 deletion cmd/headscale/cli/preauthkeys.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package cli
import (
"fmt"
"strconv"
"strings"
"time"

v1 "github.com/juanfont/headscale/gen/go/headscale/v1"
Expand Down Expand Up @@ -33,6 +34,8 @@ func init() {
Bool("ephemeral", false, "Preauthkey for ephemeral nodes")
createPreAuthKeyCmd.Flags().
StringP("expiration", "e", DefaultPreAuthKeyExpiry, "Human-readable expiration of the key (e.g. 30m, 24h)")
createPreAuthKeyCmd.Flags().
StringSlice("tags", []string{}, "Tags to automatically assign to node")
}

var preauthkeysCmd = &cobra.Command{
Expand Down Expand Up @@ -81,7 +84,16 @@ var listPreAuthKeys = &cobra.Command{
}

tableData := pterm.TableData{
{"ID", "Key", "Reusable", "Ephemeral", "Used", "Expiration", "Created"},
{
"ID",
"Key",
"Reusable",
"Ephemeral",
"Used",
"Expiration",
"Created",
"Tags",
},
}
for _, key := range response.PreAuthKeys {
expiration := "-"
Expand All @@ -96,6 +108,14 @@ var listPreAuthKeys = &cobra.Command{
reusable = fmt.Sprintf("%v", key.GetReusable())
}

aclTags := ""

for _, tag := range key.AclTags {
aclTags += "," + tag
}

aclTags = strings.TrimLeft(aclTags, ",")

tableData = append(tableData, []string{
key.GetId(),
key.GetKey(),
Expand All @@ -104,6 +124,7 @@ var listPreAuthKeys = &cobra.Command{
strconv.FormatBool(key.GetUsed()),
expiration,
key.GetCreatedAt().AsTime().Format("2006-01-02 15:04:05"),
aclTags,
})

}
Expand Down Expand Up @@ -136,6 +157,7 @@ var createPreAuthKeyCmd = &cobra.Command{

reusable, _ := cmd.Flags().GetBool("reusable")
ephemeral, _ := cmd.Flags().GetBool("ephemeral")
tags, _ := cmd.Flags().GetStringSlice("tags")

log.Trace().
Bool("reusable", reusable).
Expand All @@ -147,6 +169,7 @@ var createPreAuthKeyCmd = &cobra.Command{
Namespace: namespace,
Reusable: reusable,
Ephemeral: ephemeral,
AclTags: tags,
}

durationStr, _ := cmd.Flags().GetString("expiration")
Expand Down
5 changes: 5 additions & 0 deletions db.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,11 @@ func (h *Headscale) initDB() error {
return err
}

err = db.AutoMigrate(&PreAuthKeyACLTag{})
if err != nil {
return err
}

_ = db.Migrator().DropTable("shared_machines")

err = db.AutoMigrate(&APIKey{})
Expand Down
8 changes: 8 additions & 0 deletions dns_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ func (s *Suite) TestDNSConfigMapResponseWithMagicDNS(c *check.C) {
false,
false,
nil,
nil,
)
c.Assert(err, check.IsNil)

Expand All @@ -134,6 +135,7 @@ func (s *Suite) TestDNSConfigMapResponseWithMagicDNS(c *check.C) {
false,
false,
nil,
nil,
)
c.Assert(err, check.IsNil)

Expand All @@ -142,6 +144,7 @@ func (s *Suite) TestDNSConfigMapResponseWithMagicDNS(c *check.C) {
false,
false,
nil,
nil,
)
c.Assert(err, check.IsNil)

Expand All @@ -150,6 +153,7 @@ func (s *Suite) TestDNSConfigMapResponseWithMagicDNS(c *check.C) {
false,
false,
nil,
nil,
)
c.Assert(err, check.IsNil)

Expand Down Expand Up @@ -269,6 +273,7 @@ func (s *Suite) TestDNSConfigMapResponseWithoutMagicDNS(c *check.C) {
false,
false,
nil,
nil,
)
c.Assert(err, check.IsNil)

Expand All @@ -277,6 +282,7 @@ func (s *Suite) TestDNSConfigMapResponseWithoutMagicDNS(c *check.C) {
false,
false,
nil,
nil,
)
c.Assert(err, check.IsNil)

Expand All @@ -285,6 +291,7 @@ func (s *Suite) TestDNSConfigMapResponseWithoutMagicDNS(c *check.C) {
false,
false,
nil,
nil,
)
c.Assert(err, check.IsNil)

Expand All @@ -293,6 +300,7 @@ func (s *Suite) TestDNSConfigMapResponseWithoutMagicDNS(c *check.C) {
false,
false,
nil,
nil,
)
c.Assert(err, check.IsNil)

Expand Down
2 changes: 1 addition & 1 deletion gen/go/headscale/v1/apikey.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion gen/go/headscale/v1/device.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion gen/go/headscale/v1/headscale.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit d06ba7b

Please sign in to comment.