talos/internal/pkg/etcd/certs.go
Serge Logvinov b52b206665 feat: split etcd certificates to peer/client
Changes:
* Etcd peer port key usage: ServerAuth,ClientAuth
* Etcd client port key usage: ServerAuth,ClientAuth
* Talos etcd client key usage: ClientAuth
* KubeAPI etcd client key usage: ClientAuth
* List of etcd allowed ciphers

Signed-off-by: Serge Logvinov <serge.logvinov@sinextra.dev>
Signed-off-by: Andrey Smirnov <smirnov.andrey@gmail.com>
2021-06-23 13:26:48 -07:00

135 lines
3.5 KiB
Go

// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package etcd
import (
stdlibx509 "crypto/x509"
"fmt"
stdlibnet "net"
"os"
"time"
"github.com/talos-systems/crypto/x509"
"github.com/talos-systems/net"
)
// NewCommonOptions set common certificate options.
func NewCommonOptions() ([]x509.Option, error) {
ips, err := net.IPAddrs()
if err != nil {
return nil, fmt.Errorf("failed to discover IP addresses: %w", err)
}
ips = append(ips, stdlibnet.ParseIP("127.0.0.1"))
if net.IsIPv6(ips...) {
ips = append(ips, stdlibnet.ParseIP("::1"))
}
hostname, err := os.Hostname()
if err != nil {
return nil, fmt.Errorf("failed to get hostname: %w", err)
}
dnsNames, err := net.DNSNames()
if err != nil {
return nil, fmt.Errorf("failed to get host DNS names: %w", err)
}
dnsNames = append(dnsNames, "localhost")
return []x509.Option{
x509.CommonName(hostname),
x509.DNSNames(dnsNames),
x509.IPAddresses(ips),
x509.NotAfter(time.Now().Add(87600 * time.Hour)),
x509.KeyUsage(stdlibx509.KeyUsageDigitalSignature | stdlibx509.KeyUsageKeyEncipherment),
}, nil
}
// GeneratePeerCert generates etcd peer certificate and key from etcd CA.
//
//nolint:dupl
func GeneratePeerCert(etcdCA *x509.PEMEncodedCertificateAndKey) (*x509.PEMEncodedCertificateAndKey, error) {
opts, err := NewCommonOptions()
if err != nil {
return nil, err
}
opts = append(opts,
x509.ExtKeyUsage([]stdlibx509.ExtKeyUsage{
stdlibx509.ExtKeyUsageServerAuth,
stdlibx509.ExtKeyUsageClientAuth,
}),
)
ca, err := x509.NewCertificateAuthorityFromCertificateAndKey(etcdCA)
if err != nil {
return nil, fmt.Errorf("failed loading CA from config: %w", err)
}
keyPair, err := x509.NewKeyPair(ca, opts...)
if err != nil {
return nil, fmt.Errorf("failed generating peer key pair: %w", err)
}
return x509.NewCertificateAndKeyFromKeyPair(keyPair), nil
}
// GenerateCert generates etcd certificate and key from etcd CA.
//
//nolint:dupl
func GenerateCert(etcdCA *x509.PEMEncodedCertificateAndKey) (*x509.PEMEncodedCertificateAndKey, error) {
opts, err := NewCommonOptions()
if err != nil {
return nil, err
}
opts = append(opts,
x509.ExtKeyUsage([]stdlibx509.ExtKeyUsage{
stdlibx509.ExtKeyUsageServerAuth,
stdlibx509.ExtKeyUsageClientAuth,
}),
)
ca, err := x509.NewCertificateAuthorityFromCertificateAndKey(etcdCA)
if err != nil {
return nil, fmt.Errorf("failed loading CA from config: %w", err)
}
keyPair, err := x509.NewKeyPair(ca, opts...)
if err != nil {
return nil, fmt.Errorf("failed generating client key pair: %w", err)
}
return x509.NewCertificateAndKeyFromKeyPair(keyPair), nil
}
// GenerateClientCert generates client certificate and key from etcd CA.
func GenerateClientCert(etcdCA *x509.PEMEncodedCertificateAndKey, commonName string) (*x509.PEMEncodedCertificateAndKey, error) {
opts, err := NewCommonOptions()
if err != nil {
return nil, err
}
opts = append(opts, x509.CommonName(commonName))
opts = append(opts,
x509.ExtKeyUsage([]stdlibx509.ExtKeyUsage{
stdlibx509.ExtKeyUsageClientAuth,
}),
)
ca, err := x509.NewCertificateAuthorityFromCertificateAndKey(etcdCA)
if err != nil {
return nil, fmt.Errorf("failed loading CA from config: %w", err)
}
keyPair, err := x509.NewKeyPair(ca, opts...)
if err != nil {
return nil, fmt.Errorf("failed generating client key pair: %w", err)
}
return x509.NewCertificateAndKeyFromKeyPair(keyPair), nil
}