mirror of
https://github.com/gravitational/teleport.git
synced 2026-08-31 02:28:23 +08:00
210 lines
11 KiB
Go
210 lines
11 KiB
Go
/*
|
|
* Teleport
|
|
* Copyright (C) 2023 Gravitational, Inc.
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Affero General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Affero General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
package services
|
|
|
|
import (
|
|
"context"
|
|
"iter"
|
|
|
|
"github.com/gravitational/trace"
|
|
|
|
clusterconfigpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/clusterconfig/v1"
|
|
joiningv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/scopes/joining/v1"
|
|
"github.com/gravitational/teleport/api/types"
|
|
"github.com/gravitational/teleport/lib/backend"
|
|
"github.com/gravitational/teleport/lib/modules"
|
|
)
|
|
|
|
// ClusterNameGetter is a service that gets the cluster name from the backend.
|
|
type ClusterNameGetter interface {
|
|
// GetClusterName gets types.ClusterName from the backend.
|
|
GetClusterName(ctx context.Context) (types.ClusterName, error)
|
|
}
|
|
|
|
// ClusterConfiguration stores the cluster configuration in the backend. All
|
|
// the resources modified by this interface can only have a single instance
|
|
// in the backend.
|
|
type ClusterConfiguration interface {
|
|
ClusterNameGetter
|
|
|
|
// GetStaticTokens gets services.StaticTokens from the backend.
|
|
GetStaticTokens(context.Context) (types.StaticTokens, error)
|
|
// SetStaticTokens sets services.StaticTokens on the backend.
|
|
SetStaticTokens(types.StaticTokens) error
|
|
// DeleteStaticTokens deletes static tokens resource
|
|
DeleteStaticTokens() error
|
|
// GetUIConfig gets the proxy service UI config from the backend
|
|
GetUIConfig(context.Context) (types.UIConfig, error)
|
|
// SetUIConfig sets the proxy service UI config from the backend
|
|
SetUIConfig(context.Context, types.UIConfig) error
|
|
// DeleteUIConfig deletes the proxy service UI config from the backend
|
|
DeleteUIConfig(ctx context.Context) error
|
|
|
|
// GetAuthPreference gets types.AuthPreference from the backend.
|
|
GetAuthPreference(context.Context) (types.AuthPreference, error)
|
|
// CreateAuthPreference creates an auth preference if once does not already exist.
|
|
CreateAuthPreference(ctx context.Context, preference types.AuthPreference) (types.AuthPreference, error)
|
|
// UpdateAuthPreference updates an existing auth preference.
|
|
UpdateAuthPreference(ctx context.Context, preference types.AuthPreference) (types.AuthPreference, error)
|
|
// UpsertAuthPreference creates a new auth preference or overwrites an existing auth preference.
|
|
UpsertAuthPreference(ctx context.Context, preference types.AuthPreference) (types.AuthPreference, error)
|
|
// DeleteAuthPreference deletes types.AuthPreference from the backend.
|
|
DeleteAuthPreference(ctx context.Context) error
|
|
|
|
// GetSessionRecordingConfig gets SessionRecordingConfig from the backend.
|
|
GetSessionRecordingConfig(context.Context) (types.SessionRecordingConfig, error)
|
|
// CreateSessionRecordingConfig creates a session recording config if once does not already exist.
|
|
CreateSessionRecordingConfig(ctx context.Context, cfg types.SessionRecordingConfig) (types.SessionRecordingConfig, error)
|
|
// UpdateSessionRecordingConfig updates an existing session recording config.
|
|
UpdateSessionRecordingConfig(ctx context.Context, cfg types.SessionRecordingConfig) (types.SessionRecordingConfig, error)
|
|
// UpsertSessionRecordingConfig creates a new session recording config or overwrites the existing session recording.
|
|
UpsertSessionRecordingConfig(ctx context.Context, cfg types.SessionRecordingConfig) (types.SessionRecordingConfig, error)
|
|
// DeleteSessionRecordingConfig deletes SessionRecordingConfig from the backend.
|
|
DeleteSessionRecordingConfig(ctx context.Context) error
|
|
|
|
// GetClusterAuditConfig gets ClusterAuditConfig from the backend.
|
|
GetClusterAuditConfig(context.Context) (types.ClusterAuditConfig, error)
|
|
// CreateClusterAuditConfig creates a cluster audit config if once does not already exist.
|
|
CreateClusterAuditConfig(ctx context.Context, cfg types.ClusterAuditConfig) (types.ClusterAuditConfig, error)
|
|
// UpdateClusterAuditConfig updates an existing cluster audit config.
|
|
UpdateClusterAuditConfig(ctx context.Context, cfg types.ClusterAuditConfig) (types.ClusterAuditConfig, error)
|
|
// UpsertClusterAuditConfig creates a new cluster audit config or overwrites the existing cluster audit config.
|
|
UpsertClusterAuditConfig(ctx context.Context, cfg types.ClusterAuditConfig) (types.ClusterAuditConfig, error)
|
|
// SetClusterAuditConfig sets ClusterAuditConfig from the backend.
|
|
SetClusterAuditConfig(context.Context, types.ClusterAuditConfig) error
|
|
// DeleteClusterAuditConfig deletes ClusterAuditConfig from the backend.
|
|
DeleteClusterAuditConfig(ctx context.Context) error
|
|
|
|
// GetClusterNetworkingConfig gets ClusterNetworkingConfig from the backend.
|
|
GetClusterNetworkingConfig(context.Context) (types.ClusterNetworkingConfig, error)
|
|
// CreateClusterNetworkingConfig creates a cluster networking config if once does not already exist.
|
|
CreateClusterNetworkingConfig(ctx context.Context, cfg types.ClusterNetworkingConfig) (types.ClusterNetworkingConfig, error)
|
|
// UpdateClusterNetworkingConfig updates an existing cluster networking config.
|
|
UpdateClusterNetworkingConfig(ctx context.Context, cfg types.ClusterNetworkingConfig) (types.ClusterNetworkingConfig, error)
|
|
// UpsertClusterNetworkingConfig creates a new cluster networking config or overwrites the existing cluster networking config.
|
|
UpsertClusterNetworkingConfig(ctx context.Context, cfg types.ClusterNetworkingConfig) (types.ClusterNetworkingConfig, error)
|
|
// DeleteClusterNetworkingConfig deletes ClusterNetworkingConfig from the backend.
|
|
DeleteClusterNetworkingConfig(ctx context.Context) error
|
|
|
|
// GetInstallers gets all installer scripts from the backend
|
|
GetInstallers(context.Context) ([]types.Installer, error)
|
|
// ListInstallers returns a page of installer script resources.
|
|
ListInstallers(ctx context.Context, limit int, start string) ([]types.Installer, string, error)
|
|
// RangeInstallers returns installer script resources within the range [start, end).
|
|
RangeInstallers(ctx context.Context, start, end string) iter.Seq2[types.Installer, error]
|
|
|
|
// GetInstaller gets the installer script from the backend
|
|
GetInstaller(ctx context.Context, name string) (types.Installer, error)
|
|
// SetInstaller sets the installer script in the backend
|
|
SetInstaller(context.Context, types.Installer) error
|
|
// DeleteInstaller removes the installer script from the backend
|
|
DeleteInstaller(ctx context.Context, name string) error
|
|
// DeleteAllInstallers removes all installer script resources from the backend
|
|
DeleteAllInstallers(context.Context) error
|
|
|
|
// GetClusterMaintenanceConfig loads the current maintenance config singleton.
|
|
GetClusterMaintenanceConfig(ctx context.Context) (types.ClusterMaintenanceConfig, error)
|
|
// UpdateClusterMaintenanceConfig updates the maintenance config singleton.
|
|
UpdateClusterMaintenanceConfig(ctx context.Context, cfg types.ClusterMaintenanceConfig) error
|
|
// DeleteClusterMaintenanceConfig deletes the maintenance config singleton.
|
|
DeleteClusterMaintenanceConfig(ctx context.Context) error
|
|
|
|
// GetAccessGraphSettings gets the access graph settings from the backend.
|
|
GetAccessGraphSettings(context.Context) (*clusterconfigpb.AccessGraphSettings, error)
|
|
// CreateAccessGraphSettings creates the access graph settings in the backend.
|
|
CreateAccessGraphSettings(context.Context, *clusterconfigpb.AccessGraphSettings) (*clusterconfigpb.AccessGraphSettings, error)
|
|
// UpdateAccessGraphSettings updates the access graph settings in the backend.
|
|
UpdateAccessGraphSettings(context.Context, *clusterconfigpb.AccessGraphSettings) (*clusterconfigpb.AccessGraphSettings, error)
|
|
// UpsertAccessGraphSettings creates or updates the access graph settings in the backend.
|
|
UpsertAccessGraphSettings(context.Context, *clusterconfigpb.AccessGraphSettings) (*clusterconfigpb.AccessGraphSettings, error)
|
|
// DeleteAccessGraphSettings deletes the access graph settings from the backend.
|
|
DeleteAccessGraphSettings(context.Context) error
|
|
}
|
|
|
|
// ClusterConfigurationInternal extends [ClusterConfiguration] with
|
|
// auth-specific methods.
|
|
type ClusterConfigurationInternal interface {
|
|
ClusterConfiguration
|
|
StaticScopedTokenService
|
|
|
|
// SetClusterName sets services.ClusterName on the backend.
|
|
SetClusterName(types.ClusterName) error
|
|
// UpsertClusterName upserts cluster name
|
|
UpsertClusterName(types.ClusterName) error
|
|
// DeleteClusterName deletes cluster name resource
|
|
DeleteClusterName() error
|
|
|
|
// AppendCheckAuthPreferenceActions appends some atomic write actions to the
|
|
// given slice that will check that the currently stored cluster auth
|
|
// preference has the given revision when applied as part of a
|
|
// [backend.Backend.AtomicWrite]. The backend to which the actions are
|
|
// applied should be the same backend used by the
|
|
// ClusterConfigurationInternal.
|
|
AppendCheckAuthPreferenceActions(actions []backend.ConditionalAction, revision string) ([]backend.ConditionalAction, error)
|
|
}
|
|
|
|
// StaticScopedTokenService is the interface for interacting with the cluster's
|
|
// [*joiningv1.StaticScopedTokens].
|
|
type StaticScopedTokenService interface {
|
|
// GetStaticScopedTokens gets [*joiningv1.StaticScopedTokens] from the backend.
|
|
GetStaticScopedTokens(context.Context) (*joiningv1.StaticScopedTokens, error)
|
|
// SetStaticScopedTokens sets [*joiningv1.StaticScopedTokens] to the backend.
|
|
SetStaticScopedTokens(context.Context, *joiningv1.StaticScopedTokens) error
|
|
// DeleteStaticScopedTokens deletes the [*joiningv1.StaticScopedTokens] resource resource
|
|
// from the backend
|
|
DeleteStaticScopedTokens(context.Context) error
|
|
}
|
|
|
|
// ValidateAuthPreference performs checks that should happen before persisting a
|
|
// new version of the preference resource, typically only as part of Auth
|
|
// service operations.
|
|
func ValidateAuthPreference(ap types.AuthPreference) error {
|
|
// TODO(espadolini): the checks that are duplicated in
|
|
// {Set,Create,Update,Upsert}AuthPreference should be moved here
|
|
if err := modules.ValidateResource(ap); err != nil {
|
|
return trace.Wrap(err)
|
|
}
|
|
|
|
if err := ValidateStableUNIXUserConfig(ap.GetStableUNIXUserConfig()); err != nil {
|
|
return trace.Wrap(err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// ValidateStableUNIXUserConfig checks if the configuration is suitable for
|
|
// storage and use.
|
|
func ValidateStableUNIXUserConfig(c *types.StableUNIXUserConfig) error {
|
|
if c == nil || !c.Enabled {
|
|
return nil
|
|
}
|
|
|
|
if c.FirstUid > c.LastUid {
|
|
return trace.BadParameter("stable UNIX user is enabled but UID range is empty")
|
|
}
|
|
|
|
// see https://github.com/systemd/systemd/blob/cc7300fc5868f6d47f3f47076100b574bf54e58d/docs/UIDS-GIDS.md
|
|
const firstUserUID = 1000
|
|
if c.FirstUid < firstUserUID {
|
|
return trace.BadParameter("stable UNIX user UID range includes negative or system UIDs; the configured range should be contained between 1000 and 2147483647")
|
|
}
|
|
|
|
return nil
|
|
}
|