mirror of
https://github.com/yusing/godoxy.git
synced 2026-04-19 23:11:25 +02:00
feat(autocert): generate unique ACME key paths per CA directory URL
Previously, ACME keys were stored at a single default path regardless of which CA directory URL was configured. This caused key conflicts when using multiple different ACME CAs. Now, the key path is derived from a SHA256 hash of the CA directory URL, allowing each CA to have its own key file: - Default CA (Let's Encrypt): certs/acme.key - Custom CA: certs/acme_<url_hash_16chars>.key This enables running certificates against multiple ACME providers without key collision issues.
This commit is contained in:
@@ -4,10 +4,13 @@ import (
|
|||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
"crypto/elliptic"
|
"crypto/elliptic"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
|
"crypto/sha256"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
|
||||||
"github.com/go-acme/lego/v4/certcrypto"
|
"github.com/go-acme/lego/v4/certcrypto"
|
||||||
@@ -27,7 +30,7 @@ type Config struct {
|
|||||||
CertPath string `json:"cert_path,omitempty"`
|
CertPath string `json:"cert_path,omitempty"`
|
||||||
KeyPath string `json:"key_path,omitempty"`
|
KeyPath string `json:"key_path,omitempty"`
|
||||||
Extra []ConfigExtra `json:"extra,omitempty"`
|
Extra []ConfigExtra `json:"extra,omitempty"`
|
||||||
ACMEKeyPath string `json:"acme_key_path,omitempty"` // shared by all extra providers
|
ACMEKeyPath string `json:"acme_key_path,omitempty"` // shared by all extra providers with the same CA directory URL
|
||||||
Provider string `json:"provider,omitempty"`
|
Provider string `json:"provider,omitempty"`
|
||||||
Options map[string]strutils.Redacted `json:"options,omitempty"`
|
Options map[string]strutils.Redacted `json:"options,omitempty"`
|
||||||
|
|
||||||
@@ -88,7 +91,7 @@ func (cfg *Config) validate(seenPaths map[string]int) gperr.Error {
|
|||||||
cfg.KeyPath = KeyFileDefault
|
cfg.KeyPath = KeyFileDefault
|
||||||
}
|
}
|
||||||
if cfg.ACMEKeyPath == "" {
|
if cfg.ACMEKeyPath == "" {
|
||||||
cfg.ACMEKeyPath = ACMEKeyFileDefault
|
cfg.ACMEKeyPath = acmeKeyPath(cfg.CADirURL)
|
||||||
}
|
}
|
||||||
|
|
||||||
b := gperr.NewBuilder("certificate error")
|
b := gperr.NewBuilder("certificate error")
|
||||||
@@ -272,3 +275,16 @@ func (cfg *Config) SaveACMEKey(key *ecdsa.PrivateKey) error {
|
|||||||
}
|
}
|
||||||
return os.WriteFile(cfg.ACMEKeyPath, data, 0o600)
|
return os.WriteFile(cfg.ACMEKeyPath, data, 0o600)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// acmeKeyPath returns the path to the ACME key file based on the CA directory URL.
|
||||||
|
// Different CA directory URLs will use different key files to avoid key conflicts.
|
||||||
|
func acmeKeyPath(caDirURL string) string {
|
||||||
|
// Use a hash of the CA directory URL to create a unique key filename
|
||||||
|
// Default to "acme" if no custom CA is configured (Let's Encrypt default)
|
||||||
|
filename := "acme"
|
||||||
|
if caDirURL != "" {
|
||||||
|
hash := sha256.Sum256([]byte(caDirURL))
|
||||||
|
filename = "acme_" + hex.EncodeToString(hash[:])[:16]
|
||||||
|
}
|
||||||
|
return filepath.Join(certBasePath, filename+".key")
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
package autocert
|
package autocert
|
||||||
|
|
||||||
const (
|
const (
|
||||||
certBasePath = "certs/"
|
certBasePath = "certs/"
|
||||||
CertFileDefault = certBasePath + "cert.crt"
|
CertFileDefault = certBasePath + "cert.crt"
|
||||||
KeyFileDefault = certBasePath + "priv.key"
|
KeyFileDefault = certBasePath + "priv.key"
|
||||||
ACMEKeyFileDefault = certBasePath + "acme.key"
|
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user