Documentation ¶
Overview ¶
Package bootstrap contains logic for securely adding new clusters to the gateway using bootstrap tokens.
The bootstrap process is as follows:
- The server generates a self-signed keypair, and a bootstrap token.
- The client is given the bootstrap token and one or more fingerprints of public keys in the server's certificate chain ("pinned" public keys). It sends a request to the server's /bootstrap/join endpoint with no Authentication header. The client cannot yet trust the server's self-signed certificate, so it does not send any other data in the request.
- During the TLS handshake, the client computes the fingerprints of the public keys in the server's offered certificates, and compares them to its pinned fingerprints. If any of the fingerprints match, and the server's certificate chain is valid (i.e. each certificate is signed by the next certificate in the chain), the client trusts the server and completes the TLS handshake.
- The server responds with several JWS messages with detached payloads (one for each active bootstrap token).
- The client finds the JWS with the matching bootstrap token ID, fills in the detached payload (the bootstrap token), and sends it back to the server's /bootstrap/join endpoint along with the client's own unique identifier it wishes to use (typically the client's kube-system namespace resource UID) and an ephemeral x25519 public key.
- The server verifies the reconstructed JWS. If it is correct, the server can now trust the client. The server responds with its own ephemeral x25519 public key.
- Both the client and server use their ephemeral keypair and their peer's public key to generate a shared secret. Then, this secret is passed through a KDF to create two static ed25519 keys. One is used to generate and verify MACs for client->server messages, and the other is used to generate and verify MACs for server->client messages.
Index ¶
Constants ¶
This section is empty.
Variables ¶
View Source
var ( ErrInvalidEndpoint = errors.New("invalid endpoint") ErrNoRootCA = errors.New("no root CA found in peer certificates") ErrLeafNotSigned = errors.New("leaf certificate not signed by the root CA") ErrKeyExpired = errors.New("key expired") ErrRootCAHashMismatch = errors.New("root CA hash mismatch") ErrNoValidSignature = errors.New("no valid signature found in response") ErrNoToken = errors.New("no bootstrap token provided") )
Functions ¶
This section is empty.
Types ¶
type Bootstrapper ¶
type ClientConfig ¶
type ClientConfig struct { Capability string Token *tokens.Token Endpoint string DialOpts []grpc.DialOption K8sConfig *rest.Config K8sNamespace string TrustStrategy trust.Strategy }
type ClientConfigV2 ¶ added in v0.6.0
type ClientConfigV2 struct { Token *tokens.Token Endpoint string DialOpts []grpc.DialOption K8sConfig *rest.Config K8sNamespace string TrustStrategy trust.Strategy FriendlyName *string }
type InClusterBootstrapper ¶ added in v0.5.4
type InClusterBootstrapper struct { Capability string GatewayEndpoint string ManagementEndpoint string // contains filtered or unexported fields }
InClusterBootstrapper is a Bootstrapper that can bootstrap itself inside the main cluster with direct access to the management api.
type InClusterBootstrapperV2 ¶ added in v0.6.0
type InClusterBootstrapperV2 struct { GatewayEndpoint string ManagementEndpoint string // contains filtered or unexported fields }
InClusterBootstrapperV2 is a Bootstrapper that can bootstrap itself inside the main cluster with direct access to the management api. If unset, the cluster's friendlyName will default to "local" when using this bootstrapper.
type Server ¶ added in v0.5.4
type Server struct { bootstrapv1.UnsafeBootstrapServer // contains filtered or unexported fields }
func NewServer ¶ added in v0.5.4
func NewServer(storage Storage, privateKey crypto.Signer, capBackendStore capabilities.BackendStore) *Server
func (*Server) Auth ¶ added in v0.5.4
func (h *Server) Auth(ctx context.Context, authReq *bootstrapv1.BootstrapAuthRequest) (*bootstrapv1.BootstrapAuthResponse, error)
func (*Server) Join ¶ added in v0.5.4
func (h *Server) Join(ctx context.Context, _ *bootstrapv1.BootstrapJoinRequest) (*bootstrapv1.BootstrapJoinResponse, error)
type ServerV2 ¶ added in v0.6.0
type ServerV2 struct { bootstrapv2.UnsafeBootstrapServer // contains filtered or unexported fields }
func NewServerV2 ¶ added in v0.6.0
func (*ServerV2) Auth ¶ added in v0.6.0
func (h *ServerV2) Auth(ctx context.Context, authReq *bootstrapv2.BootstrapAuthRequest) (*bootstrapv2.BootstrapAuthResponse, error)
func (*ServerV2) Join ¶ added in v0.6.0
func (h *ServerV2) Join(ctx context.Context, _ *bootstrapv2.BootstrapJoinRequest) (*bootstrapv2.BootstrapJoinResponse, error)
type Storage ¶ added in v0.5.4
type Storage interface { storage.TokenStore storage.ClusterStore storage.KeyringStoreBroker }
type StorageConfig ¶ added in v0.5.4
type StorageConfig struct { storage.TokenStore storage.ClusterStore storage.KeyringStoreBroker }
Click to show internal directories.
Click to hide internal directories.