talos/internal/pkg/etcd/certs.go
Andrey Smirnov 2cd3f9be1f
feat: filter out SideroLink addresses by default
As SideroLink addresses are ephemeral and point-to-point, filter them
out for node addresses, Kubelet, etcd, etc.

Fixes #4448

Signed-off-by: Andrey Smirnov <andrey.smirnov@talos-systems.com>
2021-11-30 15:31:31 +03:00

139 lines
3.6 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"
"github.com/talos-systems/talos/pkg/machinery/resources/network"
)
// 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 = net.IPFilter(ips, network.NotSideroLinkStdIP)
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
}