Skip to content
This repository has been archived by the owner on Aug 19, 2023. It is now read-only.

Commit

Permalink
fix: bind etcd to IPv6 if available
Browse files Browse the repository at this point in the history
If an IPv6 address is available, etcd should bind to `[::]` instead of
`0.0.0.0`.  This will cause etcd to listen on both IPv4 and IPv6
interfaces.

Additionally, this fixes the SAN list for the etcd certificate
generation to include the FQDN of the host.

Fixes siderolabs#1842
Fixes siderolabs#1843

Signed-off-by: Seán C McCord <[email protected]>
  • Loading branch information
Ulexus authored and andrewrynhard committed Feb 3, 2020
1 parent e911353 commit dbf408e
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 17 deletions.
23 changes: 19 additions & 4 deletions internal/app/machined/pkg/system/services/etcd.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ func (e *Etcd) Condition(config runtime.Configurator) conditions.Condition {

// DependsOn implements the Service interface.
func (e *Etcd) DependsOn(config runtime.Configurator) []string {
return []string{"containerd"}
return []string{"containerd", "networkd"}
}

// Runner implements the Service interface.
Expand Down Expand Up @@ -164,15 +164,25 @@ func generatePKI(config runtime.Configurator) (err error) {
}

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 fmt.Errorf("failed to get hostname: %w", err)
}

dnsNames, err := net.DNSNames()
if err != nil {
return fmt.Errorf("failed to get host DNS names: %w", err)
}

dnsNames = append(dnsNames, "localhost")

opts := []x509.Option{
x509.CommonName(hostname),
x509.DNSNames([]string{"localhost", hostname}),
x509.DNSNames(dnsNames),
x509.RSA(true),
x509.IPAddresses(ips),
x509.NotAfter(time.Now().Add(87600 * time.Hour)),
Expand Down Expand Up @@ -338,11 +348,16 @@ func (e *Etcd) args(config runtime.Configurator) ([]string, error) {
return nil, errors.New("failed to discover local IP")
}

listenAddress := "0.0.0.0"
if net.IsIPv6(ips...) {
listenAddress = "[::]"
}

blackListArgs := argsbuilder.Args{
"name": hostname,
"data-dir": constants.EtcdDataPath,
"listen-peer-urls": "https://0.0.0.0:2380",
"listen-client-urls": "https://0.0.0.0:2379",
"listen-peer-urls": "https://" + listenAddress + ":2380",
"listen-client-urls": "https://" + listenAddress + ":2379",
"cert-file": constants.KubernetesEtcdPeerCert,
"key-file": constants.KubernetesEtcdPeerKey,
"trusted-ca-file": constants.KubernetesEtcdCACert,
Expand Down
14 changes: 1 addition & 13 deletions pkg/config/types/v1alpha1/generate/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ func NewInput(clustername string, endpoint string, kubernetesVersion string, opt

var loopback, podNet, serviceNet string

if isIPv6(endpoint) {
if tnet.IsIPv6(net.ParseIP(endpoint)) {
loopback = "::1"
podNet = DefaultIPv6PodNet
serviceNet = DefaultIPv6ServiceNet
Expand Down Expand Up @@ -380,15 +380,3 @@ func genToken(lenFirst int, lenSecond int) (string, error) {

return tokenTemp[0] + "." + tokenTemp[1], nil
}

func isIPv6(addrs ...string) bool {
for _, a := range addrs {
if ip := net.ParseIP(a); ip != nil {
if ip.To4() == nil {
return true
}
}
}

return false
}
18 changes: 18 additions & 0 deletions pkg/net/net.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,3 +118,21 @@ func DomainName() (domainname string, err error) {

return strings.TrimSuffix(domainname, "\n"), nil
}

// IsIPv6 indicates whether any IP address within the provided set is an IPv6
// address
func IsIPv6(addrs ...net.IP) bool {
for _, a := range addrs {
if a == nil || a.IsLoopback() || a.IsUnspecified() {
continue
}

if a.To4() == nil {
if a.To16() != nil {
return true
}
}
}

return false
}

0 comments on commit dbf408e

Please sign in to comment.