diff --git a/hscontrol/acls.go b/hscontrol/acls.go index 1f411a4b..449c7ffd 100644 --- a/hscontrol/acls.go +++ b/hscontrol/acls.go @@ -59,8 +59,8 @@ const ( var featureEnableSSH = envknob.RegisterBool("HEADSCALE_EXPERIMENTAL_FEATURE_SSH") -// LoadACLPolicy loads the ACL policy from the specify path, and generates the ACL rules. -func (h *Headscale) LoadACLPolicy(path string) error { +// LoadACLPolicyFromPath loads the ACL policy from the specify path, and generates the ACL rules. +func (h *Headscale) LoadACLPolicyFromPath(path string) error { log.Debug(). Str("func", "LoadACLPolicy"). Str("path", path). @@ -72,37 +72,42 @@ func (h *Headscale) LoadACLPolicy(path string) error { } defer policyFile.Close() - var policy ACLPolicy policyBytes, err := io.ReadAll(policyFile) if err != nil { return err } + log.Debug(). + Str("path", path). + Bytes("file", policyBytes). + Msg("Loading ACLs") + switch filepath.Ext(path) { case ".yml", ".yaml": - log.Debug(). - Str("path", path). - Bytes("file", policyBytes). - Msg("Loading ACLs from YAML") + return h.LoadACLPolicyFromBytes(policyBytes, "yaml") + } - err := yaml.Unmarshal(policyBytes, &policy) + 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 { return err } - log.Trace(). - Interface("policy", policy). - Msg("Loaded policy from YAML") - default: - ast, err := hujson.Parse(policyBytes) + ast, err := hujson.Parse(acl) if err != nil { return err } ast.Standardize() - policyBytes = ast.Pack() - err = json.Unmarshal(policyBytes, &policy) + acl = ast.Pack() + err = json.Unmarshal(acl, &policy) if err != nil { return err } diff --git a/hscontrol/acls_test.go b/hscontrol/acls_test.go index a065bf7d..095597f2 100644 --- a/hscontrol/acls_test.go +++ b/hscontrol/acls_test.go @@ -15,17 +15,26 @@ import ( ) func (s *Suite) TestWrongPath(c *check.C) { - err := app.LoadACLPolicy("asdfg") + err := app.LoadACLPolicyFromPath("asdfg") c.Assert(err, check.NotNil) } 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) } 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.Equals, errEmptyPolicy) } @@ -49,12 +58,161 @@ func (s *Suite) TestParseInvalidCIDR(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) } 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) 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) { - 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) 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) { - 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) 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) { - 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) 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) { - 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) rules, err := app.aclPolicy.generateFilterRules([]Machine{}, false) @@ -493,9 +744,27 @@ func (s *Suite) TestPortUser(c *check.C) { } app.db.Save(&machine) - err = app.LoadACLPolicy( - "./tests/acls/acl_policy_basic_user_as_user.hujson", - ) + acl := []byte(` +{ + "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) machines, err := app.ListMachines() @@ -538,7 +807,33 @@ func (s *Suite) TestPortGroup(c *check.C) { } 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) machines, err := app.ListMachines() diff --git a/hscontrol/app.go b/hscontrol/app.go index 430c8ab4..b8dceba8 100644 --- a/hscontrol/app.go +++ b/hscontrol/app.go @@ -21,6 +21,7 @@ import ( "github.com/gorilla/mux" grpcMiddleware "github.com/grpc-ecosystem/go-grpc-middleware" "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" + "github.com/juanfont/headscale" v1 "github.com/juanfont/headscale/gen/go/headscale/v1" "github.com/patrickmn/go-cache" 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/tailscale.reg", h.WindowsRegConfig). 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) if h.cfg.DERP.ServerEnabled { @@ -758,7 +761,7 @@ func (h *Headscale) Serve() error { if h.cfg.ACL.PolicyPath != "" { aclPath := AbsolutePathFromConfigPath(h.cfg.ACL.PolicyPath) - err := h.LoadACLPolicy(aclPath) + err := h.LoadACLPolicyFromPath(aclPath) if err != nil { log.Error().Err(err).Msg("Failed to reload ACL policy") } diff --git a/hscontrol/machine_test.go b/hscontrol/machine_test.go index 87ca7600..3f11da4b 100644 --- a/hscontrol/machine_test.go +++ b/hscontrol/machine_test.go @@ -1212,7 +1212,31 @@ func TestHeadscale_generateGivenName(t *testing.T) { } 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) user, err := app.CreateUser("test") diff --git a/tests/acls/acl_policy_1.hujson b/tests/acls/acl_policy_1.hujson deleted file mode 100644 index dba403f1..00000000 --- a/tests/acls/acl_policy_1.hujson +++ /dev/null @@ -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" - ], - }, - ], -} \ No newline at end of file diff --git a/tests/acls/acl_policy_autoapprovers.hujson b/tests/acls/acl_policy_autoapprovers.hujson deleted file mode 100644 index bf564d88..00000000 --- a/tests/acls/acl_policy_autoapprovers.hujson +++ /dev/null @@ -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"], - } - } -} \ No newline at end of file diff --git a/tests/acls/acl_policy_basic_1.hujson b/tests/acls/acl_policy_basic_1.hujson deleted file mode 100644 index db78ea9c..00000000 --- a/tests/acls/acl_policy_basic_1.hujson +++ /dev/null @@ -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:*", - ], - }, - ], -} \ No newline at end of file diff --git a/tests/acls/acl_policy_basic_groups.hujson b/tests/acls/acl_policy_basic_groups.hujson deleted file mode 100644 index a99568ad..00000000 --- a/tests/acls/acl_policy_basic_groups.hujson +++ /dev/null @@ -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:*", - ], - }, - ], -} diff --git a/tests/acls/acl_policy_basic_protocols.hujson b/tests/acls/acl_policy_basic_protocols.hujson deleted file mode 100644 index 6772c564..00000000 --- a/tests/acls/acl_policy_basic_protocols.hujson +++ /dev/null @@ -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:*", - ], - }, - ], -} \ No newline at end of file diff --git a/tests/acls/acl_policy_basic_range.hujson b/tests/acls/acl_policy_basic_range.hujson deleted file mode 100644 index 2a4208fb..00000000 --- a/tests/acls/acl_policy_basic_range.hujson +++ /dev/null @@ -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", - ], - }, - ], -} \ No newline at end of file diff --git a/tests/acls/acl_policy_basic_user_as_user.hujson b/tests/acls/acl_policy_basic_user_as_user.hujson deleted file mode 100644 index 0009364c..00000000 --- a/tests/acls/acl_policy_basic_user_as_user.hujson +++ /dev/null @@ -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:*", - ], - }, - ], -} diff --git a/tests/acls/acl_policy_basic_wildcards.hujson b/tests/acls/acl_policy_basic_wildcards.hujson deleted file mode 100644 index e1a1f714..00000000 --- a/tests/acls/acl_policy_basic_wildcards.hujson +++ /dev/null @@ -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:*", - ], - }, - ], -} \ No newline at end of file diff --git a/tests/acls/acl_policy_basic_wildcards.yaml b/tests/acls/acl_policy_basic_wildcards.yaml deleted file mode 100644 index 4318fcd2..00000000 --- a/tests/acls/acl_policy_basic_wildcards.yaml +++ /dev/null @@ -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:* diff --git a/tests/acls/acl_policy_invalid.hujson b/tests/acls/acl_policy_invalid.hujson deleted file mode 100644 index 3684b1f1..00000000 --- a/tests/acls/acl_policy_invalid.hujson +++ /dev/null @@ -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" - ], - }, - ], -} \ No newline at end of file diff --git a/tests/acls/broken.hujson b/tests/acls/broken.hujson deleted file mode 100644 index 98232c64..00000000 --- a/tests/acls/broken.hujson +++ /dev/null @@ -1 +0,0 @@ -{ diff --git a/tests/acls/invalid.hujson b/tests/acls/invalid.hujson deleted file mode 100644 index 733f6924..00000000 --- a/tests/acls/invalid.hujson +++ /dev/null @@ -1,4 +0,0 @@ -{ - "valid_json": true, - "but_a_policy_though": false -} \ No newline at end of file