-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
252 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package headscale | ||
|
||
import ( | ||
"io" | ||
"os" | ||
|
||
"github.com/tailscale/hujson" | ||
) | ||
|
||
const errorInvalidPolicy = Error("invalid policy") | ||
|
||
func (h *Headscale) ParsePolicy(path string) (*ACLPolicy, error) { | ||
policyFile, err := os.Open(path) | ||
if err != nil { | ||
return nil, err | ||
} | ||
defer policyFile.Close() | ||
|
||
var policy ACLPolicy | ||
b, err := io.ReadAll(policyFile) | ||
if err != nil { | ||
return nil, err | ||
} | ||
err = hujson.Unmarshal(b, &policy) | ||
if policy.IsZero() { | ||
return nil, errorInvalidPolicy | ||
} | ||
|
||
return &policy, err | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package headscale | ||
|
||
import ( | ||
"gopkg.in/check.v1" | ||
) | ||
|
||
func (s *Suite) TestWrongPath(c *check.C) { | ||
_, err := h.ParsePolicy("asdfg") | ||
c.Assert(err, check.NotNil) | ||
} | ||
|
||
func (s *Suite) TestBrokenHuJson(c *check.C) { | ||
_, err := h.ParsePolicy("./tests/acls/broken.hujson") | ||
c.Assert(err, check.NotNil) | ||
|
||
} | ||
|
||
func (s *Suite) TestInvalidPolicyHuson(c *check.C) { | ||
_, err := h.ParsePolicy("./tests/acls/invalid.hujson") | ||
c.Assert(err, check.NotNil) | ||
c.Assert(err, check.Equals, errorInvalidPolicy) | ||
} | ||
|
||
func (s *Suite) TestValidCheckHosts(c *check.C) { | ||
p, err := h.ParsePolicy("./tests/acls/acl_policy_1.hujson") | ||
c.Assert(err, check.IsNil) | ||
c.Assert(p, check.NotNil) | ||
c.Assert(p.IsZero(), check.Equals, false) | ||
|
||
hosts, err := p.GetHosts() | ||
c.Assert(err, check.IsNil) | ||
c.Assert(*hosts, check.HasLen, 2) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package headscale | ||
|
||
import ( | ||
"strings" | ||
|
||
"inet.af/netaddr" | ||
) | ||
|
||
type ACLPolicy struct { | ||
Groups Groups `json:"Groups"` | ||
Hosts Hosts `json:"Hosts"` | ||
TagOwners TagOwners `json:"TagOwners"` | ||
ACLs []ACL `json:"ACLs"` | ||
Tests []ACLTest `json:"Tests"` | ||
} | ||
|
||
type ACL struct { | ||
Action string `json:"Action"` | ||
Users []string `json:"Users"` | ||
Ports []string `json:"Ports"` | ||
} | ||
|
||
type Groups map[string][]string | ||
|
||
type Hosts map[string]string | ||
|
||
type TagOwners struct { | ||
TagMontrealWebserver []string `json:"tag:montreal-webserver"` | ||
TagAPIServer []string `json:"tag:api-server"` | ||
} | ||
|
||
type ACLTest struct { | ||
User string `json:"User"` | ||
Allow []string `json:"Allow"` | ||
Deny []string `json:"Deny,omitempty"` | ||
} | ||
|
||
// IsZero is perhaps a bit naive here | ||
func (p ACLPolicy) IsZero() bool { | ||
if len(p.Groups) == 0 && len(p.Hosts) == 0 && len(p.ACLs) == 0 { | ||
return true | ||
} | ||
return false | ||
} | ||
|
||
func (p ACLPolicy) GetHosts() (*map[string]netaddr.IPPrefix, error) { | ||
hosts := make(map[string]netaddr.IPPrefix) | ||
for k, v := range p.Hosts { | ||
if !strings.Contains(v, "/") { | ||
v = v + "/32" | ||
} | ||
prefix, err := netaddr.ParseIPPrefix(v) | ||
if err != nil { | ||
return nil, err | ||
} | ||
hosts[k] = prefix | ||
} | ||
return &hosts, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
{ | ||
// Declare static groups of users beyond those in the identity service. | ||
"Groups": { | ||
"group:example": [ | ||
"user1@example.com", | ||
"user2@example.com", | ||
], | ||
}, | ||
// Declare hostname aliases to use in place of IP addresses or subnets. | ||
"Hosts": { | ||
"example-host-1": "100.100.100.100", | ||
"example-host-2": "100.100.101.100/24", | ||
}, | ||
// Define who is allowed to use which tags. | ||
"TagOwners": { | ||
// Everyone in the montreal-admins or global-admins group are | ||
// allowed to tag servers as montreal-webserver. | ||
"tag:montreal-webserver": [ | ||
"group:montreal-admins", | ||
"group:global-admins", | ||
], | ||
// Only a few admins are allowed to create API servers. | ||
"tag:api-server": [ | ||
"group:global-admins", | ||
"president@example.com", | ||
], | ||
}, | ||
// Access control lists. | ||
"ACLs": [ | ||
// Engineering users, plus the president, can access port 22 (ssh) | ||
// and port 3389 (remote desktop protocol) on all servers, and all | ||
// ports on git-server or ci-server. | ||
{ | ||
"Action": "accept", | ||
"Users": [ | ||
"group:engineering", | ||
"president@example.com" | ||
], | ||
"Ports": [ | ||
"*:22,3389", | ||
"git-server:*", | ||
"ci-server:*" | ||
], | ||
}, | ||
// Allow engineer users to access any port on a device tagged with | ||
// tag:production. | ||
{ | ||
"Action": "accept", | ||
"Users": [ | ||
"group:engineers" | ||
], | ||
"Ports": [ | ||
"tag:production:*" | ||
], | ||
}, | ||
// Allow servers in the my-subnet host and 192.168.1.0/24 to access hosts | ||
// on both networks. | ||
{ | ||
"Action": "accept", | ||
"Users": [ | ||
"my-subnet", | ||
"192.168.1.0/24" | ||
], | ||
"Ports": [ | ||
"my-subnet:*", | ||
"192.168.1.0/24:*" | ||
], | ||
}, | ||
// Allow every user of your network to access anything on the network. | ||
// Comment out this section if you want to define specific ACL | ||
// restrictions above. | ||
{ | ||
"Action": "accept", | ||
"Users": [ | ||
"*" | ||
], | ||
"Ports": [ | ||
"*:*" | ||
], | ||
}, | ||
// All users in Montreal are allowed to access the Montreal web | ||
// servers. | ||
{ | ||
"Action": "accept", | ||
"Users": [ | ||
"group:montreal-users" | ||
], | ||
"Ports": [ | ||
"tag:montreal-webserver:80,443" | ||
], | ||
}, | ||
// Montreal web servers are allowed to make outgoing connections to | ||
// the API servers, but only on https port 443. | ||
// In contrast, this doesn't grant API servers the right to initiate | ||
// any connections. | ||
{ | ||
"Action": "accept", | ||
"Users": [ | ||
"tag:montreal-webserver" | ||
], | ||
"Ports": [ | ||
"tag:api-server:443" | ||
], | ||
}, | ||
], | ||
// Declare tests to check functionality of ACL rules | ||
"Tests": [ | ||
{ | ||
"User": "user1@example.com", | ||
"Allow": [ | ||
"example-host-1:22", | ||
"example-host-2:80" | ||
], | ||
"Deny": [ | ||
"exapmle-host-2:100" | ||
], | ||
}, | ||
{ | ||
"User": "user2@example.com", | ||
"Allow": [ | ||
"100.60.3.4:22" | ||
], | ||
}, | ||
], | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"valid_json": true, | ||
"but_a_policy_though": false | ||
} |