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"
|
||||
)
|
||||
|
||||
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) {
|
||||
req := certificate.ObtainRequest{
|
||||
Domains: domains,
|
||||
@ -36,12 +65,11 @@ func ObtainNewCertificate(domains []string, acmeClient *lego.Client) (Certificat
|
||||
wrapper := CertificateWrapper{
|
||||
TlsCertificate: &tlsCert,
|
||||
Domain: cert.Domain,
|
||||
//NotAfter: tlsCert.Leaf.NotAfter,
|
||||
//NotAfter: tlsCert.Leaf.NotAfter,
|
||||
NotAfter: time.Now().Add(time.Hour * 24 * 60),
|
||||
PrivateKeyEncoded: base64.StdEncoding.EncodeToString(cert.PrivateKey),
|
||||
Certificate: cert.Certificate,
|
||||
IssuerCertificate: cert.IssuerCertificate,
|
||||
CertificateUrl: cert.CertURL,
|
||||
CSR: cert.CSR,
|
||||
}
|
||||
return wrapper, nil
|
||||
}
|
||||
@ -103,7 +131,6 @@ func MakeFallbackCertificate(pagesDomain string) (*CertificateWrapper, error) {
|
||||
NotAfter: notAfter,
|
||||
PrivateKeyEncoded: base64.StdEncoding.EncodeToString(certcrypto.PEMEncode(key)),
|
||||
Certificate: outBytes,
|
||||
IssuerCertificate: outBytes,
|
||||
CertificateUrl: "localhost",
|
||||
CSR: []byte{},
|
||||
}, nil
|
||||
}
|
||||
|
@ -19,8 +19,7 @@ type CertificateWrapper struct {
|
||||
NotAfter time.Time `json:"not_after"`
|
||||
PrivateKeyEncoded string `json:"private_key"`
|
||||
Certificate []byte `json:"certificate"`
|
||||
IssuerCertificate []byte `json:"issuer_certificate"`
|
||||
CertificateUrl string `json:"certificate_url"`
|
||||
CSR []byte `json:"csr"`
|
||||
}
|
||||
|
||||
// A structure to store all the certificates we know of in.
|
||||
|
@ -15,30 +15,30 @@ import (
|
||||
|
||||
var (
|
||||
// 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
|
||||
// a certificate for it.
|
||||
requestingDomains = make(map[string]bool)
|
||||
// Domain -> _. Check if domain is a key here to see if we're already requesting
|
||||
// or renewing a certificate for that domain.
|
||||
workingDomains = make(map[string]bool)
|
||||
)
|
||||
|
||||
func lockIfUnlockedDomain(domain string) bool {
|
||||
requestingLock.Lock()
|
||||
defer requestingLock.Unlock()
|
||||
domainsLock.Lock()
|
||||
defer domainsLock.Unlock()
|
||||
|
||||
_, found := requestingDomains[domain]
|
||||
_, found := workingDomains[domain]
|
||||
if !found {
|
||||
requestingDomains[domain] = true
|
||||
workingDomains[domain] = true
|
||||
}
|
||||
|
||||
return found
|
||||
}
|
||||
|
||||
func unlockDomain(domain string) {
|
||||
requestingLock.Lock()
|
||||
defer requestingLock.Unlock()
|
||||
domainsLock.Lock()
|
||||
defer domainsLock.Unlock()
|
||||
|
||||
delete(requestingDomains, domain)
|
||||
delete(workingDomains, domain)
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
// TODO: Renew
|
||||
// Renew
|
||||
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 {
|
||||
// Don't request if we're already requesting.
|
||||
|
Loading…
Reference in New Issue
Block a user