From 538be53e9cd60e972c8d27f7f4c592f24943c483 Mon Sep 17 00:00:00 2001 From: Jacky Date: Tue, 21 May 2024 14:01:35 +0800 Subject: [PATCH] fix: renewed certificate and private key not save #391 --- api/certificate/issue.go | 2 ++ internal/cert/auto_cert.go | 1 + internal/cert/obtain.go | 33 +----------------------- internal/cert/payload.go | 50 ++++++++++++++++++++++++++++++++++++ internal/cert/renew.go | 52 ++++++++++++++++++++------------------ 5 files changed, 81 insertions(+), 57 deletions(-) diff --git a/api/certificate/issue.go b/api/certificate/issue.go index 90337709..e61c694f 100644 --- a/api/certificate/issue.go +++ b/api/certificate/issue.go @@ -95,6 +95,8 @@ func IssueCert(c *gin.Context) { log := &cert.Logger{} log.SetCertModel(&certModel) + payload.CertID = certModel.ID + go cert.IssueCert(payload, logChan, errChan) go handleIssueCertLogChan(ws, log, logChan) diff --git a/internal/cert/auto_cert.go b/internal/cert/auto_cert.go index e3acadf0..4d623275 100644 --- a/internal/cert/auto_cert.go +++ b/internal/cert/auto_cert.go @@ -71,6 +71,7 @@ func autoCert(certModel *model.Cert) { // support SAN certification payload := &ConfigPayload{ + CertID: certModel.ID, ServerName: certModel.Domains, ChallengeMethod: certModel.ChallengeMethod, DNSCredentialID: certModel.DnsCredentialID, diff --git a/internal/cert/obtain.go b/internal/cert/obtain.go index e7a42f3d..69661ca9 100644 --- a/internal/cert/obtain.go +++ b/internal/cert/obtain.go @@ -1,15 +1,11 @@ package cert import ( - "github.com/0xJacky/Nginx-UI/internal/nginx" "github.com/0xJacky/Nginx-UI/model" "github.com/go-acme/lego/v4/certificate" "github.com/go-acme/lego/v4/lego" "github.com/pkg/errors" "log" - "os" - "path/filepath" - "strings" ) func obtain(payload *ConfigPayload, client *lego.Client, l *log.Logger, errChan chan error) { @@ -31,33 +27,6 @@ func obtain(payload *ConfigPayload, client *lego.Client, l *log.Logger, errChan IssuerCertificate: certificates.IssuerCertificate, CSR: certificates.CSR, } - name := strings.Join(payload.ServerName, "_") - saveDir := nginx.GetConfPath("ssl/" + name + "_" + string(payload.KeyType)) - if _, err = os.Stat(saveDir); os.IsNotExist(err) { - err = os.MkdirAll(saveDir, 0755) - if err != nil { - errChan <- errors.Wrap(err, "mkdir error") - return - } - } - // Each certificate comes back with the cert bytes, the bytes of the client's - // private key, and a certificate URL. SAVE THESE TO DISK. - l.Println("[INFO] [Nginx UI] Writing certificate to disk") - err = os.WriteFile(filepath.Join(saveDir, "fullchain.cer"), - certificates.Certificate, 0644) - - if err != nil { - errChan <- errors.Wrap(err, "write fullchain.cer error") - return - } - - l.Println("[INFO] [Nginx UI] Writing certificate private key to disk") - err = os.WriteFile(filepath.Join(saveDir, "private.key"), - certificates.PrivateKey, 0644) - - if err != nil { - errChan <- errors.Wrap(err, "write private.key error") - return - } + payload.WriteFile(l, errChan) } diff --git a/internal/cert/payload.go b/internal/cert/payload.go index 310ab7d7..857e6301 100644 --- a/internal/cert/payload.go +++ b/internal/cert/payload.go @@ -3,13 +3,20 @@ package cert import ( "github.com/0xJacky/Nginx-UI/internal/helper" "github.com/0xJacky/Nginx-UI/internal/logger" + "github.com/0xJacky/Nginx-UI/internal/nginx" "github.com/0xJacky/Nginx-UI/model" "github.com/0xJacky/Nginx-UI/query" "github.com/go-acme/lego/v4/certcrypto" + "github.com/pkg/errors" + "log" + "os" + "path/filepath" + "strings" "time" ) type ConfigPayload struct { + CertID int `json:"cert_id"` ServerName []string `json:"server_name"` ChallengeMethod string `json:"challenge_method"` DNSCredentialID int `json:"dns_credential_id"` @@ -38,3 +45,46 @@ func (c *ConfigPayload) GetACMEUser() (user *model.AcmeUser, err error) { func (c *ConfigPayload) GetKeyType() certcrypto.KeyType { return helper.GetKeyType(c.KeyType) } + +func (c *ConfigPayload) WriteFile(l *log.Logger, errChan chan error) { + name := strings.Join(c.ServerName, "_") + saveDir := nginx.GetConfPath("ssl/" + name + "_" + string(c.KeyType)) + if _, err := os.Stat(saveDir); os.IsNotExist(err) { + err = os.MkdirAll(saveDir, 0755) + if err != nil { + errChan <- errors.Wrap(err, "mkdir error") + return + } + } + + // Each certificate comes back with the cert bytes, the bytes of the client's + // private key, and a certificate URL. SAVE THESE TO DISK. + l.Println("[INFO] [Nginx UI] Writing certificate to disk") + err := os.WriteFile(filepath.Join(saveDir, "fullchain.cer"), + c.Resource.Certificate, 0644) + + if err != nil { + errChan <- errors.Wrap(err, "write fullchain.cer error") + return + } + + l.Println("[INFO] [Nginx UI] Writing certificate private key to disk") + err = os.WriteFile(filepath.Join(saveDir, "private.key"), + c.Resource.PrivateKey, 0644) + + if err != nil { + errChan <- errors.Wrap(err, "write private.key error") + return + } + + // update database + if c.CertID <= 0 { + return + } + + db := model.UseDB() + db.Where("id = ?", c.CertID).Updates(&model.Cert{ + SSLCertificatePath: filepath.Join(saveDir, "fullchain.cer"), + SSLCertificateKeyPath: filepath.Join(saveDir, "private.key"), + }) +} diff --git a/internal/cert/renew.go b/internal/cert/renew.go index 963e4969..6dbe8690 100644 --- a/internal/cert/renew.go +++ b/internal/cert/renew.go @@ -1,36 +1,38 @@ package cert import ( - "github.com/0xJacky/Nginx-UI/model" - "github.com/go-acme/lego/v4/certificate" - "github.com/go-acme/lego/v4/lego" - "github.com/pkg/errors" - "log" + "github.com/0xJacky/Nginx-UI/model" + "github.com/go-acme/lego/v4/certificate" + "github.com/go-acme/lego/v4/lego" + "github.com/pkg/errors" + "log" ) func renew(payload *ConfigPayload, client *lego.Client, l *log.Logger, errChan chan error) { - if payload.Resource == nil { - errChan <- errors.New("resource is nil") - return - } + if payload.Resource == nil { + errChan <- errors.New("resource is nil") + return + } - options := &certificate.RenewOptions{ - Bundle: true, - } + options := &certificate.RenewOptions{ + Bundle: true, + } - cert, err := client.Certificate.RenewWithOptions(payload.Resource.GetResource(), options) - if err != nil { - errChan <- errors.Wrap(err, "renew cert error") - return - } + cert, err := client.Certificate.RenewWithOptions(payload.Resource.GetResource(), options) + if err != nil { + errChan <- errors.Wrap(err, "renew cert error") + return + } - payload.Resource = &model.CertificateResource{ - Resource: cert, - PrivateKey: cert.PrivateKey, - Certificate: cert.Certificate, - IssuerCertificate: cert.IssuerCertificate, - CSR: cert.CSR, - } + payload.Resource = &model.CertificateResource{ + Resource: cert, + PrivateKey: cert.PrivateKey, + Certificate: cert.Certificate, + IssuerCertificate: cert.IssuerCertificate, + CSR: cert.CSR, + } - l.Println("[INFO] [Nginx UI] Certificate renewed successfully") + payload.WriteFile(l, errChan) + + l.Println("[INFO] [Nginx UI] Certificate renewed successfully") }