From 952e9687d0e8f1d834c923f679bf76e9eaf19af2 Mon Sep 17 00:00:00 2001 From: Leo Chen Date: Wed, 13 Nov 2024 17:58:56 +0800 Subject: [PATCH 1/6] fix misspelling var name --- internal/deployer/tencent_cdn.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/deployer/tencent_cdn.go b/internal/deployer/tencent_cdn.go index a0a44b6a..f5230910 100644 --- a/internal/deployer/tencent_cdn.go +++ b/internal/deployer/tencent_cdn.go @@ -101,9 +101,9 @@ func (d *TencentCDNDeployer) Deploy(ctx context.Context) error { } temp := make([]string, 0) - for _, aliInstanceId := range tcInstanceIds { - if !slices.Contains(deployedDomains, aliInstanceId) { - temp = append(temp, aliInstanceId) + for _, tcInstanceId := range tcInstanceIds { + if !slices.Contains(deployedDomains, tcInstanceId) { + temp = append(temp, tcInstanceId) } } tcInstanceIds = temp From 41bd321a4f32c32d6ccf909bfd32d908fe2fb405 Mon Sep 17 00:00:00 2001 From: Leo Chen Date: Wed, 13 Nov 2024 18:52:29 +0800 Subject: [PATCH 2/6] fixed: not reapply when domain list changed fixed #334 --- internal/domains/deploy.go | 43 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/internal/domains/deploy.go b/internal/domains/deploy.go index c9df14d3..f9a6f406 100644 --- a/internal/domains/deploy.go +++ b/internal/domains/deploy.go @@ -3,13 +3,18 @@ package domains import ( "context" "fmt" + "strings" "time" "github.com/pocketbase/pocketbase/models" + "golang.org/x/exp/slices" + "github.com/usual2970/certimate/internal/applicant" "github.com/usual2970/certimate/internal/deployer" "github.com/usual2970/certimate/internal/utils/app" + + "github.com/usual2970/certimate/internal/pkg/utils/x509" ) type Phase string @@ -45,7 +50,10 @@ func deploy(ctx context.Context, record *models.Record) error { cert := currRecord.GetString("certificate") expiredAt := currRecord.GetDateTime("expiredAt").Time() - if cert != "" && time.Until(expiredAt) > time.Hour*24*10 && currRecord.GetBool("deployed") { + // 检查证书是否包含设置的所有域名 + included := isAllDomainsIncludedInCert(cert, currRecord.GetString("domain")) + + if cert != "" && time.Until(expiredAt) > time.Hour*24*10 && currRecord.GetBool("deployed") && included { app.GetApp().Logger().Info("证书在有效期内") history.record(checkPhase, "证书在有效期内且已部署,跳过", &RecordInfo{ Info: []string{fmt.Sprintf("证书有效期至 %s", expiredAt.Format("2006-01-02"))}, @@ -60,7 +68,7 @@ func deploy(ctx context.Context, record *models.Record) error { // ############2.申请证书 history.record(applyPhase, "开始申请", nil) - if cert != "" && time.Until(expiredAt) > time.Hour*24 { + if cert != "" && time.Until(expiredAt) > time.Hour*24 && included { history.record(applyPhase, "证书在有效期内,跳过", &RecordInfo{ Info: []string{fmt.Sprintf("证书有效期至 %s", expiredAt.Format("2006-01-02"))}, }) @@ -121,3 +129,34 @@ func deploy(ctx context.Context, record *models.Record) error { return nil } + +func isAllDomainsIncludedInCert(certificate, domains string) bool { + // 如果证书为空,直接返回false + if certificate == "" { + return false + } + + // 解析证书 + cert, err := x509.ParseCertificateFromPEM(certificate) + if err != nil { + app.GetApp().Logger().Error("解析证书失败", "err", err) + return false + } + + // 遍历域名列表,检查是否都在证书中,找到第一个不存在证书中域名时提前返回false + for _, domain := range strings.Split(domains, ";") { + if !slices.Contains(cert.DNSNames, domain) && !slices.Contains(cert.DNSNames, "*."+removeLastSubdomain(domain)) { + return false + } + } + + return true +} + +func removeLastSubdomain(domain string) string { + parts := strings.Split(domain, ".") + if len(parts) > 1 { + return strings.Join(parts[1:], ".") + } + return domain +} From 9a75d2ac8f337421e51855147bd39e24efa072a1 Mon Sep 17 00:00:00 2001 From: Leo Chen Date: Fri, 15 Nov 2024 00:33:09 +0800 Subject: [PATCH 3/6] add key algorithm check --- internal/domains/deploy.go | 49 ++++++++++++++++++++++++++++++++++---- 1 file changed, 44 insertions(+), 5 deletions(-) diff --git a/internal/domains/deploy.go b/internal/domains/deploy.go index f9a6f406..85bc14c6 100644 --- a/internal/domains/deploy.go +++ b/internal/domains/deploy.go @@ -6,12 +6,16 @@ import ( "strings" "time" + "crypto/rsa" + "crypto/ecdsa" + "github.com/pocketbase/pocketbase/models" "golang.org/x/exp/slices" "github.com/usual2970/certimate/internal/applicant" "github.com/usual2970/certimate/internal/deployer" + "github.com/usual2970/certimate/internal/domain" "github.com/usual2970/certimate/internal/utils/app" "github.com/usual2970/certimate/internal/pkg/utils/x509" @@ -51,9 +55,9 @@ func deploy(ctx context.Context, record *models.Record) error { expiredAt := currRecord.GetDateTime("expiredAt").Time() // 检查证书是否包含设置的所有域名 - included := isAllDomainsIncludedInCert(cert, currRecord.GetString("domain")) + changed := isCertChanged(cert, currRecord) - if cert != "" && time.Until(expiredAt) > time.Hour*24*10 && currRecord.GetBool("deployed") && included { + if cert != "" && time.Until(expiredAt) > time.Hour*24*10 && currRecord.GetBool("deployed") && changed { app.GetApp().Logger().Info("证书在有效期内") history.record(checkPhase, "证书在有效期内且已部署,跳过", &RecordInfo{ Info: []string{fmt.Sprintf("证书有效期至 %s", expiredAt.Format("2006-01-02"))}, @@ -68,7 +72,7 @@ func deploy(ctx context.Context, record *models.Record) error { // ############2.申请证书 history.record(applyPhase, "开始申请", nil) - if cert != "" && time.Until(expiredAt) > time.Hour*24 && included { + if cert != "" && time.Until(expiredAt) > time.Hour*24 && changed { history.record(applyPhase, "证书在有效期内,跳过", &RecordInfo{ Info: []string{fmt.Sprintf("证书有效期至 %s", expiredAt.Format("2006-01-02"))}, }) @@ -130,7 +134,7 @@ func deploy(ctx context.Context, record *models.Record) error { return nil } -func isAllDomainsIncludedInCert(certificate, domains string) bool { +func isCertChanged(certificate string, record *models.Record) bool { // 如果证书为空,直接返回false if certificate == "" { return false @@ -144,12 +148,47 @@ func isAllDomainsIncludedInCert(certificate, domains string) bool { } // 遍历域名列表,检查是否都在证书中,找到第一个不存在证书中域名时提前返回false - for _, domain := range strings.Split(domains, ";") { + for _, domain := range strings.Split(record.GetString("domain"), ";") { if !slices.Contains(cert.DNSNames, domain) && !slices.Contains(cert.DNSNames, "*."+removeLastSubdomain(domain)) { return false } } + // 解析applyConfig + applyConfig := &domain.ApplyConfig{} + record.UnmarshalJSONField("applyConfig", applyConfig) + + + // 检查证书加密算法是否一致 + switch pubkey := cert.PublicKey.(type) { + case *rsa.PublicKey: + bitSize := pubkey.N.BitLen() + switch bitSize { + case 2048: + // RSA2048 + if applyConfig.KeyAlgorithm != "" && applyConfig.KeyAlgorithm != "RSA2048" { return false } + case 3072: + // RSA3072 + if applyConfig.KeyAlgorithm != "RSA3072" { return false } + case 4096: + // RSA4096 + if applyConfig.KeyAlgorithm != "RSA4096" { return false } + case 8192: + // RSA8192 + if applyConfig.KeyAlgorithm != "RSA8192" { return false } + } + case *ecdsa.PublicKey: + bitSize := pubkey.Curve.Params().BitSize + switch bitSize { + case 256: + // EC256 + if applyConfig.KeyAlgorithm != "EC256" { return false } + case 384: + // EC384 + if applyConfig.KeyAlgorithm != "EC384" { return false } + } + } + return true } From 56eced3813a345b7159b39ca55318f7b09678337 Mon Sep 17 00:00:00 2001 From: Leo Chen Date: Fri, 15 Nov 2024 20:36:47 +0800 Subject: [PATCH 4/6] Invert the boolean value to match the function name --- internal/domains/deploy.go | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/internal/domains/deploy.go b/internal/domains/deploy.go index 85bc14c6..25b47970 100644 --- a/internal/domains/deploy.go +++ b/internal/domains/deploy.go @@ -137,20 +137,20 @@ func deploy(ctx context.Context, record *models.Record) error { func isCertChanged(certificate string, record *models.Record) bool { // 如果证书为空,直接返回false if certificate == "" { - return false + return true } // 解析证书 cert, err := x509.ParseCertificateFromPEM(certificate) if err != nil { app.GetApp().Logger().Error("解析证书失败", "err", err) - return false + return true } // 遍历域名列表,检查是否都在证书中,找到第一个不存在证书中域名时提前返回false for _, domain := range strings.Split(record.GetString("domain"), ";") { if !slices.Contains(cert.DNSNames, domain) && !slices.Contains(cert.DNSNames, "*."+removeLastSubdomain(domain)) { - return false + return true } } @@ -166,30 +166,30 @@ func isCertChanged(certificate string, record *models.Record) bool { switch bitSize { case 2048: // RSA2048 - if applyConfig.KeyAlgorithm != "" && applyConfig.KeyAlgorithm != "RSA2048" { return false } + if applyConfig.KeyAlgorithm != "" && applyConfig.KeyAlgorithm != "RSA2048" { return true } case 3072: // RSA3072 - if applyConfig.KeyAlgorithm != "RSA3072" { return false } + if applyConfig.KeyAlgorithm != "RSA3072" { return true } case 4096: // RSA4096 - if applyConfig.KeyAlgorithm != "RSA4096" { return false } + if applyConfig.KeyAlgorithm != "RSA4096" { return true } case 8192: // RSA8192 - if applyConfig.KeyAlgorithm != "RSA8192" { return false } + if applyConfig.KeyAlgorithm != "RSA8192" { return true } } case *ecdsa.PublicKey: bitSize := pubkey.Curve.Params().BitSize switch bitSize { case 256: // EC256 - if applyConfig.KeyAlgorithm != "EC256" { return false } + if applyConfig.KeyAlgorithm != "EC256" { return true } case 384: // EC384 - if applyConfig.KeyAlgorithm != "EC384" { return false } + if applyConfig.KeyAlgorithm != "EC384" { return true } } } - return true + return false } func removeLastSubdomain(domain string) string { From d1d7b443033347be92a918dfd9e1ffbdb84c5a10 Mon Sep 17 00:00:00 2001 From: Leo Chen Date: Fri, 15 Nov 2024 20:37:36 +0800 Subject: [PATCH 5/6] Invert the changed logic to match the function name --- internal/domains/deploy.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/domains/deploy.go b/internal/domains/deploy.go index 25b47970..f2d8d2af 100644 --- a/internal/domains/deploy.go +++ b/internal/domains/deploy.go @@ -57,7 +57,7 @@ func deploy(ctx context.Context, record *models.Record) error { // 检查证书是否包含设置的所有域名 changed := isCertChanged(cert, currRecord) - if cert != "" && time.Until(expiredAt) > time.Hour*24*10 && currRecord.GetBool("deployed") && changed { + if cert != "" && time.Until(expiredAt) > time.Hour*24*10 && currRecord.GetBool("deployed") && !changed { app.GetApp().Logger().Info("证书在有效期内") history.record(checkPhase, "证书在有效期内且已部署,跳过", &RecordInfo{ Info: []string{fmt.Sprintf("证书有效期至 %s", expiredAt.Format("2006-01-02"))}, @@ -72,7 +72,7 @@ func deploy(ctx context.Context, record *models.Record) error { // ############2.申请证书 history.record(applyPhase, "开始申请", nil) - if cert != "" && time.Until(expiredAt) > time.Hour*24 && changed { + if cert != "" && time.Until(expiredAt) > time.Hour*24 && !changed { history.record(applyPhase, "证书在有效期内,跳过", &RecordInfo{ Info: []string{fmt.Sprintf("证书有效期至 %s", expiredAt.Format("2006-01-02"))}, }) From 3265dd76ab18073f78ee83063ad9adacc0e3a1d7 Mon Sep 17 00:00:00 2001 From: Leo Chen Date: Fri, 15 Nov 2024 20:45:08 +0800 Subject: [PATCH 6/6] edit comments for the forward changes --- internal/domains/deploy.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/domains/deploy.go b/internal/domains/deploy.go index f2d8d2af..8b24c263 100644 --- a/internal/domains/deploy.go +++ b/internal/domains/deploy.go @@ -135,7 +135,7 @@ func deploy(ctx context.Context, record *models.Record) error { } func isCertChanged(certificate string, record *models.Record) bool { - // 如果证书为空,直接返回false + // 如果证书为空,直接返回true if certificate == "" { return true } @@ -147,7 +147,7 @@ func isCertChanged(certificate string, record *models.Record) bool { return true } - // 遍历域名列表,检查是否都在证书中,找到第一个不存在证书中域名时提前返回false + // 遍历域名列表,检查是否都在证书中,找到第一个不存在证书中域名时提前返回true for _, domain := range strings.Split(record.GetString("domain"), ";") { if !slices.Contains(cert.DNSNames, domain) && !slices.Contains(cert.DNSNames, "*."+removeLastSubdomain(domain)) { return true @@ -159,7 +159,7 @@ func isCertChanged(certificate string, record *models.Record) bool { record.UnmarshalJSONField("applyConfig", applyConfig) - // 检查证书加密算法是否一致 + // 检查证书加密算法是否变更 switch pubkey := cert.PublicKey.(type) { case *rsa.PublicKey: bitSize := pubkey.N.BitLen()