mirror of
https://github.com/juanfont/headscale.git
synced 2026-11-01 11:14:09 +09:00
policy: pin SSH forwarding behavior and recommend upgrades
Updates #3601
(cherry picked from commit 998c4b061, CHANGELOG dropped)
This commit is contained in:
1 parent
2d881c5e56
commit
02b1528025
10 files changed
+15961
-1
No files matched your search
+1
-1
@@ -29,7 +29,7 @@ config*.yaml
|
||||
!config-example.yaml
|
||||
derp.yaml
|
||||
*.hujson
|
||||
!hscontrol/policy/v2/testdata/*/*.hujson
|
||||
!hscontrol/policy/v2/testdata/**/*.hujson
|
||||
*.key
|
||||
/db.sqlite
|
||||
*.sqlite3
|
||||
|
||||
@@ -59,6 +59,68 @@ func loadSSHTestFile(t *testing.T, path string) *testcapture.Capture {
|
||||
return c
|
||||
}
|
||||
|
||||
// TestSSHForwardingDataCompat pins upstream forwarding actions and rejects
|
||||
// unsupported policy fields. The complete captures retain SSHUsers, but its new
|
||||
// numeric-user deny entry needs separate user-mapping compatibility coverage.
|
||||
func TestSSHForwardingDataCompat(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
files, err := filepath.Glob(filepath.Join("testdata", "ssh_results", "forwarding", "ssh-*.hujson"))
|
||||
require.NoError(t, err)
|
||||
require.NotEmpty(t, files)
|
||||
|
||||
users := setupSSHDataCompatUsers()
|
||||
|
||||
for _, file := range files {
|
||||
tf := loadSSHTestFile(t, file)
|
||||
|
||||
t.Run(tf.TestID, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
require.Empty(t, tf.CaptureError)
|
||||
require.NotEmpty(t, tf.Captures)
|
||||
|
||||
pol, err := unmarshalPolicy([]byte(tf.Input.FullPolicy))
|
||||
if tf.Input.APIResponseCode != 200 {
|
||||
require.Equal(t, 400, tf.Input.APIResponseCode)
|
||||
require.NotNil(t, tf.Input.APIResponseBody)
|
||||
field, ok := strings.CutPrefix(tf.Input.APIResponseBody.Message, "json: unknown field ")
|
||||
require.True(t, ok, "expected an upstream unknown-field rejection")
|
||||
require.ErrorIs(t, err, ErrUnknownField)
|
||||
require.ErrorContains(t, err, fmt.Sprintf("%s: %s", ErrUnknownField, field))
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
require.NoError(t, err)
|
||||
|
||||
nodes := buildGrantsNodesFromCapture(users, tf)
|
||||
|
||||
for nodeName, capture := range tf.Captures {
|
||||
t.Run(nodeName, func(t *testing.T) {
|
||||
node := findNodeByGivenName(nodes, nodeName)
|
||||
require.NotNil(t, node)
|
||||
|
||||
got, err := pol.compileSSHPolicy("https://unused", users, node.View(), nodes.ViewSlice())
|
||||
require.NoError(t, err)
|
||||
|
||||
var rules []*tailcfg.SSHRule
|
||||
if got != nil {
|
||||
rules = got.Rules
|
||||
}
|
||||
|
||||
require.Len(t, rules, len(capture.SSHRules))
|
||||
|
||||
for i, want := range capture.SSHRules {
|
||||
require.NotNil(t, want.Action)
|
||||
assert.Equal(t, want.Action, rules[i].Action)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// sshSkipReasons documents captures the upstream control plane accepts
|
||||
// but headscale cannot yet represent. Each entry names the feature gap.
|
||||
var sshSkipReasons = map[string]string{
|
||||
|
||||
+1977
File diff suppressed because it is too large.
Load diff
+2001
File diff suppressed because it is too large.
Load diff
+1985
File diff suppressed because it is too large.
Load diff
+1985
File diff suppressed because it is too large.
Load diff
+1985
File diff suppressed because it is too large.
Load diff
+1995
File diff suppressed because it is too large.
Load diff
+1985
File diff suppressed because it is too large.
Load diff
+1985
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user