mirror of
https://github.com/juanfont/headscale.git
synced 2026-07-17 16:36:02 +00:00
policy/v2: add ssh-edges captures from Tailscale SaaS
30 new captures recorded against SaaS covering multi-rule SSH policies, group nesting, tag-owner cycles, empty references, unicode, hosts table aliases, multi-src/dst, whitespace in src/dst, null and missing fields, and sshTests edges. 20 captures already match headscale behaviour. The remaining 10 land in sshSkipReasons and sshRejectSkipReasons tracking 5 engine divergences (whitespace trim in src/dst, tag-owner cycle tolerance, hosts-alias rejection on SSH dst, non-ASCII tag-name rejection, group-nesting error wording); follow-up commits close each gap and drain the corresponding skip entries.
This commit is contained in:
parent
f8aa6c46ef
commit
76ba2de85a
31 changed files with 663086 additions and 0 deletions
|
|
@ -87,6 +87,31 @@ var sshSkipReasons = map[string]string{
|
|||
// equivalent for the user:*@passkey wildcard pattern.
|
||||
"ssh-b5": "user:*@passkey wildcard not supported in headscale",
|
||||
"ssh-d10": "user:*@passkey wildcard not supported in headscale",
|
||||
|
||||
// WHITESPACE_TRIM_IN_SRC_DST (2 tests)
|
||||
//
|
||||
// SaaS strips surrounding whitespace from SSH rule src/dst entries
|
||||
// before lookup ("tag:server " resolves to "tag:server",
|
||||
// " user@host" resolves to "user@host"). headscale treats the
|
||||
// untrimmed string as a literal identifier and either fails the
|
||||
// tag/user lookup or produces no rule for the affected node. The
|
||||
// fix lives in policy/v2 alias resolution — strings.TrimSpace at
|
||||
// the same point where SaaS does, before dispatching to the alias
|
||||
// type registry.
|
||||
"ssh-dst-trailing-whitespace": "src/dst whitespace trim mismatch: SaaS trims, headscale doesn't",
|
||||
"ssh-src-leading-whitespace": "src/dst whitespace trim mismatch: SaaS trims, headscale doesn't",
|
||||
|
||||
// TAG_OWNER_CYCLE_TOLERATED (2 tests)
|
||||
//
|
||||
// SaaS accepts tagOwners with circular references (tag:a -> tag:b,
|
||||
// tag:b -> tag:a or tag:a -> tag:a) and resolves them as the empty
|
||||
// owner set. headscale's TagOwnerSet resolver eagerly detects
|
||||
// circular tag references and rejects the policy at parse time.
|
||||
// Pick a side and adjust: either match SaaS by treating cycles as
|
||||
// "no owners" instead of an error, or document that headscale is
|
||||
// intentionally stricter and remove these scenarios.
|
||||
"ssh-tag-owner-cycle": "headscale rejects tagOwner cycles that SaaS accepts as empty owner set",
|
||||
"ssh-tag-owner-self-reference": "headscale rejects self-referencing tagOwner that SaaS accepts as empty owner set",
|
||||
}
|
||||
|
||||
// sshRejectSkipReasons documents APIResponseCode != 200 captures where
|
||||
|
|
@ -106,6 +131,41 @@ var sshRejectSkipReasons = map[string]string{
|
|||
"ssh-e1": "domain validation: headscale has no 'associated tailnet domains' concept",
|
||||
"ssh-e2": "domain validation: headscale has no 'associated tailnet domains' concept",
|
||||
"ssh-malformed-user-localpart-multi-glob": "domain validation: headscale has no 'associated tailnet domains' concept (same gap as ssh-b4/d1/e1/e2)",
|
||||
|
||||
// HOSTS_ALIAS_AS_SSH_DST (2 tests)
|
||||
//
|
||||
// SaaS rejects every hosts-alias dst on an SSH rule with
|
||||
// `invalid dst "alias"`, regardless of whether the alias resolves
|
||||
// to a single IP or a CIDR. headscale's compileSSHPolicy resolves
|
||||
// host aliases through the same path as ACL dsts and accepts
|
||||
// them. Either reject hosts-aliases at SSH dst parse time to
|
||||
// match, or document that headscale is intentionally more
|
||||
// permissive than SaaS for SSH dsts.
|
||||
"ssh-hosts-as-dst-single-ip": "SaaS rejects host alias as SSH dst, headscale accepts",
|
||||
"ssh-hosts-as-dst-multi-host-prefix": "SaaS rejects host alias as SSH dst, headscale accepts",
|
||||
|
||||
// NON_ASCII_TAG_NAME (1 test)
|
||||
//
|
||||
// SaaS rejects non-ASCII characters in tag names with
|
||||
// `tag names must start with a letter, after 'tag:'`. headscale's
|
||||
// tag parser accepts arbitrary UTF-8. Tighten the tag-name
|
||||
// validator to match SaaS's letter-only rule.
|
||||
"ssh-unicode-cyrillic-tag": "SaaS rejects non-ASCII tag names, headscale accepts",
|
||||
|
||||
// GROUP_NESTING_ERROR_BODY (3 tests)
|
||||
//
|
||||
// SaaS rejects any group-in-group reference (cycle, chain,
|
||||
// self-cycle) with the structured message
|
||||
// `groups["X"]: "Y": group members cannot be recursive`.
|
||||
// headscale rejects too but the error surfaces as a generic
|
||||
// `parsing policy: parsing policy from bytes: json: unable to
|
||||
// unmarshal …` because the group resolver fails before the
|
||||
// validation phase that would emit a specific message. Wire the
|
||||
// resolver's "group references a group" detection to produce the
|
||||
// SaaS-style structured error so the body matches.
|
||||
"ssh-group-nested-cycle": "group nesting rejected with different error body (parse error vs structured 'group members cannot be recursive')",
|
||||
"ssh-group-nested-three-deep": "group nesting rejected with different error body (parse error vs structured 'group members cannot be recursive')",
|
||||
"ssh-group-nested-two-deep": "group nesting rejected with different error body (parse error vs structured 'group members cannot be recursive')",
|
||||
}
|
||||
|
||||
// TestSSHDataCompat is a data-driven test that loads all ssh-*.hujson test
|
||||
|
|
|
|||
22349
hscontrol/policy/v2/testdata/ssh_results/ssh-acceptenv-null.hujson
vendored
Normal file
22349
hscontrol/policy/v2/testdata/ssh_results/ssh-acceptenv-null.hujson
vendored
Normal file
File diff suppressed because it is too large
Load diff
22348
hscontrol/policy/v2/testdata/ssh_results/ssh-acceptenv-omitted.hujson
vendored
Normal file
22348
hscontrol/policy/v2/testdata/ssh_results/ssh-acceptenv-omitted.hujson
vendored
Normal file
File diff suppressed because it is too large
Load diff
22343
hscontrol/policy/v2/testdata/ssh_results/ssh-checkperiod-null.hujson
vendored
Normal file
22343
hscontrol/policy/v2/testdata/ssh_results/ssh-checkperiod-null.hujson
vendored
Normal file
File diff suppressed because it is too large
Load diff
22330
hscontrol/policy/v2/testdata/ssh_results/ssh-dst-empty-tag.hujson
vendored
Normal file
22330
hscontrol/policy/v2/testdata/ssh_results/ssh-dst-empty-tag.hujson
vendored
Normal file
File diff suppressed because it is too large
Load diff
22348
hscontrol/policy/v2/testdata/ssh_results/ssh-dst-trailing-whitespace.hujson
vendored
Normal file
22348
hscontrol/policy/v2/testdata/ssh_results/ssh-dst-trailing-whitespace.hujson
vendored
Normal file
File diff suppressed because it is too large
Load diff
22109
hscontrol/policy/v2/testdata/ssh_results/ssh-group-nested-cycle.hujson
vendored
Normal file
22109
hscontrol/policy/v2/testdata/ssh_results/ssh-group-nested-cycle.hujson
vendored
Normal file
File diff suppressed because it is too large
Load diff
22113
hscontrol/policy/v2/testdata/ssh_results/ssh-group-nested-three-deep.hujson
vendored
Normal file
22113
hscontrol/policy/v2/testdata/ssh_results/ssh-group-nested-three-deep.hujson
vendored
Normal file
File diff suppressed because it is too large
Load diff
22109
hscontrol/policy/v2/testdata/ssh_results/ssh-group-nested-two-deep.hujson
vendored
Normal file
22109
hscontrol/policy/v2/testdata/ssh_results/ssh-group-nested-two-deep.hujson
vendored
Normal file
File diff suppressed because it is too large
Load diff
22107
hscontrol/policy/v2/testdata/ssh_results/ssh-hosts-as-dst-multi-host-prefix.hujson
vendored
Normal file
22107
hscontrol/policy/v2/testdata/ssh_results/ssh-hosts-as-dst-multi-host-prefix.hujson
vendored
Normal file
File diff suppressed because it is too large
Load diff
22107
hscontrol/policy/v2/testdata/ssh_results/ssh-hosts-as-dst-single-ip.hujson
vendored
Normal file
22107
hscontrol/policy/v2/testdata/ssh_results/ssh-hosts-as-dst-single-ip.hujson
vendored
Normal file
File diff suppressed because it is too large
Load diff
22143
hscontrol/policy/v2/testdata/ssh_results/ssh-many-tags-as-dst.hujson
vendored
Normal file
22143
hscontrol/policy/v2/testdata/ssh_results/ssh-many-tags-as-dst.hujson
vendored
Normal file
File diff suppressed because it is too large
Load diff
21916
hscontrol/policy/v2/testdata/ssh_results/ssh-multi-rule-accept-then-check.hujson
vendored
Normal file
21916
hscontrol/policy/v2/testdata/ssh_results/ssh-multi-rule-accept-then-check.hujson
vendored
Normal file
File diff suppressed because it is too large
Load diff
21916
hscontrol/policy/v2/testdata/ssh_results/ssh-multi-rule-check-then-accept.hujson
vendored
Normal file
21916
hscontrol/policy/v2/testdata/ssh_results/ssh-multi-rule-check-then-accept.hujson
vendored
Normal file
File diff suppressed because it is too large
Load diff
22146
hscontrol/policy/v2/testdata/ssh_results/ssh-multi-rule-disjoint-srcs.hujson
vendored
Normal file
22146
hscontrol/policy/v2/testdata/ssh_results/ssh-multi-rule-disjoint-srcs.hujson
vendored
Normal file
File diff suppressed because it is too large
Load diff
22152
hscontrol/policy/v2/testdata/ssh_results/ssh-multi-rule-overlap-conflicting-acceptenv.hujson
vendored
Normal file
22152
hscontrol/policy/v2/testdata/ssh_results/ssh-multi-rule-overlap-conflicting-acceptenv.hujson
vendored
Normal file
File diff suppressed because it is too large
Load diff
22146
hscontrol/policy/v2/testdata/ssh_results/ssh-multi-rule-overlap-different-users.hujson
vendored
Normal file
22146
hscontrol/policy/v2/testdata/ssh_results/ssh-multi-rule-overlap-different-users.hujson
vendored
Normal file
File diff suppressed because it is too large
Load diff
22146
hscontrol/policy/v2/testdata/ssh_results/ssh-multi-src-multi-dst-multi-user.hujson
vendored
Normal file
22146
hscontrol/policy/v2/testdata/ssh_results/ssh-multi-src-multi-dst-multi-user.hujson
vendored
Normal file
File diff suppressed because it is too large
Load diff
21944
hscontrol/policy/v2/testdata/ssh_results/ssh-src-autogroup-tagged-no-tagged-nodes.hujson
vendored
Normal file
21944
hscontrol/policy/v2/testdata/ssh_results/ssh-src-autogroup-tagged-no-tagged-nodes.hujson
vendored
Normal file
File diff suppressed because it is too large
Load diff
22105
hscontrol/policy/v2/testdata/ssh_results/ssh-src-empty-group.hujson
vendored
Normal file
22105
hscontrol/policy/v2/testdata/ssh_results/ssh-src-empty-group.hujson
vendored
Normal file
File diff suppressed because it is too large
Load diff
22123
hscontrol/policy/v2/testdata/ssh_results/ssh-src-leading-whitespace.hujson
vendored
Normal file
22123
hscontrol/policy/v2/testdata/ssh_results/ssh-src-leading-whitespace.hujson
vendored
Normal file
File diff suppressed because it is too large
Load diff
22123
hscontrol/policy/v2/testdata/ssh_results/ssh-tab-in-user.hujson
vendored
Normal file
22123
hscontrol/policy/v2/testdata/ssh_results/ssh-tab-in-user.hujson
vendored
Normal file
File diff suppressed because it is too large
Load diff
22101
hscontrol/policy/v2/testdata/ssh_results/ssh-tag-owner-cycle.hujson
vendored
Normal file
22101
hscontrol/policy/v2/testdata/ssh_results/ssh-tag-owner-cycle.hujson
vendored
Normal file
File diff suppressed because it is too large
Load diff
22101
hscontrol/policy/v2/testdata/ssh_results/ssh-tag-owner-self-reference.hujson
vendored
Normal file
22101
hscontrol/policy/v2/testdata/ssh_results/ssh-tag-owner-self-reference.hujson
vendored
Normal file
File diff suppressed because it is too large
Load diff
21880
hscontrol/policy/v2/testdata/ssh_results/ssh-unicode-cyrillic-tag.hujson
vendored
Normal file
21880
hscontrol/policy/v2/testdata/ssh_results/ssh-unicode-cyrillic-tag.hujson
vendored
Normal file
File diff suppressed because it is too large
Load diff
21898
hscontrol/policy/v2/testdata/ssh_results/ssh-unicode-emoji-user.hujson
vendored
Normal file
21898
hscontrol/policy/v2/testdata/ssh_results/ssh-unicode-emoji-user.hujson
vendored
Normal file
File diff suppressed because it is too large
Load diff
22123
hscontrol/policy/v2/testdata/ssh_results/ssh-unicode-rtl-user.hujson
vendored
Normal file
22123
hscontrol/policy/v2/testdata/ssh_results/ssh-unicode-rtl-user.hujson
vendored
Normal file
File diff suppressed because it is too large
Load diff
22106
hscontrol/policy/v2/testdata/ssh_results/ssh-users-null.hujson
vendored
Normal file
22106
hscontrol/policy/v2/testdata/ssh_results/ssh-users-null.hujson
vendored
Normal file
File diff suppressed because it is too large
Load diff
21887
hscontrol/policy/v2/testdata/sshtest_results/sshtest-accept-and-deny-same-user.hujson
vendored
Normal file
21887
hscontrol/policy/v2/testdata/sshtest_results/sshtest-accept-and-deny-same-user.hujson
vendored
Normal file
File diff suppressed because it is too large
Load diff
21903
hscontrol/policy/v2/testdata/sshtest_results/sshtest-dst-duplicate-tags.hujson
vendored
Normal file
21903
hscontrol/policy/v2/testdata/sshtest_results/sshtest-dst-duplicate-tags.hujson
vendored
Normal file
File diff suppressed because it is too large
Load diff
21904
hscontrol/policy/v2/testdata/sshtest_results/sshtest-multi-rule-disjoint-srcs.hujson
vendored
Normal file
21904
hscontrol/policy/v2/testdata/sshtest_results/sshtest-multi-rule-disjoint-srcs.hujson
vendored
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue