浏览代码

fix: renewed certificate and private key not save #391

Jacky 11 月之前
父节点
当前提交
538be53e9c
共有 5 个文件被更改,包括 81 次插入57 次删除
  1. 2 0
      api/certificate/issue.go
  2. 1 0
      internal/cert/auto_cert.go
  3. 1 32
      internal/cert/obtain.go
  4. 50 0
      internal/cert/payload.go
  5. 27 25
      internal/cert/renew.go

+ 2 - 0
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)

+ 1 - 0
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,

+ 1 - 32
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)
 }

+ 50 - 0
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"),
+	})
+}

+ 27 - 25
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")
 }