From afe23635078cbb38a59820cc23108f3ad6e9f4f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Mouton?= Date: Wed, 17 Dec 2025 16:27:29 +0100 Subject: [PATCH 1/3] Update README.md to add TLS configuration options for CA and client certificates --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index b589a55..8ebc452 100644 --- a/README.md +++ b/README.md @@ -117,6 +117,10 @@ spec: | `dialTimeout` | Connection timeout (seconds) | no | `10` | | `tlsSecretRef` | Name of Kubernetes secret containing TLS certs | no | - | | `tlsSecretNamespace` | Namespace of the TLS secret | no | challenge namespace | +| `tlsCAKey` | Key name for CA certificate in the secret | no | `ca.crt` | +| `tlsCertKey` | Key name for client certificate in the secret | no | `tls.crt` | +| `tlsKeyKey` | Key name for client private key in the secret | no | `tls.key` | +| `tlsServerName` | Server name for TLS verification (when connecting via IP) | no | - | | `tlsInsecureSkipVerify` | Skip TLS verification (not recommended) | no | `false` | ## 🔐 TLS Configuration From 34f49b3c1d60d4c441bad1e51d395403c3c8ccdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Mouton?= Date: Wed, 17 Dec 2025 16:27:37 +0100 Subject: [PATCH 2/3] Add optional TLS configuration options for etcd webhook --- deploy/examples/issuer.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/deploy/examples/issuer.yaml b/deploy/examples/issuer.yaml index db11290..8c75fd3 100644 --- a/deploy/examples/issuer.yaml +++ b/deploy/examples/issuer.yaml @@ -55,6 +55,12 @@ spec: # TLS configuration - reference to a Kubernetes secret tlsSecretRef: "etcd-tls-certs" tlsSecretNamespace: "etcd" + # Optional: Custom key names in the TLS secret (defaults shown) + # tlsCAKey: "ca.crt" # Key name for CA certificate + # tlsCertKey: "tls.crt" # Key name for client certificate + # tlsKeyKey: "tls.key" # Key name for client private key + # Optional: Server name for TLS verification (useful when connecting via IP) + # tlsServerName: "etcd.local" --- # Example TLS Secret for etcd connection # The secret should contain: From 258164351f8e4674b5c98b68530048f5c4adae4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Mouton?= Date: Wed, 17 Dec 2025 16:27:47 +0100 Subject: [PATCH 3/3] Add TLS configuration options for server name and secret key customization --- pkg/solver/solver.go | 50 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 43 insertions(+), 7 deletions(-) diff --git a/pkg/solver/solver.go b/pkg/solver/solver.go index 9801a9b..f390424 100644 --- a/pkg/solver/solver.go +++ b/pkg/solver/solver.go @@ -40,6 +40,14 @@ type EtcdConfig struct { TLSSecretRef string `json:"tlsSecretRef,omitempty"` // TLSSecretNamespace is the namespace of the TLS secret (defaults to challenge namespace) TLSSecretNamespace string `json:"tlsSecretNamespace,omitempty"` + // TLSCAKey is the key name for CA certificate in the secret (default: ca.crt) + TLSCAKey string `json:"tlsCAKey,omitempty"` + // TLSCertKey is the key name for client certificate in the secret (default: tls.crt) + TLSCertKey string `json:"tlsCertKey,omitempty"` + // TLSKeyKey is the key name for client private key in the secret (default: tls.key) + TLSKeyKey string `json:"tlsKeyKey,omitempty"` + // TLSServerName is the server name for TLS certificate verification (useful when connecting via IP) + TLSServerName string `json:"tlsServerName,omitempty"` // TLSInsecureSkipVerify skips TLS certificate verification (not recommended for production) TLSInsecureSkipVerify bool `json:"tlsInsecureSkipVerify,omitempty"` // TLSCA is the CA certificate in PEM format (alternative to using a secret) @@ -252,6 +260,12 @@ func (e *EtcdDNSSolver) loadTLSConfigFromInline(cfg *EtcdConfig) (*tls.Config, e InsecureSkipVerify: cfg.TLSInsecureSkipVerify, } + // Set ServerName for TLS verification if specified + if cfg.TLSServerName != "" { + tlsConfig.ServerName = cfg.TLSServerName + klog.V(2).Infof("Using TLS ServerName: %s", cfg.TLSServerName) + } + // Load CA certificate if provided if cfg.TLSCA != "" { caCertPool := x509.NewCertPool() @@ -300,19 +314,41 @@ func (e *EtcdDNSSolver) loadTLSConfigFromSecret(cfg *EtcdConfig, ch *v1alpha1.Ch InsecureSkipVerify: cfg.TLSInsecureSkipVerify, } + // Set ServerName for TLS verification if specified + if cfg.TLSServerName != "" { + tlsConfig.ServerName = cfg.TLSServerName + klog.V(2).Infof("Using TLS ServerName: %s", cfg.TLSServerName) + } + + // Determine key names (use defaults if not specified) + caKey := cfg.TLSCAKey + if caKey == "" { + caKey = "ca.crt" + } + certKey := cfg.TLSCertKey + if certKey == "" { + certKey = "tls.crt" + } + keyKey := cfg.TLSKeyKey + if keyKey == "" { + keyKey = "tls.key" + } + + klog.V(2).Infof("Using TLS secret keys: CA=%s, Cert=%s, Key=%s", caKey, certKey, keyKey) + // Load CA certificate if present - if caCert, ok := secret.Data["ca.crt"]; ok { + if caCert, ok := secret.Data[caKey]; ok { caCertPool := x509.NewCertPool() if !caCertPool.AppendCertsFromPEM(caCert) { - return nil, fmt.Errorf("failed to parse CA certificate") + return nil, fmt.Errorf("failed to parse CA certificate from key '%s'", caKey) } tlsConfig.RootCAs = caCertPool - klog.V(2).Info("CA certificate loaded from secret") + klog.V(2).Infof("CA certificate loaded from secret key '%s'", caKey) } // Load client certificate and key if present (for mTLS) - clientCert, certOk := secret.Data["tls.crt"] - clientKey, keyOk := secret.Data["tls.key"] + clientCert, certOk := secret.Data[certKey] + clientKey, keyOk := secret.Data[keyKey] if certOk && keyOk { cert, err := tls.X509KeyPair(clientCert, clientKey) @@ -320,9 +356,9 @@ func (e *EtcdDNSSolver) loadTLSConfigFromSecret(cfg *EtcdConfig, ch *v1alpha1.Ch return nil, fmt.Errorf("failed to load client certificate and key: %v", err) } tlsConfig.Certificates = []tls.Certificate{cert} - klog.V(2).Info("Client certificate and key loaded from secret") + klog.V(2).Infof("Client certificate and key loaded from secret keys '%s' and '%s'", certKey, keyKey) } else if certOk || keyOk { - return nil, fmt.Errorf("both tls.crt and tls.key must be present in the secret for client authentication") + return nil, fmt.Errorf("both '%s' and '%s' must be present in the secret for client authentication", certKey, keyKey) } return tlsConfig, nil