mirror of
				https://github.com/juanfont/headscale.git
				synced 2025-11-04 01:51:04 +01:00 
			
		
		
		
	inline old acl hujson tests
Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
This commit is contained in:
		
							parent
							
								
									f2c1d1b8f9
								
							
						
					
					
						commit
						2d365c8c9c
					
				@ -59,8 +59,8 @@ const (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
var featureEnableSSH = envknob.RegisterBool("HEADSCALE_EXPERIMENTAL_FEATURE_SSH")
 | 
					var featureEnableSSH = envknob.RegisterBool("HEADSCALE_EXPERIMENTAL_FEATURE_SSH")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// LoadACLPolicy loads the ACL policy from the specify path, and generates the ACL rules.
 | 
					// LoadACLPolicyFromPath loads the ACL policy from the specify path, and generates the ACL rules.
 | 
				
			||||||
func (h *Headscale) LoadACLPolicy(path string) error {
 | 
					func (h *Headscale) LoadACLPolicyFromPath(path string) error {
 | 
				
			||||||
	log.Debug().
 | 
						log.Debug().
 | 
				
			||||||
		Str("func", "LoadACLPolicy").
 | 
							Str("func", "LoadACLPolicy").
 | 
				
			||||||
		Str("path", path).
 | 
							Str("path", path).
 | 
				
			||||||
@ -72,37 +72,42 @@ func (h *Headscale) LoadACLPolicy(path string) error {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	defer policyFile.Close()
 | 
						defer policyFile.Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var policy ACLPolicy
 | 
					 | 
				
			||||||
	policyBytes, err := io.ReadAll(policyFile)
 | 
						policyBytes, err := io.ReadAll(policyFile)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch filepath.Ext(path) {
 | 
					 | 
				
			||||||
	case ".yml", ".yaml":
 | 
					 | 
				
			||||||
	log.Debug().
 | 
						log.Debug().
 | 
				
			||||||
		Str("path", path).
 | 
							Str("path", path).
 | 
				
			||||||
		Bytes("file", policyBytes).
 | 
							Bytes("file", policyBytes).
 | 
				
			||||||
			Msg("Loading ACLs from YAML")
 | 
							Msg("Loading ACLs")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		err := yaml.Unmarshal(policyBytes, &policy)
 | 
						switch filepath.Ext(path) {
 | 
				
			||||||
 | 
						case ".yml", ".yaml":
 | 
				
			||||||
 | 
							return h.LoadACLPolicyFromBytes(policyBytes, "yaml")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return h.LoadACLPolicyFromBytes(policyBytes, "hujson")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (h *Headscale) LoadACLPolicyFromBytes(acl []byte, format string) error {
 | 
				
			||||||
 | 
						var policy ACLPolicy
 | 
				
			||||||
 | 
						switch format {
 | 
				
			||||||
 | 
						case "yaml":
 | 
				
			||||||
 | 
							err := yaml.Unmarshal(acl, &policy)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return err
 | 
								return err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		log.Trace().
 | 
					 | 
				
			||||||
			Interface("policy", policy).
 | 
					 | 
				
			||||||
			Msg("Loaded policy from YAML")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		ast, err := hujson.Parse(policyBytes)
 | 
							ast, err := hujson.Parse(acl)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return err
 | 
								return err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ast.Standardize()
 | 
							ast.Standardize()
 | 
				
			||||||
		policyBytes = ast.Pack()
 | 
							acl = ast.Pack()
 | 
				
			||||||
		err = json.Unmarshal(policyBytes, &policy)
 | 
							err = json.Unmarshal(acl, &policy)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return err
 | 
								return err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
				
			|||||||
@ -15,17 +15,26 @@ import (
 | 
				
			|||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (s *Suite) TestWrongPath(c *check.C) {
 | 
					func (s *Suite) TestWrongPath(c *check.C) {
 | 
				
			||||||
	err := app.LoadACLPolicy("asdfg")
 | 
						err := app.LoadACLPolicyFromPath("asdfg")
 | 
				
			||||||
	c.Assert(err, check.NotNil)
 | 
						c.Assert(err, check.NotNil)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (s *Suite) TestBrokenHuJson(c *check.C) {
 | 
					func (s *Suite) TestBrokenHuJson(c *check.C) {
 | 
				
			||||||
	err := app.LoadACLPolicy("./tests/acls/broken.hujson")
 | 
						acl := []byte(`
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						`)
 | 
				
			||||||
 | 
						err := app.LoadACLPolicyFromBytes(acl, "hujson")
 | 
				
			||||||
	c.Assert(err, check.NotNil)
 | 
						c.Assert(err, check.NotNil)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (s *Suite) TestInvalidPolicyHuson(c *check.C) {
 | 
					func (s *Suite) TestInvalidPolicyHuson(c *check.C) {
 | 
				
			||||||
	err := app.LoadACLPolicy("./tests/acls/invalid.hujson")
 | 
						acl := []byte(`
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    "valid_json": true,
 | 
				
			||||||
 | 
					    "but_a_policy_though": false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
						`)
 | 
				
			||||||
 | 
						err := app.LoadACLPolicyFromBytes(acl, "hujson")
 | 
				
			||||||
	c.Assert(err, check.NotNil)
 | 
						c.Assert(err, check.NotNil)
 | 
				
			||||||
	c.Assert(err, check.Equals, errEmptyPolicy)
 | 
						c.Assert(err, check.Equals, errEmptyPolicy)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -49,12 +58,161 @@ func (s *Suite) TestParseInvalidCIDR(c *check.C) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (s *Suite) TestRuleInvalidGeneration(c *check.C) {
 | 
					func (s *Suite) TestRuleInvalidGeneration(c *check.C) {
 | 
				
			||||||
	err := app.LoadACLPolicy("./tests/acls/acl_policy_invalid.hujson")
 | 
						acl := []byte(`
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    // 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",
 | 
				
			||||||
 | 
					            "example-host-1",
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    // 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",
 | 
				
			||||||
 | 
					            "src": [
 | 
				
			||||||
 | 
					                "group:engineering",
 | 
				
			||||||
 | 
					                "president@example.com"
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            "dst": [
 | 
				
			||||||
 | 
					                "*:22,3389",
 | 
				
			||||||
 | 
					                "git-server:*",
 | 
				
			||||||
 | 
					                "ci-server:*"
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        // Allow engineer users to access any port on a device tagged with
 | 
				
			||||||
 | 
					        // tag:production.
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "action": "accept",
 | 
				
			||||||
 | 
					            "src": [
 | 
				
			||||||
 | 
					                "group:engineers"
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            "dst": [
 | 
				
			||||||
 | 
					                "tag:production:*"
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        // Allow servers in the my-subnet host and 192.168.1.0/24 to access hosts
 | 
				
			||||||
 | 
					        // on both networks.
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "action": "accept",
 | 
				
			||||||
 | 
					            "src": [
 | 
				
			||||||
 | 
					                "my-subnet",
 | 
				
			||||||
 | 
					                "192.168.1.0/24"
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            "dst": [
 | 
				
			||||||
 | 
					                "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",
 | 
				
			||||||
 | 
					            "src": [
 | 
				
			||||||
 | 
					                "*"
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            "dst": [
 | 
				
			||||||
 | 
					                "*:*"
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        // All users in Montreal are allowed to access the Montreal web
 | 
				
			||||||
 | 
					        // servers.
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "action": "accept",
 | 
				
			||||||
 | 
					            "src": [
 | 
				
			||||||
 | 
					                "group:montreal-users"
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            "dst": [
 | 
				
			||||||
 | 
					                "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",
 | 
				
			||||||
 | 
					            "src": [
 | 
				
			||||||
 | 
					                "tag:montreal-webserver"
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            "dst": [
 | 
				
			||||||
 | 
					                "tag:api-server:443"
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    // Declare tests to check functionality of ACL rules
 | 
				
			||||||
 | 
					    "tests": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "src": "user1@example.com",
 | 
				
			||||||
 | 
					            "accept": [
 | 
				
			||||||
 | 
					                "example-host-1:22",
 | 
				
			||||||
 | 
					                "example-host-2:80"
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            "deny": [
 | 
				
			||||||
 | 
					                "exapmle-host-2:100"
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "src": "user2@example.com",
 | 
				
			||||||
 | 
					            "accept": [
 | 
				
			||||||
 | 
					                "100.60.3.4:22"
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
						`)
 | 
				
			||||||
 | 
						err := app.LoadACLPolicyFromBytes(acl, "hujson")
 | 
				
			||||||
	c.Assert(err, check.NotNil)
 | 
						c.Assert(err, check.NotNil)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (s *Suite) TestBasicRule(c *check.C) {
 | 
					func (s *Suite) TestBasicRule(c *check.C) {
 | 
				
			||||||
	err := app.LoadACLPolicy("./tests/acls/acl_policy_basic_1.hujson")
 | 
						acl := []byte(`
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    "hosts": {
 | 
				
			||||||
 | 
					        "host-1": "100.100.100.100",
 | 
				
			||||||
 | 
					        "subnet-1": "100.100.101.100/24",
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    "acls": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "action": "accept",
 | 
				
			||||||
 | 
					            "src": [
 | 
				
			||||||
 | 
					                "subnet-1",
 | 
				
			||||||
 | 
					                "192.168.1.0/24"
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            "dst": [
 | 
				
			||||||
 | 
					                "*:22,3389",
 | 
				
			||||||
 | 
					                "host-1:*",
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
						`)
 | 
				
			||||||
 | 
						err := app.LoadACLPolicyFromBytes(acl, "hujson")
 | 
				
			||||||
	c.Assert(err, check.IsNil)
 | 
						c.Assert(err, check.IsNil)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rules, err := app.aclPolicy.generateFilterRules([]Machine{}, false)
 | 
						rules, err := app.aclPolicy.generateFilterRules([]Machine{}, false)
 | 
				
			||||||
@ -411,7 +569,27 @@ func (s *Suite) TestValidTagInvalidUser(c *check.C) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (s *Suite) TestPortRange(c *check.C) {
 | 
					func (s *Suite) TestPortRange(c *check.C) {
 | 
				
			||||||
	err := app.LoadACLPolicy("./tests/acls/acl_policy_basic_range.hujson")
 | 
						acl := []byte(`
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    "hosts": {
 | 
				
			||||||
 | 
					        "host-1": "100.100.100.100",
 | 
				
			||||||
 | 
					        "subnet-1": "100.100.101.100/24",
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    "acls": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "action": "accept",
 | 
				
			||||||
 | 
					            "src": [
 | 
				
			||||||
 | 
					                "subnet-1",
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            "dst": [
 | 
				
			||||||
 | 
					                "host-1:5400-5500",
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
						`)
 | 
				
			||||||
 | 
						err := app.LoadACLPolicyFromBytes(acl, "hujson")
 | 
				
			||||||
	c.Assert(err, check.IsNil)
 | 
						c.Assert(err, check.IsNil)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rules, err := app.aclPolicy.generateFilterRules([]Machine{}, false)
 | 
						rules, err := app.aclPolicy.generateFilterRules([]Machine{}, false)
 | 
				
			||||||
@ -425,7 +603,48 @@ func (s *Suite) TestPortRange(c *check.C) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (s *Suite) TestProtocolParsing(c *check.C) {
 | 
					func (s *Suite) TestProtocolParsing(c *check.C) {
 | 
				
			||||||
	err := app.LoadACLPolicy("./tests/acls/acl_policy_basic_protocols.hujson")
 | 
						acl := []byte(`
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    "hosts": {
 | 
				
			||||||
 | 
					        "host-1": "100.100.100.100",
 | 
				
			||||||
 | 
					        "subnet-1": "100.100.101.100/24",
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    "acls": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "Action": "accept",
 | 
				
			||||||
 | 
					            "src": [
 | 
				
			||||||
 | 
					                "*",
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            "proto": "tcp",
 | 
				
			||||||
 | 
					            "dst": [
 | 
				
			||||||
 | 
					                "host-1:*",
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "Action": "accept",
 | 
				
			||||||
 | 
					            "src": [
 | 
				
			||||||
 | 
					                "*",
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            "proto": "udp",
 | 
				
			||||||
 | 
					            "dst": [
 | 
				
			||||||
 | 
					                "host-1:53",
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "Action": "accept",
 | 
				
			||||||
 | 
					            "src": [
 | 
				
			||||||
 | 
					                "*",
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            "proto": "icmp",
 | 
				
			||||||
 | 
					            "dst": [
 | 
				
			||||||
 | 
					                "host-1:*",
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
						`)
 | 
				
			||||||
 | 
						err := app.LoadACLPolicyFromBytes(acl, "hujson")
 | 
				
			||||||
	c.Assert(err, check.IsNil)
 | 
						c.Assert(err, check.IsNil)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rules, err := app.aclPolicy.generateFilterRules([]Machine{}, false)
 | 
						rules, err := app.aclPolicy.generateFilterRules([]Machine{}, false)
 | 
				
			||||||
@ -439,7 +658,27 @@ func (s *Suite) TestProtocolParsing(c *check.C) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (s *Suite) TestPortWildcard(c *check.C) {
 | 
					func (s *Suite) TestPortWildcard(c *check.C) {
 | 
				
			||||||
	err := app.LoadACLPolicy("./tests/acls/acl_policy_basic_wildcards.hujson")
 | 
						acl := []byte(`
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    "hosts": {
 | 
				
			||||||
 | 
					        "host-1": "100.100.100.100",
 | 
				
			||||||
 | 
					        "subnet-1": "100.100.101.100/24",
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    "acls": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "Action": "accept",
 | 
				
			||||||
 | 
					            "src": [
 | 
				
			||||||
 | 
					                "*",
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            "dst": [
 | 
				
			||||||
 | 
					                "host-1:*",
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
						`)
 | 
				
			||||||
 | 
						err := app.LoadACLPolicyFromBytes(acl, "hujson")
 | 
				
			||||||
	c.Assert(err, check.IsNil)
 | 
						c.Assert(err, check.IsNil)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rules, err := app.aclPolicy.generateFilterRules([]Machine{}, false)
 | 
						rules, err := app.aclPolicy.generateFilterRules([]Machine{}, false)
 | 
				
			||||||
@ -455,7 +694,19 @@ func (s *Suite) TestPortWildcard(c *check.C) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (s *Suite) TestPortWildcardYAML(c *check.C) {
 | 
					func (s *Suite) TestPortWildcardYAML(c *check.C) {
 | 
				
			||||||
	err := app.LoadACLPolicy("./tests/acls/acl_policy_basic_wildcards.yaml")
 | 
						acl := []byte(`
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					hosts:
 | 
				
			||||||
 | 
					  host-1: 100.100.100.100/32
 | 
				
			||||||
 | 
					  subnet-1: 100.100.101.100/24
 | 
				
			||||||
 | 
					acls:
 | 
				
			||||||
 | 
					  - action: accept
 | 
				
			||||||
 | 
					    src:
 | 
				
			||||||
 | 
					      - "*"
 | 
				
			||||||
 | 
					    dst:
 | 
				
			||||||
 | 
					      - host-1:*
 | 
				
			||||||
 | 
					`)
 | 
				
			||||||
 | 
						err := app.LoadACLPolicyFromBytes(acl, "yaml")
 | 
				
			||||||
	c.Assert(err, check.IsNil)
 | 
						c.Assert(err, check.IsNil)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rules, err := app.aclPolicy.generateFilterRules([]Machine{}, false)
 | 
						rules, err := app.aclPolicy.generateFilterRules([]Machine{}, false)
 | 
				
			||||||
@ -493,9 +744,27 @@ func (s *Suite) TestPortUser(c *check.C) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	app.db.Save(&machine)
 | 
						app.db.Save(&machine)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = app.LoadACLPolicy(
 | 
						acl := []byte(`
 | 
				
			||||||
		"./tests/acls/acl_policy_basic_user_as_user.hujson",
 | 
					{
 | 
				
			||||||
	)
 | 
					    "hosts": {
 | 
				
			||||||
 | 
					        "host-1": "100.100.100.100",
 | 
				
			||||||
 | 
					        "subnet-1": "100.100.101.100/24",
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    "acls": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "action": "accept",
 | 
				
			||||||
 | 
					            "src": [
 | 
				
			||||||
 | 
					                "testuser",
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            "dst": [
 | 
				
			||||||
 | 
					                "host-1:*",
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
						`)
 | 
				
			||||||
 | 
						err = app.LoadACLPolicyFromBytes(acl, "hujson")
 | 
				
			||||||
	c.Assert(err, check.IsNil)
 | 
						c.Assert(err, check.IsNil)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	machines, err := app.ListMachines()
 | 
						machines, err := app.ListMachines()
 | 
				
			||||||
@ -538,7 +807,33 @@ func (s *Suite) TestPortGroup(c *check.C) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	app.db.Save(&machine)
 | 
						app.db.Save(&machine)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = app.LoadACLPolicy("./tests/acls/acl_policy_basic_groups.hujson")
 | 
						acl := []byte(`
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    "groups": {
 | 
				
			||||||
 | 
					        "group:example": [
 | 
				
			||||||
 | 
					            "testuser",
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    "hosts": {
 | 
				
			||||||
 | 
					        "host-1": "100.100.100.100",
 | 
				
			||||||
 | 
					        "subnet-1": "100.100.101.100/24",
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    "acls": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "action": "accept",
 | 
				
			||||||
 | 
					            "src": [
 | 
				
			||||||
 | 
					                "group:example",
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            "dst": [
 | 
				
			||||||
 | 
					                "host-1:*",
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
						`)
 | 
				
			||||||
 | 
						err = app.LoadACLPolicyFromBytes(acl, "hujson")
 | 
				
			||||||
	c.Assert(err, check.IsNil)
 | 
						c.Assert(err, check.IsNil)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	machines, err := app.ListMachines()
 | 
						machines, err := app.ListMachines()
 | 
				
			||||||
 | 
				
			|||||||
@ -21,6 +21,7 @@ import (
 | 
				
			|||||||
	"github.com/gorilla/mux"
 | 
						"github.com/gorilla/mux"
 | 
				
			||||||
	grpcMiddleware "github.com/grpc-ecosystem/go-grpc-middleware"
 | 
						grpcMiddleware "github.com/grpc-ecosystem/go-grpc-middleware"
 | 
				
			||||||
	"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
 | 
						"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
 | 
				
			||||||
 | 
						"github.com/juanfont/headscale"
 | 
				
			||||||
	v1 "github.com/juanfont/headscale/gen/go/headscale/v1"
 | 
						v1 "github.com/juanfont/headscale/gen/go/headscale/v1"
 | 
				
			||||||
	"github.com/patrickmn/go-cache"
 | 
						"github.com/patrickmn/go-cache"
 | 
				
			||||||
	zerolog "github.com/philip-bui/grpc-zerolog"
 | 
						zerolog "github.com/philip-bui/grpc-zerolog"
 | 
				
			||||||
@ -507,8 +508,10 @@ func (h *Headscale) createRouter(grpcMux *runtime.ServeMux) *mux.Router {
 | 
				
			|||||||
	router.HandleFunc("/windows", h.WindowsConfigMessage).Methods(http.MethodGet)
 | 
						router.HandleFunc("/windows", h.WindowsConfigMessage).Methods(http.MethodGet)
 | 
				
			||||||
	router.HandleFunc("/windows/tailscale.reg", h.WindowsRegConfig).
 | 
						router.HandleFunc("/windows/tailscale.reg", h.WindowsRegConfig).
 | 
				
			||||||
		Methods(http.MethodGet)
 | 
							Methods(http.MethodGet)
 | 
				
			||||||
	router.HandleFunc("/swagger", SwaggerUI).Methods(http.MethodGet)
 | 
					
 | 
				
			||||||
	router.HandleFunc("/swagger/v1/openapiv2.json", SwaggerAPIv1).
 | 
						// TODO(kristoffer): move swagger into a package
 | 
				
			||||||
 | 
						router.HandleFunc("/swagger", headscale.SwaggerUI).Methods(http.MethodGet)
 | 
				
			||||||
 | 
						router.HandleFunc("/swagger/v1/openapiv2.json", headscale.SwaggerAPIv1).
 | 
				
			||||||
		Methods(http.MethodGet)
 | 
							Methods(http.MethodGet)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if h.cfg.DERP.ServerEnabled {
 | 
						if h.cfg.DERP.ServerEnabled {
 | 
				
			||||||
@ -758,7 +761,7 @@ func (h *Headscale) Serve() error {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
				if h.cfg.ACL.PolicyPath != "" {
 | 
									if h.cfg.ACL.PolicyPath != "" {
 | 
				
			||||||
					aclPath := AbsolutePathFromConfigPath(h.cfg.ACL.PolicyPath)
 | 
										aclPath := AbsolutePathFromConfigPath(h.cfg.ACL.PolicyPath)
 | 
				
			||||||
					err := h.LoadACLPolicy(aclPath)
 | 
										err := h.LoadACLPolicyFromPath(aclPath)
 | 
				
			||||||
					if err != nil {
 | 
										if err != nil {
 | 
				
			||||||
						log.Error().Err(err).Msg("Failed to reload ACL policy")
 | 
											log.Error().Err(err).Msg("Failed to reload ACL policy")
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
 | 
				
			|||||||
@ -1212,7 +1212,31 @@ func TestHeadscale_generateGivenName(t *testing.T) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (s *Suite) TestAutoApproveRoutes(c *check.C) {
 | 
					func (s *Suite) TestAutoApproveRoutes(c *check.C) {
 | 
				
			||||||
	err := app.LoadACLPolicy("./tests/acls/acl_policy_autoapprovers.hujson")
 | 
						acl := []byte(`
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    "tagOwners": {
 | 
				
			||||||
 | 
					        "tag:exit": ["test"],
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    "groups": {
 | 
				
			||||||
 | 
					        "group:test": ["test"]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    "acls": [
 | 
				
			||||||
 | 
					        {"action": "accept", "users": ["*"], "ports": ["*:*"]},
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    "autoApprovers": {
 | 
				
			||||||
 | 
					        "exitNode": ["tag:exit"],
 | 
				
			||||||
 | 
					        "routes": {
 | 
				
			||||||
 | 
					            "10.10.0.0/16": ["group:test"],
 | 
				
			||||||
 | 
					            "10.11.0.0/16": ["test"],
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
						`)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						err := app.LoadACLPolicyFromBytes(acl, "hujson")
 | 
				
			||||||
	c.Assert(err, check.IsNil)
 | 
						c.Assert(err, check.IsNil)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	user, err := app.CreateUser("test")
 | 
						user, err := app.CreateUser("test")
 | 
				
			||||||
 | 
				
			|||||||
@ -1,127 +0,0 @@
 | 
				
			|||||||
{
 | 
					 | 
				
			||||||
    // Declare static groups of users beyond those in the identity service.
 | 
					 | 
				
			||||||
    "groups": {
 | 
					 | 
				
			||||||
        "group:example": [
 | 
					 | 
				
			||||||
            "user1@example.com",
 | 
					 | 
				
			||||||
            "user2@example.com",
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
        "group:example2": [
 | 
					 | 
				
			||||||
            "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:example",
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
        // Only a few admins are allowed to create API servers.
 | 
					 | 
				
			||||||
        "tag:production": [
 | 
					 | 
				
			||||||
            "group:example",
 | 
					 | 
				
			||||||
            "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",
 | 
					 | 
				
			||||||
            "src": [
 | 
					 | 
				
			||||||
                "group:example2",
 | 
					 | 
				
			||||||
                "192.168.1.0/24"
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
            "dst": [
 | 
					 | 
				
			||||||
                "*:22,3389",
 | 
					 | 
				
			||||||
                "git-server:*",
 | 
					 | 
				
			||||||
                "ci-server:*"
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        // Allow engineer users to access any port on a device tagged with
 | 
					 | 
				
			||||||
        // tag:production.
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            "action": "accept",
 | 
					 | 
				
			||||||
            "src": [
 | 
					 | 
				
			||||||
                "group:example"
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
            "dst": [
 | 
					 | 
				
			||||||
                "tag:production:*"
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        // Allow servers in the my-subnet host and 192.168.1.0/24 to access hosts
 | 
					 | 
				
			||||||
        // on both networks.
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            "action": "accept",
 | 
					 | 
				
			||||||
            "src": [
 | 
					 | 
				
			||||||
                "example-host-2", 
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
            "dst": [
 | 
					 | 
				
			||||||
                "example-host-1:*",
 | 
					 | 
				
			||||||
                "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",
 | 
					 | 
				
			||||||
            "src": [
 | 
					 | 
				
			||||||
                "*"
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
            "dst": [
 | 
					 | 
				
			||||||
                "*:*"
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        // All users in Montreal are allowed to access the Montreal web
 | 
					 | 
				
			||||||
        // servers.
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            "action": "accept",
 | 
					 | 
				
			||||||
            "src": [
 | 
					 | 
				
			||||||
                "example-host-1"
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
            "dst": [
 | 
					 | 
				
			||||||
                "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",
 | 
					 | 
				
			||||||
            "src": [
 | 
					 | 
				
			||||||
                "tag:montreal-webserver"
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
            "dst": [
 | 
					 | 
				
			||||||
                "tag:api-server:443"
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    // Declare tests to check functionality of ACL rules
 | 
					 | 
				
			||||||
    "tests": [
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            "src": "user1@example.com",
 | 
					 | 
				
			||||||
            "accept": [
 | 
					 | 
				
			||||||
                "example-host-1:22",
 | 
					 | 
				
			||||||
                "example-host-2:80"
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
            "deny": [
 | 
					 | 
				
			||||||
                "exapmle-host-2:100"
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            "src": "user2@example.com",
 | 
					 | 
				
			||||||
            "accept": [
 | 
					 | 
				
			||||||
                "100.60.3.4:22"
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,24 +0,0 @@
 | 
				
			|||||||
// This ACL validates autoApprovers support for
 | 
					 | 
				
			||||||
// exit nodes and advertised routes
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    "tagOwners": {
 | 
					 | 
				
			||||||
        "tag:exit": ["test"],
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    "groups": {
 | 
					 | 
				
			||||||
        "group:test": ["test"]
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    "acls": [
 | 
					 | 
				
			||||||
        {"action": "accept", "users": ["*"], "ports": ["*:*"]},
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    "autoApprovers": {
 | 
					 | 
				
			||||||
        "exitNode": ["tag:exit"],
 | 
					 | 
				
			||||||
        "routes": {
 | 
					 | 
				
			||||||
            "10.10.0.0/16": ["group:test"],
 | 
					 | 
				
			||||||
            "10.11.0.0/16": ["test"],
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,24 +0,0 @@
 | 
				
			|||||||
// This ACL is a very basic example to validate the 
 | 
					 | 
				
			||||||
// expansion of hosts
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    "hosts": {
 | 
					 | 
				
			||||||
        "host-1": "100.100.100.100",
 | 
					 | 
				
			||||||
        "subnet-1": "100.100.101.100/24",
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    "acls": [
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            "action": "accept",
 | 
					 | 
				
			||||||
            "src": [
 | 
					 | 
				
			||||||
                "subnet-1",
 | 
					 | 
				
			||||||
                "192.168.1.0/24"
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
            "dst": [
 | 
					 | 
				
			||||||
                "*:22,3389",
 | 
					 | 
				
			||||||
                "host-1:*",
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,26 +0,0 @@
 | 
				
			|||||||
// This ACL is used to test group expansion
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    "groups": {
 | 
					 | 
				
			||||||
        "group:example": [
 | 
					 | 
				
			||||||
            "testuser",
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    "hosts": {
 | 
					 | 
				
			||||||
        "host-1": "100.100.100.100",
 | 
					 | 
				
			||||||
        "subnet-1": "100.100.101.100/24",
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    "acls": [
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            "action": "accept",
 | 
					 | 
				
			||||||
            "src": [
 | 
					 | 
				
			||||||
                "group:example",
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
            "dst": [
 | 
					 | 
				
			||||||
                "host-1:*",
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,41 +0,0 @@
 | 
				
			|||||||
// This ACL is used to test wildcards
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    "hosts": {
 | 
					 | 
				
			||||||
        "host-1": "100.100.100.100",
 | 
					 | 
				
			||||||
        "subnet-1": "100.100.101.100/24",
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    "acls": [
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            "Action": "accept",
 | 
					 | 
				
			||||||
            "src": [
 | 
					 | 
				
			||||||
                "*",
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
            "proto": "tcp",
 | 
					 | 
				
			||||||
            "dst": [
 | 
					 | 
				
			||||||
                "host-1:*",
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            "Action": "accept",
 | 
					 | 
				
			||||||
            "src": [
 | 
					 | 
				
			||||||
                "*",
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
            "proto": "udp",
 | 
					 | 
				
			||||||
            "dst": [
 | 
					 | 
				
			||||||
                "host-1:53",
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            "Action": "accept",
 | 
					 | 
				
			||||||
            "src": [
 | 
					 | 
				
			||||||
                "*",
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
            "proto": "icmp",
 | 
					 | 
				
			||||||
            "dst": [
 | 
					 | 
				
			||||||
                "host-1:*",
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,20 +0,0 @@
 | 
				
			|||||||
// This ACL is used to test the port range expansion
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    "hosts": {
 | 
					 | 
				
			||||||
        "host-1": "100.100.100.100",
 | 
					 | 
				
			||||||
        "subnet-1": "100.100.101.100/24",
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    "acls": [
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            "action": "accept",
 | 
					 | 
				
			||||||
            "src": [
 | 
					 | 
				
			||||||
                "subnet-1",
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
            "dst": [
 | 
					 | 
				
			||||||
                "host-1:5400-5500",
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,20 +0,0 @@
 | 
				
			|||||||
// This ACL is used to test namespace expansion
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    "hosts": {
 | 
					 | 
				
			||||||
        "host-1": "100.100.100.100",
 | 
					 | 
				
			||||||
        "subnet-1": "100.100.101.100/24",
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    "acls": [
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            "action": "accept",
 | 
					 | 
				
			||||||
            "src": [
 | 
					 | 
				
			||||||
                "testuser",
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
            "dst": [
 | 
					 | 
				
			||||||
                "host-1:*",
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,20 +0,0 @@
 | 
				
			|||||||
// This ACL is used to test wildcards
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    "hosts": {
 | 
					 | 
				
			||||||
        "host-1": "100.100.100.100",
 | 
					 | 
				
			||||||
        "subnet-1": "100.100.101.100/24",
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    "acls": [
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            "Action": "accept",
 | 
					 | 
				
			||||||
            "src": [
 | 
					 | 
				
			||||||
                "*",
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
            "dst": [
 | 
					 | 
				
			||||||
                "host-1:*",
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,10 +0,0 @@
 | 
				
			|||||||
---
 | 
					 | 
				
			||||||
hosts:
 | 
					 | 
				
			||||||
  host-1: 100.100.100.100/32
 | 
					 | 
				
			||||||
  subnet-1: 100.100.101.100/24
 | 
					 | 
				
			||||||
acls:
 | 
					 | 
				
			||||||
  - action: accept
 | 
					 | 
				
			||||||
    src:
 | 
					 | 
				
			||||||
      - "*"
 | 
					 | 
				
			||||||
    dst:
 | 
					 | 
				
			||||||
      - host-1:*
 | 
					 | 
				
			||||||
@ -1,125 +0,0 @@
 | 
				
			|||||||
{
 | 
					 | 
				
			||||||
    // 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",
 | 
					 | 
				
			||||||
            "example-host-1",
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    // 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",
 | 
					 | 
				
			||||||
            "src": [
 | 
					 | 
				
			||||||
                "group:engineering",
 | 
					 | 
				
			||||||
                "president@example.com"
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
            "dst": [
 | 
					 | 
				
			||||||
                "*:22,3389",
 | 
					 | 
				
			||||||
                "git-server:*",
 | 
					 | 
				
			||||||
                "ci-server:*"
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        // Allow engineer users to access any port on a device tagged with
 | 
					 | 
				
			||||||
        // tag:production.
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            "action": "accept",
 | 
					 | 
				
			||||||
            "src": [
 | 
					 | 
				
			||||||
                "group:engineers"
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
            "dst": [
 | 
					 | 
				
			||||||
                "tag:production:*"
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        // Allow servers in the my-subnet host and 192.168.1.0/24 to access hosts
 | 
					 | 
				
			||||||
        // on both networks.
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            "action": "accept",
 | 
					 | 
				
			||||||
            "src": [
 | 
					 | 
				
			||||||
                "my-subnet",
 | 
					 | 
				
			||||||
                "192.168.1.0/24"
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
            "dst": [
 | 
					 | 
				
			||||||
                "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",
 | 
					 | 
				
			||||||
            "src": [
 | 
					 | 
				
			||||||
                "*"
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
            "dst": [
 | 
					 | 
				
			||||||
                "*:*"
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        // All users in Montreal are allowed to access the Montreal web
 | 
					 | 
				
			||||||
        // servers.
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            "action": "accept",
 | 
					 | 
				
			||||||
            "src": [
 | 
					 | 
				
			||||||
                "group:montreal-users"
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
            "dst": [
 | 
					 | 
				
			||||||
                "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",
 | 
					 | 
				
			||||||
            "src": [
 | 
					 | 
				
			||||||
                "tag:montreal-webserver"
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
            "dst": [
 | 
					 | 
				
			||||||
                "tag:api-server:443"
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    // Declare tests to check functionality of ACL rules
 | 
					 | 
				
			||||||
    "tests": [
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            "src": "user1@example.com",
 | 
					 | 
				
			||||||
            "accept": [
 | 
					 | 
				
			||||||
                "example-host-1:22",
 | 
					 | 
				
			||||||
                "example-host-2:80"
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
            "deny": [
 | 
					 | 
				
			||||||
                "exapmle-host-2:100"
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            "src": "user2@example.com",
 | 
					 | 
				
			||||||
            "accept": [
 | 
					 | 
				
			||||||
                "100.60.3.4:22"
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1 +0,0 @@
 | 
				
			|||||||
{
 | 
					 | 
				
			||||||
@ -1,4 +0,0 @@
 | 
				
			|||||||
{
 | 
					 | 
				
			||||||
    "valid_json": true,
 | 
					 | 
				
			||||||
    "but_a_policy_though": false
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user