feat: Potentially handle renewing certificates
This commit is contained in:
parent
3af3f6bb7e
commit
d0a24a60ed
6
.gitignore
vendored
6
.gitignore
vendored
@ -1 +1,5 @@
|
|||||||
./rio
|
# Artificats
|
||||||
|
rio
|
||||||
|
|
||||||
|
# Testing stuff
|
||||||
|
*.json
|
@ -18,6 +18,35 @@ import (
|
|||||||
"github.com/go-acme/lego/v4/lego"
|
"github.com/go-acme/lego/v4/lego"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func RenewCertificate(old *CertificateWrapper, acmeClient *lego.Client) (CertificateWrapper, error) {
|
||||||
|
pk, _ := base64.StdEncoding.DecodeString(old.PrivateKeyEncoded)
|
||||||
|
res := certificate.Resource{
|
||||||
|
PrivateKey: pk,
|
||||||
|
Certificate: old.Certificate,
|
||||||
|
CSR: old.CSR,
|
||||||
|
}
|
||||||
|
|
||||||
|
new, err := acmeClient.Certificate.Renew(res, true, false, "")
|
||||||
|
if err != nil {
|
||||||
|
return CertificateWrapper{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert the new certificate into a wrapper struct
|
||||||
|
tlsCert, err := tls.X509KeyPair(new.Certificate, new.PrivateKey)
|
||||||
|
if err != nil {
|
||||||
|
return CertificateWrapper{}, err
|
||||||
|
}
|
||||||
|
wrapper := CertificateWrapper{
|
||||||
|
TlsCertificate: &tlsCert,
|
||||||
|
Domain: old.Domain,
|
||||||
|
NotAfter: time.Now().Add(time.Hour * 24 * 60),
|
||||||
|
PrivateKeyEncoded: base64.StdEncoding.EncodeToString(new.PrivateKey),
|
||||||
|
Certificate: new.Certificate,
|
||||||
|
CSR: new.CSR,
|
||||||
|
}
|
||||||
|
return wrapper, nil
|
||||||
|
}
|
||||||
|
|
||||||
func ObtainNewCertificate(domains []string, acmeClient *lego.Client) (CertificateWrapper, error) {
|
func ObtainNewCertificate(domains []string, acmeClient *lego.Client) (CertificateWrapper, error) {
|
||||||
req := certificate.ObtainRequest{
|
req := certificate.ObtainRequest{
|
||||||
Domains: domains,
|
Domains: domains,
|
||||||
@ -36,12 +65,11 @@ func ObtainNewCertificate(domains []string, acmeClient *lego.Client) (Certificat
|
|||||||
wrapper := CertificateWrapper{
|
wrapper := CertificateWrapper{
|
||||||
TlsCertificate: &tlsCert,
|
TlsCertificate: &tlsCert,
|
||||||
Domain: cert.Domain,
|
Domain: cert.Domain,
|
||||||
//NotAfter: tlsCert.Leaf.NotAfter,
|
//NotAfter: tlsCert.Leaf.NotAfter,
|
||||||
NotAfter: time.Now().Add(time.Hour * 24 * 60),
|
NotAfter: time.Now().Add(time.Hour * 24 * 60),
|
||||||
PrivateKeyEncoded: base64.StdEncoding.EncodeToString(cert.PrivateKey),
|
PrivateKeyEncoded: base64.StdEncoding.EncodeToString(cert.PrivateKey),
|
||||||
Certificate: cert.Certificate,
|
Certificate: cert.Certificate,
|
||||||
IssuerCertificate: cert.IssuerCertificate,
|
CSR: cert.CSR,
|
||||||
CertificateUrl: cert.CertURL,
|
|
||||||
}
|
}
|
||||||
return wrapper, nil
|
return wrapper, nil
|
||||||
}
|
}
|
||||||
@ -103,7 +131,6 @@ func MakeFallbackCertificate(pagesDomain string) (*CertificateWrapper, error) {
|
|||||||
NotAfter: notAfter,
|
NotAfter: notAfter,
|
||||||
PrivateKeyEncoded: base64.StdEncoding.EncodeToString(certcrypto.PEMEncode(key)),
|
PrivateKeyEncoded: base64.StdEncoding.EncodeToString(certcrypto.PEMEncode(key)),
|
||||||
Certificate: outBytes,
|
Certificate: outBytes,
|
||||||
IssuerCertificate: outBytes,
|
CSR: []byte{},
|
||||||
CertificateUrl: "localhost",
|
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
@ -19,8 +19,7 @@ type CertificateWrapper struct {
|
|||||||
NotAfter time.Time `json:"not_after"`
|
NotAfter time.Time `json:"not_after"`
|
||||||
PrivateKeyEncoded string `json:"private_key"`
|
PrivateKeyEncoded string `json:"private_key"`
|
||||||
Certificate []byte `json:"certificate"`
|
Certificate []byte `json:"certificate"`
|
||||||
IssuerCertificate []byte `json:"issuer_certificate"`
|
CSR []byte `json:"csr"`
|
||||||
CertificateUrl string `json:"certificate_url"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// A structure to store all the certificates we know of in.
|
// A structure to store all the certificates we know of in.
|
||||||
|
@ -15,30 +15,30 @@ import (
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
// To access requestingDomains, first acquire the lock.
|
// To access requestingDomains, first acquire the lock.
|
||||||
requestingLock = sync.Mutex{}
|
domainsLock = sync.Mutex{}
|
||||||
|
|
||||||
// Domain -> _. Check if domain is a key here to see if we're already requeting
|
// Domain -> _. Check if domain is a key here to see if we're already requesting
|
||||||
// a certificate for it.
|
// or renewing a certificate for that domain.
|
||||||
requestingDomains = make(map[string]bool)
|
workingDomains = make(map[string]bool)
|
||||||
)
|
)
|
||||||
|
|
||||||
func lockIfUnlockedDomain(domain string) bool {
|
func lockIfUnlockedDomain(domain string) bool {
|
||||||
requestingLock.Lock()
|
domainsLock.Lock()
|
||||||
defer requestingLock.Unlock()
|
defer domainsLock.Unlock()
|
||||||
|
|
||||||
_, found := requestingDomains[domain]
|
_, found := workingDomains[domain]
|
||||||
if !found {
|
if !found {
|
||||||
requestingDomains[domain] = true
|
workingDomains[domain] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
return found
|
return found
|
||||||
}
|
}
|
||||||
|
|
||||||
func unlockDomain(domain string) {
|
func unlockDomain(domain string) {
|
||||||
requestingLock.Lock()
|
domainsLock.Lock()
|
||||||
defer requestingLock.Unlock()
|
defer domainsLock.Unlock()
|
||||||
|
|
||||||
delete(requestingDomains, domain)
|
delete(workingDomains, domain)
|
||||||
}
|
}
|
||||||
|
|
||||||
func MakeTlsConfig(pagesDomain, cachePath string, cache *certificates.CertificatesCache, acmeClient *lego.Client) *tls.Config {
|
func MakeTlsConfig(pagesDomain, cachePath string, cache *certificates.CertificatesCache, acmeClient *lego.Client) *tls.Config {
|
||||||
@ -76,8 +76,15 @@ func MakeTlsConfig(pagesDomain, cachePath string, cache *certificates.Certificat
|
|||||||
}
|
}
|
||||||
defer unlockDomain(domain)
|
defer unlockDomain(domain)
|
||||||
|
|
||||||
// TODO: Renew
|
// Renew
|
||||||
log.Debugf("Certificate for %s expired, renewing", domain)
|
log.Debugf("Certificate for %s expired, renewing", domain)
|
||||||
|
newCert, err := certificates.RenewCertificate(&cert, acmeClient)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("Failed to renew certificate for %s: %v", domain, err)
|
||||||
|
return cert.TlsCertificate, nil
|
||||||
|
}
|
||||||
|
cache.AddCert(newCert, cachePath)
|
||||||
|
return newCert.TlsCertificate, nil
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Don't request if we're already requesting.
|
// Don't request if we're already requesting.
|
||||||
|
Loading…
Reference in New Issue
Block a user