Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -875,3 +875,9 @@ const (
// to invite to the session.
KubeSessionInvitedQueryParam = "invite"
)

const (
// KubeLegacyProxySuffix is the suffix used for legacy proxy services when
// generating their names Server names.
KubeLegacyProxySuffix = "-proxy_service"
)
5 changes: 3 additions & 2 deletions lib/auth/auth_with_roles.go
Original file line number Diff line number Diff line change
Expand Up @@ -1333,8 +1333,9 @@ func (a *ServerWithRoles) KeepAliveServer(ctx context.Context, handle types.Keep
} else if serverName != handle.HostID {
return trace.AccessDenied("access denied")
}

if !a.hasBuiltinRole(types.RoleKube) {
// Legacy kube proxy can heartbeat kube servers from the proxy itself so
// we need to check if the host has the Kube or Proxy role.
if !a.hasBuiltinRole(types.RoleKube, types.RoleProxy) {
return trace.AccessDenied("access denied")
}
if err := a.action(apidefaults.Namespace, types.KindKubeServer, types.VerbUpdate); err != nil {
Expand Down
90 changes: 90 additions & 0 deletions lib/auth/auth_with_roles_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6066,3 +6066,93 @@ func createAppServerOrSPFromSP(sp types.SAMLIdPServiceProvider) types.AppServerO

return appServerOrSP
}

func TestKubeKeepAliveServer(t *testing.T) {
t.Parallel()
srv := newTestTLSServer(t)
domainName, err := srv.Auth().GetDomainName()
require.NoError(t, err)

tests := map[string]struct {
builtInRole types.SystemRole
assertErr require.ErrorAssertionFunc
}{
"as kube service": {
builtInRole: types.RoleKube,
assertErr: require.NoError,
},
"as legacy proxy service": {
builtInRole: types.RoleProxy,
assertErr: require.NoError,
},
"as database service": {
builtInRole: types.RoleDatabase,
assertErr: require.Error,
},
}
for name, test := range tests {
test := test
t.Run(name, func(t *testing.T) {
t.Parallel()
hostID := uuid.New().String()
// Create a kubernetes cluster.
kube, err := types.NewKubernetesClusterV3(
types.Metadata{
Name: "kube",
Namespace: defaults.Namespace,
},
types.KubernetesClusterSpecV3{},
)
require.NoError(t, err)
// Create a kubernetes server.
// If the built-in role is proxy, the server name should be
// kube-proxy_service
serverName := "kube"
if test.builtInRole == types.RoleProxy {
serverName += teleport.KubeLegacyProxySuffix
}
kubeServer, err := types.NewKubernetesServerV3(
types.Metadata{
Name: serverName,
Namespace: defaults.Namespace,
},
types.KubernetesServerSpecV3{
Cluster: kube,
HostID: hostID,
},
)
require.NoError(t, err)
// Upsert the kubernetes server into the backend.
_, err = srv.Auth().UpsertKubernetesServer(context.Background(), kubeServer)
require.NoError(t, err)

// Create a built-in role.
authContext, err := authz.ContextForBuiltinRole(
authz.BuiltinRole{
Role: test.builtInRole,
Username: fmt.Sprintf("%s.%s", hostID, domainName),
},
types.DefaultSessionRecordingConfig(),
)
require.NoError(t, err)

// Create a server with the built-in role.
srv := ServerWithRoles{
authServer: srv.Auth(),
context: *authContext,
}
// Keep alive the server.
err = srv.KeepAliveServer(context.Background(),
types.KeepAlive{
Type: types.KeepAlive_KUBERNETES,
Expires: time.Now().Add(5 * time.Minute),
Name: serverName,
Namespace: defaults.Namespace,
HostID: hostID,
},
)
test.assertErr(t, err)
},
)
}
}
2 changes: 1 addition & 1 deletion lib/kube/proxy/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@ func (t *TLSServer) getServerInfo(name string) (types.Resource, error) {
// Note: we *don't* want to add suffix for kubernetes_service!
// This breaks reverse tunnel routing, which uses server.Name.
if t.KubeServiceType != KubeService {
name += "-proxy_service"
name += teleport.KubeLegacyProxySuffix
}

srv, err := types.NewKubernetesServerV3(
Expand Down