mirror of
https://github.com/juanfont/headscale.git
synced 2025-08-17 16:17:30 +00:00
Compare commits
4 Commits
doc/0.24.1
...
more-acl-t
Author | SHA1 | Date | |
---|---|---|---|
![]() |
8426fe71e0 | ||
![]() |
0e28018637 | ||
![]() |
9e1c3c1688 | ||
![]() |
a7c608f0cb |
@@ -1,9 +1,10 @@
|
|||||||
# CHANGELOG
|
# CHANGELOG
|
||||||
|
|
||||||
## 0.17.0 (2022-XX-XX)
|
## 0.17.0 (2022-11-26)
|
||||||
|
|
||||||
### BREAKING
|
### BREAKING
|
||||||
|
|
||||||
|
- `noise.private_key_path` has been added and is required for the new noise protocol.
|
||||||
- Log level option `log_level` was moved to a distinct `log` config section and renamed to `level` [#768](https://github.com/juanfont/headscale/pull/768)
|
- Log level option `log_level` was moved to a distinct `log` config section and renamed to `level` [#768](https://github.com/juanfont/headscale/pull/768)
|
||||||
- Removed Alpine Linux container image [#962](https://github.com/juanfont/headscale/pull/962)
|
- Removed Alpine Linux container image [#962](https://github.com/juanfont/headscale/pull/962)
|
||||||
|
|
||||||
|
41
acls.go
41
acls.go
@@ -117,7 +117,16 @@ func (h *Headscale) LoadACLPolicy(path string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *Headscale) UpdateACLRules() error {
|
func (h *Headscale) UpdateACLRules() error {
|
||||||
rules, err := h.generateACLRules()
|
machines, err := h.ListMachines()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if h.aclPolicy == nil {
|
||||||
|
return errEmptyPolicy
|
||||||
|
}
|
||||||
|
|
||||||
|
rules, err := generateACLRules(machines, *h.aclPolicy, h.cfg.OIDC.StripEmaildomain)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -141,26 +150,17 @@ func (h *Headscale) UpdateACLRules() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Headscale) generateACLRules() ([]tailcfg.FilterRule, error) {
|
func generateACLRules(machines []Machine, aclPolicy ACLPolicy, stripEmaildomain bool) ([]tailcfg.FilterRule, error) {
|
||||||
rules := []tailcfg.FilterRule{}
|
rules := []tailcfg.FilterRule{}
|
||||||
|
|
||||||
if h.aclPolicy == nil {
|
for index, acl := range aclPolicy.ACLs {
|
||||||
return nil, errEmptyPolicy
|
|
||||||
}
|
|
||||||
|
|
||||||
machines, err := h.ListMachines()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
for index, acl := range h.aclPolicy.ACLs {
|
|
||||||
if acl.Action != "accept" {
|
if acl.Action != "accept" {
|
||||||
return nil, errInvalidAction
|
return nil, errInvalidAction
|
||||||
}
|
}
|
||||||
|
|
||||||
srcIPs := []string{}
|
srcIPs := []string{}
|
||||||
for innerIndex, src := range acl.Sources {
|
for innerIndex, src := range acl.Sources {
|
||||||
srcs, err := h.generateACLPolicySrcIP(machines, *h.aclPolicy, src)
|
srcs, err := generateACLPolicySrcIP(machines, aclPolicy, src, stripEmaildomain)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().
|
log.Error().
|
||||||
Msgf("Error parsing ACL %d, Source %d", index, innerIndex)
|
Msgf("Error parsing ACL %d, Source %d", index, innerIndex)
|
||||||
@@ -180,11 +180,12 @@ func (h *Headscale) generateACLRules() ([]tailcfg.FilterRule, error) {
|
|||||||
|
|
||||||
destPorts := []tailcfg.NetPortRange{}
|
destPorts := []tailcfg.NetPortRange{}
|
||||||
for innerIndex, dest := range acl.Destinations {
|
for innerIndex, dest := range acl.Destinations {
|
||||||
dests, err := h.generateACLPolicyDest(
|
dests, err := generateACLPolicyDest(
|
||||||
machines,
|
machines,
|
||||||
*h.aclPolicy,
|
aclPolicy,
|
||||||
dest,
|
dest,
|
||||||
needsWildcard,
|
needsWildcard,
|
||||||
|
stripEmaildomain,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().
|
log.Error().
|
||||||
@@ -310,19 +311,21 @@ func sshCheckAction(duration string) (*tailcfg.SSHAction, error) {
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Headscale) generateACLPolicySrcIP(
|
func generateACLPolicySrcIP(
|
||||||
machines []Machine,
|
machines []Machine,
|
||||||
aclPolicy ACLPolicy,
|
aclPolicy ACLPolicy,
|
||||||
src string,
|
src string,
|
||||||
|
stripEmaildomain bool,
|
||||||
) ([]string, error) {
|
) ([]string, error) {
|
||||||
return expandAlias(machines, aclPolicy, src, h.cfg.OIDC.StripEmaildomain)
|
return expandAlias(machines, aclPolicy, src, stripEmaildomain)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Headscale) generateACLPolicyDest(
|
func generateACLPolicyDest(
|
||||||
machines []Machine,
|
machines []Machine,
|
||||||
aclPolicy ACLPolicy,
|
aclPolicy ACLPolicy,
|
||||||
dest string,
|
dest string,
|
||||||
needsWildcard bool,
|
needsWildcard bool,
|
||||||
|
stripEmaildomain bool,
|
||||||
) ([]tailcfg.NetPortRange, error) {
|
) ([]tailcfg.NetPortRange, error) {
|
||||||
tokens := strings.Split(dest, ":")
|
tokens := strings.Split(dest, ":")
|
||||||
if len(tokens) < expectedTokenItems || len(tokens) > 3 {
|
if len(tokens) < expectedTokenItems || len(tokens) > 3 {
|
||||||
@@ -346,7 +349,7 @@ func (h *Headscale) generateACLPolicyDest(
|
|||||||
machines,
|
machines,
|
||||||
aclPolicy,
|
aclPolicy,
|
||||||
alias,
|
alias,
|
||||||
h.cfg.OIDC.StripEmaildomain,
|
stripEmaildomain,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
20
acls_test.go
20
acls_test.go
@@ -54,7 +54,7 @@ func (s *Suite) TestBasicRule(c *check.C) {
|
|||||||
err := app.LoadACLPolicy("./tests/acls/acl_policy_basic_1.hujson")
|
err := app.LoadACLPolicy("./tests/acls/acl_policy_basic_1.hujson")
|
||||||
c.Assert(err, check.IsNil)
|
c.Assert(err, check.IsNil)
|
||||||
|
|
||||||
rules, err := app.generateACLRules()
|
rules, err := generateACLRules([]Machine{}, *app.aclPolicy, false)
|
||||||
c.Assert(err, check.IsNil)
|
c.Assert(err, check.IsNil)
|
||||||
c.Assert(rules, check.NotNil)
|
c.Assert(rules, check.NotNil)
|
||||||
}
|
}
|
||||||
@@ -411,7 +411,7 @@ func (s *Suite) TestPortRange(c *check.C) {
|
|||||||
err := app.LoadACLPolicy("./tests/acls/acl_policy_basic_range.hujson")
|
err := app.LoadACLPolicy("./tests/acls/acl_policy_basic_range.hujson")
|
||||||
c.Assert(err, check.IsNil)
|
c.Assert(err, check.IsNil)
|
||||||
|
|
||||||
rules, err := app.generateACLRules()
|
rules, err := generateACLRules([]Machine{}, *app.aclPolicy, false)
|
||||||
c.Assert(err, check.IsNil)
|
c.Assert(err, check.IsNil)
|
||||||
c.Assert(rules, check.NotNil)
|
c.Assert(rules, check.NotNil)
|
||||||
|
|
||||||
@@ -425,7 +425,7 @@ func (s *Suite) TestProtocolParsing(c *check.C) {
|
|||||||
err := app.LoadACLPolicy("./tests/acls/acl_policy_basic_protocols.hujson")
|
err := app.LoadACLPolicy("./tests/acls/acl_policy_basic_protocols.hujson")
|
||||||
c.Assert(err, check.IsNil)
|
c.Assert(err, check.IsNil)
|
||||||
|
|
||||||
rules, err := app.generateACLRules()
|
rules, err := generateACLRules([]Machine{}, *app.aclPolicy, false)
|
||||||
c.Assert(err, check.IsNil)
|
c.Assert(err, check.IsNil)
|
||||||
c.Assert(rules, check.NotNil)
|
c.Assert(rules, check.NotNil)
|
||||||
|
|
||||||
@@ -439,7 +439,7 @@ func (s *Suite) TestPortWildcard(c *check.C) {
|
|||||||
err := app.LoadACLPolicy("./tests/acls/acl_policy_basic_wildcards.hujson")
|
err := app.LoadACLPolicy("./tests/acls/acl_policy_basic_wildcards.hujson")
|
||||||
c.Assert(err, check.IsNil)
|
c.Assert(err, check.IsNil)
|
||||||
|
|
||||||
rules, err := app.generateACLRules()
|
rules, err := generateACLRules([]Machine{}, *app.aclPolicy, false)
|
||||||
c.Assert(err, check.IsNil)
|
c.Assert(err, check.IsNil)
|
||||||
c.Assert(rules, check.NotNil)
|
c.Assert(rules, check.NotNil)
|
||||||
|
|
||||||
@@ -455,7 +455,7 @@ func (s *Suite) TestPortWildcardYAML(c *check.C) {
|
|||||||
err := app.LoadACLPolicy("./tests/acls/acl_policy_basic_wildcards.yaml")
|
err := app.LoadACLPolicy("./tests/acls/acl_policy_basic_wildcards.yaml")
|
||||||
c.Assert(err, check.IsNil)
|
c.Assert(err, check.IsNil)
|
||||||
|
|
||||||
rules, err := app.generateACLRules()
|
rules, err := generateACLRules([]Machine{}, *app.aclPolicy, false)
|
||||||
c.Assert(err, check.IsNil)
|
c.Assert(err, check.IsNil)
|
||||||
c.Assert(rules, check.NotNil)
|
c.Assert(rules, check.NotNil)
|
||||||
|
|
||||||
@@ -495,7 +495,10 @@ func (s *Suite) TestPortNamespace(c *check.C) {
|
|||||||
)
|
)
|
||||||
c.Assert(err, check.IsNil)
|
c.Assert(err, check.IsNil)
|
||||||
|
|
||||||
rules, err := app.generateACLRules()
|
machines, err := app.ListMachines()
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
|
|
||||||
|
rules, err := generateACLRules(machines, *app.aclPolicy, false)
|
||||||
c.Assert(err, check.IsNil)
|
c.Assert(err, check.IsNil)
|
||||||
c.Assert(rules, check.NotNil)
|
c.Assert(rules, check.NotNil)
|
||||||
|
|
||||||
@@ -535,7 +538,10 @@ func (s *Suite) TestPortGroup(c *check.C) {
|
|||||||
err = app.LoadACLPolicy("./tests/acls/acl_policy_basic_groups.hujson")
|
err = app.LoadACLPolicy("./tests/acls/acl_policy_basic_groups.hujson")
|
||||||
c.Assert(err, check.IsNil)
|
c.Assert(err, check.IsNil)
|
||||||
|
|
||||||
rules, err := app.generateACLRules()
|
machines, err := app.ListMachines()
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
|
|
||||||
|
rules, err := generateACLRules(machines, *app.aclPolicy, false)
|
||||||
c.Assert(err, check.IsNil)
|
c.Assert(err, check.IsNil)
|
||||||
c.Assert(rules, check.NotNil)
|
c.Assert(rules, check.NotNil)
|
||||||
|
|
||||||
|
@@ -122,6 +122,10 @@ func TestPingAllByHostname(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If subtests are parallel, then they will start before setup is run.
|
||||||
|
// This might mean we approach setup slightly wrong, but for now, ignore
|
||||||
|
// the linter
|
||||||
|
// nolint:tparallel
|
||||||
func TestTaildrop(t *testing.T) {
|
func TestTaildrop(t *testing.T) {
|
||||||
IntegrationSkip(t)
|
IntegrationSkip(t)
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
@@ -21,6 +21,10 @@ func IntegrationSkip(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If subtests are parallel, then they will start before setup is run.
|
||||||
|
// This might mean we approach setup slightly wrong, but for now, ignore
|
||||||
|
// the linter
|
||||||
|
// nolint:tparallel
|
||||||
func TestHeadscale(t *testing.T) {
|
func TestHeadscale(t *testing.T) {
|
||||||
IntegrationSkip(t)
|
IntegrationSkip(t)
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
@@ -70,6 +74,10 @@ func TestHeadscale(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If subtests are parallel, then they will start before setup is run.
|
||||||
|
// This might mean we approach setup slightly wrong, but for now, ignore
|
||||||
|
// the linter
|
||||||
|
// nolint:tparallel
|
||||||
func TestCreateTailscale(t *testing.T) {
|
func TestCreateTailscale(t *testing.T) {
|
||||||
IntegrationSkip(t)
|
IntegrationSkip(t)
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
@@ -104,6 +112,10 @@ func TestCreateTailscale(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If subtests are parallel, then they will start before setup is run.
|
||||||
|
// This might mean we approach setup slightly wrong, but for now, ignore
|
||||||
|
// the linter
|
||||||
|
// nolint:tparallel
|
||||||
func TestTailscaleNodesJoiningHeadcale(t *testing.T) {
|
func TestTailscaleNodesJoiningHeadcale(t *testing.T) {
|
||||||
IntegrationSkip(t)
|
IntegrationSkip(t)
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
@@ -220,8 +220,8 @@ func (h *Headscale) ApplePlatformConfig(
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch platform {
|
switch platform {
|
||||||
case "macos-standlone":
|
case "macos-standalone":
|
||||||
if err := macosStandloneTemplate.Execute(&payload, platformConfig); err != nil {
|
if err := macosStandaloneTemplate.Execute(&payload, platformConfig); err != nil {
|
||||||
handleMacError(err)
|
handleMacError(err)
|
||||||
|
|
||||||
return
|
return
|
||||||
@@ -390,7 +390,7 @@ var macosAppStoreTemplate = template.Must(template.New("macosTemplate").Parse(`
|
|||||||
</dict>
|
</dict>
|
||||||
`))
|
`))
|
||||||
|
|
||||||
var macosStandloneTemplate = template.Must(template.New("macosStandloneTemplate").Parse(`
|
var macosStandaloneTemplate = template.Must(template.New("macosStandaloneTemplate").Parse(`
|
||||||
<dict>
|
<dict>
|
||||||
<key>PayloadType</key>
|
<key>PayloadType</key>
|
||||||
<string>io.tailscale.ipn.macsys</string>
|
<string>io.tailscale.ipn.macsys</string>
|
||||||
|
@@ -92,7 +92,7 @@
|
|||||||
<code>defaults write io.tailscale.ipn.macos ControlURL {{.URL}}</code>
|
<code>defaults write io.tailscale.ipn.macos ControlURL {{.URL}}</code>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
for standlone client:
|
for standalone client:
|
||||||
<code>defaults write io.tailscale.ipn.macsys ControlURL {{.URL}}</code>
|
<code>defaults write io.tailscale.ipn.macsys ControlURL {{.URL}}</code>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
Reference in New Issue
Block a user