Documentation ¶
Index ¶
- Constants
- Variables
- func AuthorizeForwardedRoleAndOrg(ctx context.Context, authorizedRoles, forwarderRoles []string, org string) (string, error)
- func AuthorizeOrgAndRole(ctx context.Context, org string, ou ...string) (string, error)
- func BootstrapCluster(baseCertDir string) error
- func DefaultAcceptancePolicy() api.AcceptancePolicy
- func DefaultCAConfig() api.CAConfig
- func EncryptECPrivateKey(key []byte, passphraseStr string) ([]byte, error)
- func FormatRole(role string) (api.NodeRole, error)
- func GenerateAndSignNewTLSCert(rootCA RootCA, cn, ou, org string, paths CertPaths) (*tls.Certificate, error)
- func GenerateAndWriteNewKey(paths CertPaths) (csr, key []byte, err error)
- func GetAndValidateCertificateSubject(certs []tls.Certificate) (pkix.Name, error)
- func GetRemoteSignedCertificate(ctx context.Context, csr []byte, role, secret string, ...) ([]byte, error)
- func LoadTLSCreds(rootCA RootCA, paths CertPaths) (*MutableTLSCreds, *MutableTLSCreds, error)
- func LogTLSState(ctx context.Context, tlsState *tls.ConnectionState)
- func NewClientTLSConfig(cert *tls.Certificate, rootCAPool *x509.CertPool, serverName string) (*tls.Config, error)
- func NewServerTLSConfig(cert *tls.Certificate, rootCAPool *x509.CertPool) (*tls.Config, error)
- func ParseRole(apiRole api.NodeRole) (string, error)
- func RenewTLSConfig(ctx context.Context, s *SecurityConfig, baseCertDir string, ...) <-chan CertificateUpdate
- func WithMetadataForwardTLSInfo(ctx context.Context) (context.Context, error)
- type CertPaths
- type CertificateUpdate
- type MutableTLSCreds
- func (c *MutableTLSCreds) ClientHandshake(addr string, rawConn net.Conn, timeout time.Duration) (net.Conn, credentials.AuthInfo, error)
- func (c *MutableTLSCreds) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error)
- func (c *MutableTLSCreds) Info() credentials.ProtocolInfo
- func (c *MutableTLSCreds) LoadNewTLSConfig(newConfig *tls.Config) error
- func (c *MutableTLSCreds) NodeID() string
- func (c *MutableTLSCreds) Organization() string
- func (c *MutableTLSCreds) RequireTransportSecurity() bool
- func (c *MutableTLSCreds) Role() string
- func (c *MutableTLSCreds) ServerHandshake(rawConn net.Conn) (net.Conn, credentials.AuthInfo, error)
- type RemoteNodeInfo
- type RootCA
- func (rca *RootCA) CanSign() bool
- func (rca *RootCA) IssueAndSaveNewCertificates(paths CertPaths, cn, ou, org string) (*tls.Certificate, error)
- func (rca *RootCA) NewClientTLSCredentials(cert *tls.Certificate, serverName string) (*MutableTLSCreds, error)
- func (rca *RootCA) NewServerTLSCredentials(cert *tls.Certificate) (*MutableTLSCreds, error)
- func (rca *RootCA) ParseValidateAndSignCSR(csrBytes []byte, cn, ou, org string) ([]byte, error)
- func (rca *RootCA) RequestAndSaveNewCertificates(ctx context.Context, paths CertPaths, role, secret string, ...) (*tls.Certificate, error)
- type SecurityConfig
- type SecurityConfigPaths
- type Server
- func (s *Server) GetRootCACertificate(ctx context.Context, request *api.GetRootCACertificateRequest) (*api.GetRootCACertificateResponse, error)
- func (s *Server) IssueNodeCertificate(ctx context.Context, request *api.IssueNodeCertificateRequest) (*api.IssueNodeCertificateResponse, error)
- func (s *Server) NodeCertificateStatus(ctx context.Context, request *api.NodeCertificateStatusRequest) (*api.NodeCertificateStatusResponse, error)
- func (s *Server) Run(ctx context.Context) error
- func (s *Server) Stop() error
Constants ¶
const ( // RootKeySize is the default size of the root CA key RootKeySize = 384 // RootKeyAlgo defines the default algorithm for the root CA Key RootKeyAlgo = "ecdsa" // PassphraseENVVar defines the environment variable to look for the // root CA private key material encryption key PassphraseENVVar = "SWARM_ROOT_CA_PASSPHRASE" // PassphraseENVVarPrev defines the alternate environment variable to look for the // root CA private key material encryption key. It can be used for seamless // KEK rotations. PassphraseENVVarPrev = "SWARM_ROOT_CA_PASSPHRASE_PREV" // RootCAExpiration represents the expiration for the root CA in seconds (20 years) RootCAExpiration = "630720000s" // DefaultNodeCertExpiration represents the default expiration for node certificates (3 months) DefaultNodeCertExpiration = 2160 * time.Hour // CertLowerRotationRange represents the minimum fraction of time that we will wait when randomly // choosing our next certificate rotation CertLowerRotationRange = 0.5 // CertUpperRotationRange represents the maximum fraction of time that we will wait when randomly // choosing our next certificate rotation CertUpperRotationRange = 0.8 // MinNodeCertExpiration represents the minimum expiration for node certificates (25 + 5 minutes) // X - 5 > CertUpperRotationRange * X <=> X < 5/(1 - CertUpperRotationRange) // Since we're issuing certificates 5 minutes in the past to get around clock drifts, and // we're selecting a random rotation distribution range from CertLowerRotationRange to // CertUpperRotationRange, we need to ensure that we don't accept an expiration time that will // make a node able to randomly choose the next rotation after the expiration of the certificate. MinNodeCertExpiration = 30 * time.Minute )
const ( // ManagerRole represents the Manager node type, and is used for authorization to endpoints ManagerRole = "swarm-manager" // AgentRole represents the Agent node type, and is used for authorization to endpoints AgentRole = "swarm-worker" // CARole represents the CA node type, and is used for clients attempting to get new certificates issued CARole = "swarm-ca" )
Variables ¶
var DefaultPolicy = func() *cfconfig.Signing { return SigningPolicy(DefaultNodeCertExpiration) }
DefaultPolicy is the default policy used by the signers to ensure that the only fields from the remote CSRs we trust are: PublicKey, PublicKeyAlgorithm and SignatureAlgorithm.
var ErrNoLocalRootCA = errors.New("local root CA certificate does not exist")
ErrNoLocalRootCA is an error type used to indicate that the local root CA certificate file does not exist.
var SigningPolicy = func(certExpiry time.Duration) *cfconfig.Signing { if certExpiry < MinNodeCertExpiration { certExpiry = DefaultNodeCertExpiration } return &cfconfig.Signing{ Default: &cfconfig.SigningProfile{ Usage: []string{"signing", "key encipherment", "server auth", "client auth"}, Expiry: certExpiry, CSRWhitelist: &cfconfig.CSRWhitelist{ PublicKey: true, PublicKeyAlgorithm: true, SignatureAlgorithm: true, }, }, } }
SigningPolicy creates a policy used by the signer to ensure that the only fields from the remote CSRs we trust are: PublicKey, PublicKeyAlgorithm and SignatureAlgorithm. It receives the duration a certificate will be valid for
Functions ¶
func AuthorizeForwardedRoleAndOrg ¶
func AuthorizeForwardedRoleAndOrg(ctx context.Context, authorizedRoles, forwarderRoles []string, org string) (string, error)
AuthorizeForwardedRoleAndOrg checks for proper roles and organization of caller. The RPC may have been proxied by a manager, in which case the manager is authenticated and so is the certificate information that it forwarded. It returns the node ID of the original client.
func AuthorizeOrgAndRole ¶
AuthorizeOrgAndRole takes in a context and a list of roles, and returns the Node ID of the node.
func BootstrapCluster ¶
BootstrapCluster receives a directory and creates both new Root CA key material and a ManagerRole key/certificate pair to be used by the initial cluster manager
func DefaultAcceptancePolicy ¶
func DefaultAcceptancePolicy() api.AcceptancePolicy
DefaultAcceptancePolicy returns the default acceptance policy.
func DefaultCAConfig ¶
DefaultCAConfig returns the default CA Config, with a default expiration.
func EncryptECPrivateKey ¶
EncryptECPrivateKey receives a PEM encoded private key and returns an encrypted AES256 version using a passphrase TODO: Make this method generic to handle RSA keys
func FormatRole ¶
FormatRole parses an internal role string into an apiRole
func GenerateAndSignNewTLSCert ¶
func GenerateAndSignNewTLSCert(rootCA RootCA, cn, ou, org string, paths CertPaths) (*tls.Certificate, error)
GenerateAndSignNewTLSCert creates a new keypair, signs the certificate using signer, and saves the certificate and key to disk. This method is used to bootstrap the first manager TLS certificates.
func GenerateAndWriteNewKey ¶
GenerateAndWriteNewKey generates a new pub/priv key pair, writes it to disk and returns the CSR and the private key material
func GetAndValidateCertificateSubject ¶
func GetAndValidateCertificateSubject(certs []tls.Certificate) (pkix.Name, error)
GetAndValidateCertificateSubject is a helper method to retrieve and validate the subject from the x509 certificate underlying a tls.Certificate
func GetRemoteSignedCertificate ¶
func GetRemoteSignedCertificate(ctx context.Context, csr []byte, role, secret string, rootCAPool *x509.CertPool, picker *picker.Picker, creds credentials.TransportAuthenticator, nodeInfo chan<- string) ([]byte, error)
GetRemoteSignedCertificate submits a CSR together with the intended role to a remote CA server address available through a picker, and that is part of a CA identified by a specific certificate pool.
func LoadTLSCreds ¶
func LoadTLSCreds(rootCA RootCA, paths CertPaths) (*MutableTLSCreds, *MutableTLSCreds, error)
LoadTLSCreds loads tls credentials from the specified path and verifies that thay are valid for the RootCA.
func LogTLSState ¶
func LogTLSState(ctx context.Context, tlsState *tls.ConnectionState)
LogTLSState logs information about the TLS connection and remote peers
func NewClientTLSConfig ¶
func NewClientTLSConfig(cert *tls.Certificate, rootCAPool *x509.CertPool, serverName string) (*tls.Config, error)
NewClientTLSConfig returns a tls.Config configured for a TLS Client, given a tls.Certificate the PEM-encoded root CA Certificate, and the name of the remote server the client wants to connect to.
func NewServerTLSConfig ¶
NewServerTLSConfig returns a tls.Config configured for a TLS Server, given a tls.Certificate and the PEM-encoded root CA Certificate
func RenewTLSConfig ¶
func RenewTLSConfig(ctx context.Context, s *SecurityConfig, baseCertDir string, picker *picker.Picker, renew <-chan struct{}) <-chan CertificateUpdate
RenewTLSConfig will continuously monitor for the necessity of renewing the local certificates, either by issuing them locally if key-material is available, or requesting them from a remote CA.
Types ¶
type CertPaths ¶
type CertPaths struct {
Cert, Key string
}
CertPaths is a helper struct that keeps track of the paths of a Cert and corresponding Key
type CertificateUpdate ¶
CertificateUpdate represents a change in the underlying TLS configuration being returned by a certificate renewal event.
type MutableTLSCreds ¶
type MutableTLSCreds struct { // Mutex for the tls config sync.Mutex // contains filtered or unexported fields }
MutableTLSCreds is the credentials required for authenticating a connection using TLS.
func NewMutableTLS ¶
func NewMutableTLS(c *tls.Config) (*MutableTLSCreds, error)
NewMutableTLS uses c to construct a mutable TransportAuthenticator based on TLS.
func (*MutableTLSCreds) ClientHandshake ¶
func (c *MutableTLSCreds) ClientHandshake(addr string, rawConn net.Conn, timeout time.Duration) (net.Conn, credentials.AuthInfo, error)
ClientHandshake implements the credentials.TransportAuthenticator interface
func (*MutableTLSCreds) GetRequestMetadata ¶
func (c *MutableTLSCreds) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error)
GetRequestMetadata implements the credentials.TransportAuthenticator interface
func (*MutableTLSCreds) Info ¶
func (c *MutableTLSCreds) Info() credentials.ProtocolInfo
Info implements the credentials.TransportAuthenticator interface
func (*MutableTLSCreds) LoadNewTLSConfig ¶
func (c *MutableTLSCreds) LoadNewTLSConfig(newConfig *tls.Config) error
LoadNewTLSConfig replaces the currently loaded TLS config with a new one
func (*MutableTLSCreds) NodeID ¶
func (c *MutableTLSCreds) NodeID() string
NodeID returns the CN for the certificate encapsulated in this TransportAuthenticator
func (*MutableTLSCreds) Organization ¶
func (c *MutableTLSCreds) Organization() string
Organization returns the O for the certificate encapsulated in this TransportAuthenticator
func (*MutableTLSCreds) RequireTransportSecurity ¶
func (c *MutableTLSCreds) RequireTransportSecurity() bool
RequireTransportSecurity implements the credentials.TransportAuthenticator interface
func (*MutableTLSCreds) Role ¶
func (c *MutableTLSCreds) Role() string
Role returns the OU for the certificate encapsulated in this TransportAuthenticator
func (*MutableTLSCreds) ServerHandshake ¶
func (c *MutableTLSCreds) ServerHandshake(rawConn net.Conn) (net.Conn, credentials.AuthInfo, error)
ServerHandshake implements the credentials.TransportAuthenticator interface
type RemoteNodeInfo ¶
type RemoteNodeInfo struct { // Roles is a list of roles contained in the node's certificate // (or forwarded by a trusted node). Roles []string // Organization is the organization contained in the node's certificate // (or forwarded by a trusted node). Organization string // NodeID is the node's ID, from the CN field in its certificate // (or forwarded by a trusted node). NodeID string // ForwardedBy contains information for the node that forwarded this // request. It is set to nil if the request was received directly. ForwardedBy *RemoteNodeInfo }
RemoteNodeInfo describes a node sending an RPC request.
func RemoteNode ¶
func RemoteNode(ctx context.Context) (RemoteNodeInfo, error)
RemoteNode returns the node ID and role from the client's TLS certificate. If the RPC was forwarded, the original client's ID and role is returned, as well as the forwarder's ID. This function does not do authorization checks - it only looks up the node ID.
type RootCA ¶
type RootCA struct { // Key will only be used by the original manager to put the private // key-material in raft, no signing operations depend on it. Key []byte Cert []byte Pool *x509.CertPool NodeCertExpiry time.Duration // This signer will be nil if the node doesn't have the appropriate key material Signer cfsigner.Signer }
RootCA is the representation of everything we need to sign certificates
func CreateAndWriteRootCA ¶
CreateAndWriteRootCA creates a Certificate authority for a new Swarm Cluster, potentially overwriting any existing CAs.
func GetLocalRootCA ¶
GetLocalRootCA validates if the contents of the file are a valid self-signed CA certificate, and returns the PEM-encoded Certificate if so
func GetRemoteCA ¶
GetRemoteCA returns the remote endpoint's CA certificate
func NewRootCA ¶
NewRootCA creates a new RootCA object from unparsed cert and key byte slices. key may be nil, and in this case NewRootCA will return a RootCA without a signer.
func (*RootCA) CanSign ¶
CanSign ensures that the signer has all three necessary elements needed to operate
func (*RootCA) IssueAndSaveNewCertificates ¶
func (rca *RootCA) IssueAndSaveNewCertificates(paths CertPaths, cn, ou, org string) (*tls.Certificate, error)
IssueAndSaveNewCertificates generates a new key-pair, signs it with the local root-ca, and returns a tls certificate
func (*RootCA) NewClientTLSCredentials ¶
func (rca *RootCA) NewClientTLSCredentials(cert *tls.Certificate, serverName string) (*MutableTLSCreds, error)
NewClientTLSCredentials returns GRPC credentials for a TLS GRPC client, given a tls.Certificate a PEM-Encoded root CA Certificate, and the name of the remote server the client wants to connect to.
func (*RootCA) NewServerTLSCredentials ¶
func (rca *RootCA) NewServerTLSCredentials(cert *tls.Certificate) (*MutableTLSCreds, error)
NewServerTLSCredentials returns GRPC credentials for a TLS GRPC client, given a tls.Certificate a PEM-Encoded root CA Certificate, and the name of the remote server the client wants to connect to.
func (*RootCA) ParseValidateAndSignCSR ¶
ParseValidateAndSignCSR returns a signed certificate from a particular rootCA and a CSR.
func (*RootCA) RequestAndSaveNewCertificates ¶
func (rca *RootCA) RequestAndSaveNewCertificates(ctx context.Context, paths CertPaths, role, secret string, picker *picker.Picker, transport credentials.TransportAuthenticator, nodeInfo chan<- string) (*tls.Certificate, error)
RequestAndSaveNewCertificates gets new certificates issued, either by signing them locally if a signer is available, or by requesting them from the remote server at remoteAddr.
type SecurityConfig ¶
type SecurityConfig struct { ServerTLSCreds *MutableTLSCreds ClientTLSCreds *MutableTLSCreds // contains filtered or unexported fields }
SecurityConfig is used to represent a node's security configuration. It includes information about the RootCA and ServerTLSCreds/ClientTLSCreds transport authenticators to be used for MTLS
func LoadOrCreateSecurityConfig ¶
func LoadOrCreateSecurityConfig(ctx context.Context, baseCertDir, caHash, secret, proposedRole string, picker *picker.Picker, nodeInfo chan<- string) (*SecurityConfig, error)
LoadOrCreateSecurityConfig encapsulates the security logic behind joining a cluster. Every node requires at least a set of TLS certificates with which to join the cluster with. In the case of a manager, these certificates will be used both for client and server credentials.
func NewSecurityConfig ¶
func NewSecurityConfig(rootCA *RootCA, clientTLSCreds, serverTLSCreds *MutableTLSCreds) *SecurityConfig
NewSecurityConfig initializes and returns a new SecurityConfig.
func (*SecurityConfig) RootCA ¶
func (s *SecurityConfig) RootCA() *RootCA
RootCA returns the root CA.
func (*SecurityConfig) UpdateRootCA ¶
func (s *SecurityConfig) UpdateRootCA(cert, key []byte, certExpiry time.Duration) error
UpdateRootCA replaces the root CA with a new root CA based on the specified certificate, key, and the number of hours the certificates issue should last.
type SecurityConfigPaths ¶
type SecurityConfigPaths struct {
Node, RootCA CertPaths
}
SecurityConfigPaths is used as a helper to hold all the paths of security relevant files
func NewConfigPaths ¶
func NewConfigPaths(baseCertDir string) *SecurityConfigPaths
NewConfigPaths returns the absolute paths to all of the different types of files
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server is the CA and NodeCA API gRPC server. TODO(aaronl): At some point we may want to have separate implementations of CA, NodeCA, and other hypothetical future CA services. At the moment, breaking it apart doesn't seem worth it.
func NewServer ¶
func NewServer(store *store.MemoryStore, securityConfig *SecurityConfig) *Server
NewServer creates a CA API server.
func (*Server) GetRootCACertificate ¶
func (s *Server) GetRootCACertificate(ctx context.Context, request *api.GetRootCACertificateRequest) (*api.GetRootCACertificateResponse, error)
GetRootCACertificate returns the certificate of the Root CA.
func (*Server) IssueNodeCertificate ¶
func (s *Server) IssueNodeCertificate(ctx context.Context, request *api.IssueNodeCertificateRequest) (*api.IssueNodeCertificateResponse, error)
IssueNodeCertificate receives requests from a remote client indicating a node type and a CSR, returning a certificate chain signed by the local CA, if available.
func (*Server) NodeCertificateStatus ¶
func (s *Server) NodeCertificateStatus(ctx context.Context, request *api.NodeCertificateStatusRequest) (*api.NodeCertificateStatusResponse, error)
NodeCertificateStatus returns the current issuance status of an issuance request identified by the nodeID