policy/v2: align SSH rule validation with Tailscale

Trim whitespace on action, users, src, dst; reject empty/wildcard users; reject empty acceptEnv; reject negative and over-max checkPeriod; reject hosts-table aliases as SSH dst; reject non-ASCII tag names; tolerate tag-owner cycles; match group-nesting wording.
This commit is contained in:
Kristoffer Dalby 2026-05-13 14:09:17 +00:00
parent 4ad200ab73
commit d600090f2c
70 changed files with 1361660 additions and 308 deletions

View file

@ -1317,7 +1317,7 @@ func TestSSHPolicyRules(t *testing.T) {
]
}`,
expectErr: true,
errorMessage: `invalid SSH action: "invalid", must be one of: accept, check`,
errorMessage: `"invalid" is not a valid action`,
},
{
name: "invalid-check-period",
@ -1341,10 +1341,15 @@ func TestSSHPolicyRules(t *testing.T) {
]
}`,
expectErr: true,
errorMessage: "not a valid duration string",
errorMessage: `time: invalid duration "invalid"`,
},
// `autogroup:invalid` as an SSH user is no longer rejected:
// SaaS treats every `autogroup:*` user-string as a literal
// label and compiles it into the SSHUsers map. The compat
// suite covers this via ssh-malformed-user-autogroup-* — no
// dedicated case is needed here.
{
name: "unsupported-autogroup",
name: "ssh-user-unknown-autogroup-as-literal",
targetNode: taggedClient,
peers: types.Nodes{&nodeUser2},
policy: `{
@ -1363,8 +1368,23 @@ func TestSSHPolicyRules(t *testing.T) {
}
]
}`,
expectErr: true,
errorMessage: "autogroup not supported for SSH user",
wantSSH: &tailcfg.SSHPolicy{Rules: []*tailcfg.SSHRule{
{
Principals: []*tailcfg.SSHPrincipal{
{NodeIP: "100.64.0.2"},
},
SSHUsers: map[string]string{
"autogroup:invalid": "autogroup:invalid",
"root": "",
},
Action: &tailcfg.SSHAction{
Accept: true,
AllowAgentForwarding: true,
AllowLocalPortForwarding: true,
AllowRemotePortForwarding: true,
},
},
}},
},
{
name: "autogroup-nonroot-should-use-wildcard-with-root-excluded",