mirror of
https://github.com/tailscale/tailscale.git
synced 2026-05-08 21:56:48 +02:00
ssh/tailssh: add nodeCap SSH principal
Signed-off-by: Anton Tolchanov <anton@tailscale.com>
This commit is contained in:
parent
4657cbdb11
commit
99f0c03e9b
@ -1201,6 +1201,9 @@ func (c *conn) principalMatchesTailscaleIdentity(p *tailcfg.SSHPrincipal) bool {
|
||||
return true
|
||||
}
|
||||
}
|
||||
if p.NodeCap != "" && ci.node.Valid() && ci.node.HasCap(p.NodeCap) {
|
||||
return true
|
||||
}
|
||||
if p.UserLogin != "" && ci.uprof.LoginName == p.UserLogin {
|
||||
return true
|
||||
}
|
||||
|
||||
@ -202,6 +202,16 @@ func TestMatchRule(t *testing.T) {
|
||||
ci: &sshConnInfo{node: (&tailcfg.Node{StableID: "some-node-ID"}).View()},
|
||||
wantUser: "ubuntu",
|
||||
},
|
||||
{
|
||||
name: "match-principal-node-cap",
|
||||
rule: &tailcfg.SSHRule{
|
||||
Action: someAction,
|
||||
Principals: []*tailcfg.SSHPrincipal{{NodeCap: "some-node-cap"}},
|
||||
SSHUsers: map[string]string{"*": "ubuntu"},
|
||||
},
|
||||
ci: &sshConnInfo{node: (&tailcfg.Node{CapMap: tailcfg.NodeCapMap{"some-node-cap": nil}}).View()},
|
||||
wantUser: "ubuntu",
|
||||
},
|
||||
{
|
||||
name: "match-principal-userlogin",
|
||||
rule: &tailcfg.SSHRule{
|
||||
|
||||
@ -2841,13 +2841,14 @@ type SSHRule struct {
|
||||
|
||||
// SSHPrincipal is either a particular node or a user on any node.
|
||||
type SSHPrincipal struct {
|
||||
// Matching any one of the following four field causes a match.
|
||||
// Matching any one of the following five field causes a match.
|
||||
// It must also match Certs, if non-empty.
|
||||
|
||||
Node StableNodeID `json:"node,omitempty"`
|
||||
NodeIP string `json:"nodeIP,omitempty"`
|
||||
UserLogin string `json:"userLogin,omitempty"` // email-ish: foo@example.com, bar@github
|
||||
Any bool `json:"any,omitempty"` // if true, match any connection
|
||||
Node StableNodeID `json:"node,omitempty"`
|
||||
NodeIP string `json:"nodeIP,omitempty"`
|
||||
NodeCap NodeCapability `json:"nodeCap,omitempty"`
|
||||
UserLogin string `json:"userLogin,omitempty"` // email-ish: foo@example.com, bar@github
|
||||
Any bool `json:"any,omitempty"` // if true, match any connection
|
||||
// TODO(bradfitz): add StableUserID, once that exists
|
||||
|
||||
// UnusedPubKeys was public key support. It never became an official product
|
||||
|
||||
@ -569,6 +569,7 @@ func (src *SSHPrincipal) Clone() *SSHPrincipal {
|
||||
var _SSHPrincipalCloneNeedsRegeneration = SSHPrincipal(struct {
|
||||
Node StableNodeID
|
||||
NodeIP string
|
||||
NodeCap NodeCapability
|
||||
UserLogin string
|
||||
Any bool
|
||||
UnusedPubKeys []string
|
||||
|
||||
@ -2220,8 +2220,9 @@ func (v *SSHPrincipalView) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v SSHPrincipalView) Node() StableNodeID { return v.ж.Node }
|
||||
func (v SSHPrincipalView) NodeIP() string { return v.ж.NodeIP }
|
||||
func (v SSHPrincipalView) Node() StableNodeID { return v.ж.Node }
|
||||
func (v SSHPrincipalView) NodeIP() string { return v.ж.NodeIP }
|
||||
func (v SSHPrincipalView) NodeCap() NodeCapability { return v.ж.NodeCap }
|
||||
|
||||
// email-ish: foo@example.com, bar@github
|
||||
func (v SSHPrincipalView) UserLogin() string { return v.ж.UserLogin }
|
||||
@ -2243,6 +2244,7 @@ func (v SSHPrincipalView) UnusedPubKeys() views.Slice[string] {
|
||||
var _SSHPrincipalViewNeedsRegeneration = SSHPrincipal(struct {
|
||||
Node StableNodeID
|
||||
NodeIP string
|
||||
NodeCap NodeCapability
|
||||
UserLogin string
|
||||
Any bool
|
||||
UnusedPubKeys []string
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user