mirror of
https://hubproxy.babadafafafafa.cn/https://github.com/1Panel-dev/1Panel.git
synced 2026-09-20 08:03:55 +08:00
Merge pull request #12829 from rowanchen-com/feat/lego-v5-and-dynadot
feat: upgrade lego to v5.1.0 and add Dynadot DNS provider
This commit is contained in:
@@ -61,7 +61,7 @@ type WebsiteSSLObtain struct {
|
||||
type WebsiteAcmeAccountCreate struct {
|
||||
Email string `json:"email" validate:"required"`
|
||||
Type string `json:"type" validate:"required,oneof=letsencrypt zerossl buypass google custom"`
|
||||
KeyType string `json:"keyType" validate:"required,oneof=P256 P384 2048 3072 4096 8192"`
|
||||
KeyType string `json:"keyType" validate:"required,oneof=EC256 EC384 RSA2048 RSA3072 RSA4096 RSA8192"`
|
||||
EabKid string `json:"eabKid"`
|
||||
EabHmacKey string `json:"eabHmacKey"`
|
||||
UseProxy bool `json:"useProxy"`
|
||||
@@ -138,7 +138,7 @@ type WebsiteCACreate struct {
|
||||
Organization string `json:"organization" validate:"required"`
|
||||
OrganizationUint string `json:"organizationUint"`
|
||||
Name string `json:"name" validate:"required"`
|
||||
KeyType string `json:"keyType" validate:"required,oneof=P256 P384 2048 3072 4096 8192"`
|
||||
KeyType string `json:"keyType" validate:"required,oneof=EC256 EC384 RSA2048 RSA3072 RSA4096 RSA8192"`
|
||||
Province string `json:"province" `
|
||||
City string `json:"city"`
|
||||
}
|
||||
@@ -146,7 +146,7 @@ type WebsiteCACreate struct {
|
||||
type WebsiteCAObtain struct {
|
||||
ID uint `json:"id" validate:"required"`
|
||||
Domains string `json:"domains" validate:"required"`
|
||||
KeyType string `json:"keyType" validate:"required,oneof=P256 P384 2048 3072 4096 8192"`
|
||||
KeyType string `json:"keyType" validate:"required,oneof=EC256 EC384 RSA2048 RSA3072 RSA4096 RSA8192"`
|
||||
Time int `json:"time" validate:"required"`
|
||||
Unit string `json:"unit" validate:"required"`
|
||||
PushDir bool `json:"pushDir"`
|
||||
|
||||
@@ -8,7 +8,7 @@ type WebsiteAcmeAccount struct {
|
||||
Type string `gorm:"not null;default:letsencrypt" json:"type"`
|
||||
EabKid string `json:"eabKid"`
|
||||
EabHmacKey string `json:"eabHmacKey"`
|
||||
KeyType string `gorm:"not null;default:2048" json:"keyType"`
|
||||
KeyType string `gorm:"not null;default:RSA2048" json:"keyType"`
|
||||
UseProxy bool `gorm:"default:false" json:"useProxy"`
|
||||
CaDirURL string `json:"caDirURL"`
|
||||
UseEAB bool `json:"useEAB"`
|
||||
|
||||
@@ -5,5 +5,5 @@ type WebsiteCA struct {
|
||||
CSR string `gorm:"not null;" json:"csr"`
|
||||
Name string `gorm:"not null;" json:"name"`
|
||||
PrivateKey string `gorm:"not null" json:"privateKey"`
|
||||
KeyType string `gorm:"not null;default:2048" json:"keyType"`
|
||||
KeyType string `gorm:"not null;default:RSA2048" json:"keyType"`
|
||||
}
|
||||
|
||||
@@ -2153,7 +2153,7 @@ func handleSSLConfig(appInstall *model.AppInstall, hasDefaultWebsite bool, sslRe
|
||||
caRequest := request.WebsiteCAObtain{
|
||||
ID: ca.ID,
|
||||
Domains: "localhost",
|
||||
KeyType: "4096",
|
||||
KeyType: "RSA4096",
|
||||
Time: 99,
|
||||
Unit: "year",
|
||||
Dir: sslDir,
|
||||
|
||||
@@ -68,7 +68,7 @@ func (w WebsiteAcmeAccountService) Create(create request.WebsiteAcmeAccountCreat
|
||||
return nil, err
|
||||
}
|
||||
acmeAccount.PrivateKey = string(privateKey)
|
||||
acmeAccount.URL = client.User.Registration.URI
|
||||
acmeAccount.URL = client.User.Registration.Location
|
||||
|
||||
if err := websiteAcmeRepo.Create(*acmeAccount); err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -30,7 +30,7 @@ import (
|
||||
"github.com/1Panel-dev/1Panel/agent/i18n"
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/files"
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/ssl"
|
||||
"github.com/go-acme/lego/v4/certcrypto"
|
||||
"github.com/go-acme/lego/v5/certcrypto"
|
||||
)
|
||||
|
||||
type WebsiteCAService struct {
|
||||
|
||||
@@ -7,14 +7,15 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"log/slog"
|
||||
"os"
|
||||
"path"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/go-acme/lego/v4/certificate"
|
||||
legoLogger "github.com/go-acme/lego/v4/log"
|
||||
"github.com/go-acme/lego/v5/certificate"
|
||||
legoLogger "github.com/go-acme/lego/v5/log"
|
||||
"github.com/jinzhu/gorm"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/agent/app/dto/request"
|
||||
@@ -347,7 +348,10 @@ func (w WebsiteSSLService) obtainSSL(id uint, autoRenew bool) error {
|
||||
if logFile != nil {
|
||||
defer logFile.Close()
|
||||
}
|
||||
legoLogger.Logger = logger
|
||||
// lego v5 switched to slog. Bridge it to the existing *log.Logger
|
||||
// so the SSL apply log is still written to the per-domain file
|
||||
// under SSLLogDir.
|
||||
legoLogger.SetDefault(slog.New(slog.NewTextHandler(logger.Writer(), nil)))
|
||||
startMsg := i18n.GetMsgWithMap("ApplySSLStart", map[string]interface{}{"domain": strings.Join(domains, ","), "type": i18n.GetMsgByKey(websiteSSL.Provider)})
|
||||
if websiteSSL.Provider == constant.DNSAccount {
|
||||
startMsg = startMsg + i18n.GetMsgWithMap("DNSAccountName", map[string]interface{}{"name": dnsAccount.Name, "type": dnsAccount.Type})
|
||||
@@ -474,7 +478,9 @@ func handleError(websiteSSL *model.WebsiteSSL, err error) {
|
||||
websiteSSL.Status = constant.SSLApplyError
|
||||
}
|
||||
websiteSSL.Message = err.Error()
|
||||
legoLogger.Logger.Println(i18n.GetErrMsg("ApplySSLFailed", map[string]interface{}{"domain": websiteSSL.PrimaryDomain, "detail": err.Error()}))
|
||||
// lego v5 uses slog; use the same global default logger to write the
|
||||
// failure message to the SSL log.
|
||||
legoLogger.Default().Error(i18n.GetErrMsg("ApplySSLFailed", map[string]interface{}{"domain": websiteSSL.PrimaryDomain, "detail": err.Error()}))
|
||||
_ = websiteSSLRepo.Save(websiteSSL)
|
||||
}
|
||||
|
||||
|
||||
16
agent/go.mod
16
agent/go.mod
@@ -14,7 +14,7 @@ require (
|
||||
github.com/fsnotify/fsnotify v1.9.0
|
||||
github.com/gin-gonic/gin v1.12.0
|
||||
github.com/glebarez/sqlite v1.11.0
|
||||
github.com/go-acme/lego/v4 v4.35.2
|
||||
github.com/go-acme/lego/v5 v5.1.0
|
||||
github.com/go-gormigrate/gormigrate/v2 v2.1.5
|
||||
github.com/go-playground/validator/v10 v10.30.2
|
||||
github.com/go-redis/redis v6.15.9+incompatible
|
||||
@@ -58,7 +58,7 @@ require (
|
||||
golang.org/x/text v0.37.0
|
||||
golang.org/x/time v0.15.0
|
||||
google.golang.org/genproto v0.0.0-20260414002931-afd174a4e478
|
||||
gopkg.in/ini.v1 v1.67.1
|
||||
gopkg.in/ini.v1 v1.67.2
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
gorm.io/gorm v1.31.1
|
||||
)
|
||||
@@ -84,13 +84,13 @@ require (
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.24 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.9 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.23 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/route53 v1.62.6 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/route53 v1.62.7 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/signin v1.0.11 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.30.17 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.21 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.42.1 // indirect
|
||||
github.com/aws/smithy-go v1.25.1 // indirect
|
||||
github.com/baidubce/bce-sdk-go v0.9.265 // indirect
|
||||
github.com/baidubce/bce-sdk-go v0.9.266 // indirect
|
||||
github.com/bodgit/plumbing v1.3.0 // indirect
|
||||
github.com/bodgit/sevenzip v1.6.1 // indirect
|
||||
github.com/bodgit/windows v1.0.1 // indirect
|
||||
@@ -152,7 +152,7 @@ require (
|
||||
github.com/kr/fs v0.1.0 // indirect
|
||||
github.com/leodido/go-urn v1.4.0 // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20260330125221-c963978e514e // indirect
|
||||
github.com/mattn/go-isatty v0.0.21 // indirect
|
||||
github.com/mattn/go-isatty v0.0.22 // indirect
|
||||
github.com/mattn/go-shellwords v1.0.13 // indirect
|
||||
github.com/minio/crc64nvme v1.1.1 // indirect
|
||||
github.com/minio/md5-simd v1.1.2 // indirect
|
||||
@@ -171,7 +171,6 @@ require (
|
||||
github.com/mozillazg/go-httpheader v0.4.0 // indirect
|
||||
github.com/namedotcom/go/v4 v4.0.2 // indirect
|
||||
github.com/ncruces/go-strftime v1.0.0 // indirect
|
||||
github.com/nrdcg/dnspod-go v0.4.0 // indirect
|
||||
github.com/nrdcg/freemyip v0.3.0 // indirect
|
||||
github.com/nrdcg/goacmedns v0.2.0 // indirect
|
||||
github.com/nrdcg/namesilo v0.5.0 // indirect
|
||||
@@ -191,7 +190,7 @@ require (
|
||||
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 // indirect
|
||||
github.com/spf13/cast v1.10.0 // indirect
|
||||
github.com/spf13/pflag v1.0.10 // indirect
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.83 // indirect
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.102 // indirect
|
||||
github.com/therootcompany/xz v1.0.1 // indirect
|
||||
github.com/tinylib/msgp v1.6.4 // indirect
|
||||
github.com/tjfoc/gmsm v1.4.1 // indirect
|
||||
@@ -200,7 +199,7 @@ require (
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.3.1 // indirect
|
||||
github.com/ulikunitz/xz v0.5.15 // indirect
|
||||
github.com/volcengine/volc-sdk-golang v1.0.242 // indirect
|
||||
github.com/volcengine/volc-sdk-golang v1.0.248 // indirect
|
||||
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
|
||||
github.com/xdg-go/scram v1.2.0 // indirect
|
||||
github.com/xdg-go/stringprep v1.0.4 // indirect
|
||||
@@ -227,4 +226,5 @@ require (
|
||||
modernc.org/mathutil v1.7.1 // indirect
|
||||
modernc.org/memory v1.11.0 // indirect
|
||||
modernc.org/sqlite v1.48.2 // indirect
|
||||
software.sslmate.com/src/go-pkcs12 v0.7.1 // indirect
|
||||
)
|
||||
|
||||
40
agent/go.sum
40
agent/go.sum
@@ -145,8 +145,8 @@ github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.9 h1:FLudkZL
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.9/go.mod h1:w7wZ/s9qK7c8g4al+UyoF1Sp/Z45UwMGcqIzLWVQHWk=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.23 h1:pbrxO/kuIwgEsOPLkaHu0O+m4fNgLU8B3vxQ+72jTPw=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.23/go.mod h1:/CMNUqoj46HpS3MNRDEDIwcgEnrtZlKRaHNaHxIFpNA=
|
||||
github.com/aws/aws-sdk-go-v2/service/route53 v1.62.6 h1:6b+KS0uVMMsCUKlW8OPNxmcEmoEUtqP1LfnzSzWmuQM=
|
||||
github.com/aws/aws-sdk-go-v2/service/route53 v1.62.6/go.mod h1:+wmraHmxwqi7feUL/41uULJWl8V1HxtxzOJH6a4ZRg4=
|
||||
github.com/aws/aws-sdk-go-v2/service/route53 v1.62.7 h1:twRRMmtSITnt/rrp+D7UDLzE5pKMZe759aalkUdN+OY=
|
||||
github.com/aws/aws-sdk-go-v2/service/route53 v1.62.7/go.mod h1:ztM1lr+sRoCAI8336ZUvlRPbToue0d3gE/wd6jomSJ8=
|
||||
github.com/aws/aws-sdk-go-v2/service/signin v1.0.11 h1:TdJ+HdzOBhU8+iVAOGUTU63VXopcumCOF1paFulHWZc=
|
||||
github.com/aws/aws-sdk-go-v2/service/signin v1.0.11/go.mod h1:R82ZRExE/nheo0N+T8zHPcLRTcH8MGsnR3BiVGX0TwI=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.30.17 h1:7byT8HUWrgoRp6sXjxtZwgOKfhss5fW6SkLBtqzgRoE=
|
||||
@@ -158,8 +158,8 @@ github.com/aws/aws-sdk-go-v2/service/sts v1.42.1/go.mod h1:mTNxImtovCOEEuD65mKW7
|
||||
github.com/aws/smithy-go v1.8.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E=
|
||||
github.com/aws/smithy-go v1.25.1 h1:J8ERsGSU7d+aCmdQur5Txg6bVoYelvQJgtZehD12GkI=
|
||||
github.com/aws/smithy-go v1.25.1/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc=
|
||||
github.com/baidubce/bce-sdk-go v0.9.265 h1:xZeLhmADeOmmV+Zlt+3TelazS0czBNXELYSPrbtU3zE=
|
||||
github.com/baidubce/bce-sdk-go v0.9.265/go.mod h1:zbYJMQwE4IZuyrJiFO8tO8NbtYiKTFTbwh4eIsqjVdg=
|
||||
github.com/baidubce/bce-sdk-go v0.9.266 h1:MDWm/S4TNRZRH8Mo5J0t4gq34G3y2+WcbG0KCGLEpek=
|
||||
github.com/baidubce/bce-sdk-go v0.9.266/go.mod h1:zbYJMQwE4IZuyrJiFO8tO8NbtYiKTFTbwh4eIsqjVdg=
|
||||
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
@@ -297,8 +297,8 @@ github.com/go-acme/alidns-20150109/v4 v4.7.0 h1:PqJ/wR0JTpL4v0Owu1uM7bPQ1Yww0eQL
|
||||
github.com/go-acme/alidns-20150109/v4 v4.7.0/go.mod h1:btQvB6xZoN6ykKB74cPhiR+uvhrEE2AFVXm6RDmCHm0=
|
||||
github.com/go-acme/esa-20240910/v2 v2.48.0 h1:muSDyhjDTejxUGe3FTthCPCqRaEdYY9cG3N/AmU52Lc=
|
||||
github.com/go-acme/esa-20240910/v2 v2.48.0/go.mod h1:shPb6hzc1rJL15IJBY8HQ4GZk4E8RC52+52twutEwIg=
|
||||
github.com/go-acme/lego/v4 v4.35.2 h1:uVQg+KC/yj9R2g7Q9W5wDqhvQvxV5SMu5eqFVoN5xZU=
|
||||
github.com/go-acme/lego/v4 v4.35.2/go.mod h1:pX2jN5n8OphMGY1IaMjYm5DAEzguBaKRt8AvJAgJXpc=
|
||||
github.com/go-acme/lego/v5 v5.1.0 h1:8JvnoRgH6uyFENTKS+3+JXdobpo4jYGfj4Bs4izVwmk=
|
||||
github.com/go-acme/lego/v5 v5.1.0/go.mod h1:oCmaeLjpcqHmB1JGqGzsAjCMXXCPbDpNCckYv6J47m4=
|
||||
github.com/go-acme/tencentclouddnspod v1.3.24 h1:uCSiOW1EJttcnOON+MVVyVDJguFL/Q4NIGkq1CrT9p8=
|
||||
github.com/go-acme/tencentclouddnspod v1.3.24/go.mod h1:RKcB2wSoZncjBA0OEFj59s1ko1XDy+ZsAtk+9uMxUF0=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
@@ -587,8 +587,8 @@ github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcME
|
||||
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/mattn/go-isatty v0.0.21 h1:xYae+lCNBP7QuW4PUnNG61ffM4hVIfm+zUzDuSzYLGs=
|
||||
github.com/mattn/go-isatty v0.0.21/go.mod h1:ZXfXG4SQHsB/w3ZeOYbR0PrPwLy+n6xiMrJlRFqopa4=
|
||||
github.com/mattn/go-isatty v0.0.22 h1:j8l17JJ9i6VGPUFUYoTUKPSgKe/83EYU2zBC7YNKMw4=
|
||||
github.com/mattn/go-isatty v0.0.22/go.mod h1:ZXfXG4SQHsB/w3ZeOYbR0PrPwLy+n6xiMrJlRFqopa4=
|
||||
github.com/mattn/go-shellwords v1.0.13 h1:DC0OMEpGjm6LfNFU4ckYcvbQKyp2vE8atyFGXNtDcf4=
|
||||
github.com/mattn/go-shellwords v1.0.13/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus=
|
||||
@@ -667,8 +667,6 @@ github.com/ncruces/go-strftime v1.0.0/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJm
|
||||
github.com/nicksnyder/go-i18n/v2 v2.6.1 h1:JDEJraFsQE17Dut9HFDHzCoAWGEQJom5s0TRd17NIEQ=
|
||||
github.com/nicksnyder/go-i18n/v2 v2.6.1/go.mod h1:Vee0/9RD3Quc/NmwEjzzD7VTZ+Ir7QbXocrkhOzmUKA=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/nrdcg/dnspod-go v0.4.0 h1:c/jn1mLZNKF3/osJ6mz3QPxTudvPArXTjpkmYj0uK6U=
|
||||
github.com/nrdcg/dnspod-go v0.4.0/go.mod h1:vZSoFSFeQVm2gWLMkyX61LZ8HI3BaqtHZWgPTGKr6KQ=
|
||||
github.com/nrdcg/freemyip v0.3.0 h1:0D2rXgvLwe2RRaVIjyUcQ4S26+cIS2iFwnhzDsEuuwc=
|
||||
github.com/nrdcg/freemyip v0.3.0/go.mod h1:c1PscDvA0ukBF0dwelU/IwOakNKnVxetpAQ863RMJoM=
|
||||
github.com/nrdcg/goacmedns v0.2.0 h1:ADMbThobzEMnr6kg2ohs4KGa3LFqmgiBA22/6jUWJR0=
|
||||
@@ -834,8 +832,8 @@ github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8
|
||||
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.563/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y=
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.24/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.83 h1:C8ro7XQVV17O+A7zUTe28VK02NuyazuaY0CB2CH5Scw=
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.83/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.102 h1:3n7BpLOPnE9Rv3Y9Jxgl/XaQX3GzktO+dEaAbtVbjSk=
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.102/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/kms v1.0.563/go.mod h1:uom4Nvi9W+Qkom0exYiJ9VWJjXwyxtPYTkKkaLMlfE0=
|
||||
github.com/tencentyun/cos-go-sdk-v5 v0.7.73 h1:uFfgp1A7cQaAGR6QP9DsIkoEQ67b8ewj5r1RV6XB540=
|
||||
github.com/tencentyun/cos-go-sdk-v5 v0.7.73/go.mod h1:STbTNaNKq03u+gscPEGOahKzLcGSYOj6Dzc5zNay7Pg=
|
||||
@@ -864,8 +862,8 @@ github.com/ulikunitz/xz v0.5.15/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0o
|
||||
github.com/upyun/go-sdk v2.1.0+incompatible h1:OdjXghQ/TVetWV16Pz3C1/SUpjhGBVPr+cLiqZLLyq0=
|
||||
github.com/upyun/go-sdk v2.1.0+incompatible/go.mod h1:eu3F5Uz4b9ZE5bE5QsCL6mgSNWRwfj0zpJ9J626HEqs=
|
||||
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
|
||||
github.com/volcengine/volc-sdk-golang v1.0.242 h1:YEnYLl8mn83JCdO/X5GRDvxfxGvpUqk5j0Mj4VhwM6Y=
|
||||
github.com/volcengine/volc-sdk-golang v1.0.242/go.mod h1:zHJlaqiMbIB+0mcrsZPTwOb3FB7S/0MCfqlnO8R7hlM=
|
||||
github.com/volcengine/volc-sdk-golang v1.0.248 h1:2XxvADkC9Q3UNxE1/X/QhRB45Ic2z7dbH33jZurwB8I=
|
||||
github.com/volcengine/volc-sdk-golang v1.0.248/go.mod h1:zHJlaqiMbIB+0mcrsZPTwOb3FB7S/0MCfqlnO8R7hlM=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
|
||||
github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs=
|
||||
@@ -1345,8 +1343,8 @@ google.golang.org/genproto v0.0.0-20260414002931-afd174a4e478 h1:aLsVTW0lZ8+IY5u
|
||||
google.golang.org/genproto v0.0.0-20260414002931-afd174a4e478/go.mod h1:YJAzKjfHIUHb9T+bfu8L7mthAp7VVXQBUs1PLdBWS7M=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478 h1:yQugLulqltosq0B/f8l4w9VryjV+N/5gcW0jQ3N8Qec=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478/go.mod h1:C6ADNqOxbgdUUeRTU+LCHDPB9ttAMCTff6auwCVa4uc=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 h1:RmoJA1ujG+/lRGNfUnOMfhCy5EipVMyvUE+KNbPbTlw=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260511170946-3700d4141b60 h1:seT2EwLWM78plQ7wcDfuWBc/4FAEAXDDiaSol4ku4qo=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260511170946-3700d4141b60/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
@@ -1364,8 +1362,8 @@ google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv
|
||||
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
||||
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
|
||||
google.golang.org/grpc v1.80.0 h1:Xr6m2WmWZLETvUNvIUmeD5OAagMw3FiKmMlTdViWsHM=
|
||||
google.golang.org/grpc v1.80.0/go.mod h1:ho/dLnxwi3EDJA4Zghp7k2Ec1+c2jqup0bFkw07bwF4=
|
||||
google.golang.org/grpc v1.81.1 h1:VnnIIZ88UzOOKLukQi+ImGz8O1Wdp8nAGGnvOfEIWQQ=
|
||||
google.golang.org/grpc v1.81.1/go.mod h1:xGH9GfzOyMTGIOXBJmXt+BX/V0kcdQbdcuwQ/zNw42I=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
@@ -1394,8 +1392,8 @@ gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMy
|
||||
gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
|
||||
gopkg.in/ini.v1 v1.56.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.67.1 h1:tVBILHy0R6e4wkYOn3XmiITt/hEVH4TFMYvAX2Ytz6k=
|
||||
gopkg.in/ini.v1 v1.67.1/go.mod h1:x/cyOwCgZqOkJoDIJ3c1KNHMo10+nLGAhh+kn3Zizss=
|
||||
gopkg.in/ini.v1 v1.67.2 h1:JtOSMb9OuaCZKr7h5D/h6iii14sK0hLbplTc6frx4Ss=
|
||||
gopkg.in/ini.v1 v1.67.2/go.mod h1:x/cyOwCgZqOkJoDIJ3c1KNHMo10+nLGAhh+kn3Zizss=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
@@ -1457,3 +1455,5 @@ rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
|
||||
software.sslmate.com/src/go-pkcs12 v0.7.1 h1:bxkUPRsvTPNRBZa4M/aSX4PyMOEbq3V8I6hbkG4F4Q8=
|
||||
software.sslmate.com/src/go-pkcs12 v0.7.1/go.mod h1:Qiz0EyvDRJjjxGyUQa2cCNZn/wMyzrRJ/qcDXOQazLI=
|
||||
|
||||
@@ -68,7 +68,7 @@ func initAcmeAccount() {
|
||||
createAcmeAccount := request.WebsiteAcmeAccountCreate{
|
||||
Email: "acme@1paneldev.com",
|
||||
Type: "letsencrypt",
|
||||
KeyType: "2048",
|
||||
KeyType: "RSA2048",
|
||||
}
|
||||
systemProxy, _ := service.NewISettingService().GetSystemProxy()
|
||||
if systemProxy.URL != "" {
|
||||
|
||||
@@ -83,6 +83,7 @@ func InitAgentDB() {
|
||||
migrations.AddFileManageAISettings,
|
||||
migrations.AddFileShareTable,
|
||||
migrations.AddFileHistoryTable,
|
||||
migrations.MigrateLegoV5,
|
||||
})
|
||||
if err := m.Migrate(); err != nil {
|
||||
global.LOG.Error(err)
|
||||
|
||||
@@ -233,7 +233,7 @@ var InitDefaultCA = &gormigrate.Migration{
|
||||
if _, err := caService.Create(request.WebsiteCACreate{
|
||||
CommonName: "1Panel-CA",
|
||||
Country: "CN",
|
||||
KeyType: "P256",
|
||||
KeyType: "EC256",
|
||||
Name: "1Panel",
|
||||
Organization: "FIT2CLOUD",
|
||||
OrganizationUint: "1Panel",
|
||||
@@ -1260,3 +1260,56 @@ var AddFileHistoryTable = &gormigrate.Migration{
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
// MigrateLegoV5 normalizes data persisted under lego v4 so that lego v5 can read it.
|
||||
//
|
||||
// Two things changed in lego v5 that affect existing rows:
|
||||
//
|
||||
// 1. certcrypto.KeyType string values were renamed:
|
||||
// "P256"->"EC256", "P384"->"EC384",
|
||||
// "2048"->"RSA2048", "3072"->"RSA3072", "4096"->"RSA4096", "8192"->"RSA8192".
|
||||
// We update every key_type column we own to the new form.
|
||||
//
|
||||
// 2. DnsPod provider was removed from upstream lego v5; the frontend already
|
||||
// marked it deprecated. Existing DnsPod website_dns_accounts rows are kept
|
||||
// so the user can decide what to do, but any website_ssls still pointing
|
||||
// at a DnsPod account would fail to renew. We log a warning row count and
|
||||
// leave deletion to the operator.
|
||||
var MigrateLegoV5 = &gormigrate.Migration{
|
||||
ID: "20260523-migrate-lego-v5",
|
||||
Migrate: func(tx *gorm.DB) error {
|
||||
keyTypeMap := map[string]string{
|
||||
"P256": "EC256",
|
||||
"P384": "EC384",
|
||||
"2048": "RSA2048",
|
||||
"3072": "RSA3072",
|
||||
"4096": "RSA4096",
|
||||
"8192": "RSA8192",
|
||||
}
|
||||
for old, neu := range keyTypeMap {
|
||||
if err := tx.Model(&model.WebsiteAcmeAccount{}).
|
||||
Where("key_type = ?", old).
|
||||
Update("key_type", neu).Error; err != nil {
|
||||
return fmt.Errorf("migrate WebsiteAcmeAccount.key_type %s->%s: %w", old, neu, err)
|
||||
}
|
||||
if err := tx.Model(&model.WebsiteSSL{}).
|
||||
Where("key_type = ?", old).
|
||||
Update("key_type", neu).Error; err != nil {
|
||||
return fmt.Errorf("migrate WebsiteSSL.key_type %s->%s: %w", old, neu, err)
|
||||
}
|
||||
if err := tx.Model(&model.WebsiteCA{}).
|
||||
Where("key_type = ?", old).
|
||||
Update("key_type", neu).Error; err != nil {
|
||||
return fmt.Errorf("migrate WebsiteCA.key_type %s->%s: %w", old, neu, err)
|
||||
}
|
||||
}
|
||||
|
||||
var dnsPodCount int64
|
||||
_ = tx.Model(&model.WebsiteDnsAccount{}).Where("type = ?", "DnsPod").Count(&dnsPodCount).Error
|
||||
if dnsPodCount > 0 {
|
||||
global.LOG.Warnf("lego v5 removed the DnsPod provider; %d existing DnsPod DNS account(s) will not be usable for renewal -- please switch them to TencentCloud", dnsPodCount)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package ssl
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto"
|
||||
"crypto/ecdsa"
|
||||
"crypto/rsa"
|
||||
@@ -10,9 +11,6 @@ import (
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/1Panel-dev/1Panel/agent/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/agent/buserr"
|
||||
"golang.org/x/crypto/acme"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
@@ -22,14 +20,46 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"golang.org/x/crypto/acme"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/agent/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/agent/app/model"
|
||||
"github.com/go-acme/lego/v4/certcrypto"
|
||||
"github.com/go-acme/lego/v4/lego"
|
||||
"github.com/go-acme/lego/v4/registration"
|
||||
"github.com/1Panel-dev/1Panel/agent/buserr"
|
||||
legoacme "github.com/go-acme/lego/v5/acme"
|
||||
"github.com/go-acme/lego/v5/certcrypto"
|
||||
"github.com/go-acme/lego/v5/certcrypto/compat"
|
||||
"github.com/go-acme/lego/v5/lego"
|
||||
"github.com/go-acme/lego/v5/registration"
|
||||
)
|
||||
|
||||
var Orders = make(map[uint]*acme.Order)
|
||||
|
||||
// parsePrivateKeyPEM decodes a PEM-encoded private key produced by either
|
||||
// lego v4 (SEC1 for EC, PKCS#1 for RSA) or lego v5 (PKCS#8 for both). It tries
|
||||
// PKCS#8 first because that is what v5 and any modern tooling emits, then
|
||||
// falls back to the legacy formats so account keys persisted under v4 keep
|
||||
// working without manual conversion.
|
||||
func parsePrivateKeyPEM(pemBytes []byte) (crypto.Signer, error) {
|
||||
block, _ := pem.Decode(pemBytes)
|
||||
if block == nil {
|
||||
return nil, buserr.New("invalid PEM block")
|
||||
}
|
||||
if key, err := x509.ParsePKCS8PrivateKey(block.Bytes); err == nil {
|
||||
signer, ok := key.(crypto.Signer)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("PKCS#8 key does not implement crypto.Signer")
|
||||
}
|
||||
return signer, nil
|
||||
}
|
||||
if key, err := x509.ParseECPrivateKey(block.Bytes); err == nil {
|
||||
return key, nil
|
||||
}
|
||||
if key, err := x509.ParsePKCS1PrivateKey(block.Bytes); err == nil {
|
||||
return key, nil
|
||||
}
|
||||
return nil, fmt.Errorf("unsupported private key format")
|
||||
}
|
||||
|
||||
type zeroSSLRes struct {
|
||||
Success bool `json:"success"`
|
||||
EabKid string `json:"eab_kid"`
|
||||
@@ -46,20 +76,35 @@ const (
|
||||
KeyRSA4096 = certcrypto.RSA4096
|
||||
)
|
||||
|
||||
// normalizeKeyType maps legacy v4 KeyType strings (P256/P384/2048/...) to the
|
||||
// v5 form (EC256/EC384/RSA2048/...) using lego v5's official compat helper, so
|
||||
// any account/SSL row written under v4 keeps loading without manual conversion.
|
||||
// Unknown values are returned as-is and let the downstream caller error out.
|
||||
func normalizeKeyType(stored string) KeyType {
|
||||
var k compat.KeyTypeCompat
|
||||
if err := k.UnmarshalText([]byte(stored)); err != nil {
|
||||
return KeyType(stored)
|
||||
}
|
||||
return KeyType(k)
|
||||
}
|
||||
|
||||
// AcmeUser implements registration.User. Key is crypto.Signer
|
||||
// (lego v5 changed the field type from crypto.PrivateKey to crypto.Signer).
|
||||
type AcmeUser struct {
|
||||
Email string
|
||||
Registration *registration.Resource
|
||||
Key crypto.PrivateKey
|
||||
Registration *legoacme.ExtendedAccount
|
||||
Key crypto.Signer
|
||||
}
|
||||
|
||||
func (u *AcmeUser) GetEmail() string {
|
||||
return u.Email
|
||||
}
|
||||
|
||||
func (u *AcmeUser) GetRegistration() *registration.Resource {
|
||||
func (u *AcmeUser) GetRegistration() *legoacme.ExtendedAccount {
|
||||
return u.Registration
|
||||
}
|
||||
func (u *AcmeUser) GetPrivateKey() crypto.PrivateKey {
|
||||
|
||||
func (u *AcmeUser) GetPrivateKey() crypto.Signer {
|
||||
return u.Key
|
||||
}
|
||||
|
||||
@@ -95,31 +140,28 @@ func GetPrivateKey(priKey crypto.PrivateKey, keyType KeyType) ([]byte, error) {
|
||||
|
||||
func NewRegisterClient(acmeAccount *model.WebsiteAcmeAccount, proxy *dto.SystemProxy) (*AcmeClient, error) {
|
||||
var (
|
||||
priKey crypto.PrivateKey
|
||||
priKey crypto.Signer
|
||||
err error
|
||||
)
|
||||
|
||||
if acmeAccount.PrivateKey != "" {
|
||||
switch KeyType(acmeAccount.KeyType) {
|
||||
case KeyEC256, KeyEC384:
|
||||
block, _ := pem.Decode([]byte(acmeAccount.PrivateKey))
|
||||
priKey, err = x509.ParseECPrivateKey(block.Bytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case KeyRSA2048, KeyRSA3072, KeyRSA4096:
|
||||
block, _ := pem.Decode([]byte(acmeAccount.PrivateKey))
|
||||
priKey, err = x509.ParsePKCS1PrivateKey(block.Bytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
keyType := normalizeKeyType(acmeAccount.KeyType)
|
||||
|
||||
} else {
|
||||
priKey, err = certcrypto.GeneratePrivateKey(KeyType(acmeAccount.KeyType))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if acmeAccount.PrivateKey != "" {
|
||||
signer, parseErr := parsePrivateKeyPEM([]byte(acmeAccount.PrivateKey))
|
||||
if parseErr != nil {
|
||||
return nil, parseErr
|
||||
}
|
||||
priKey = signer
|
||||
} else {
|
||||
generated, genErr := certcrypto.GeneratePrivateKey(keyType)
|
||||
if genErr != nil {
|
||||
return nil, genErr
|
||||
}
|
||||
signer, ok := generated.(crypto.Signer)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("generated key does not implement crypto.Signer")
|
||||
}
|
||||
priKey = signer
|
||||
}
|
||||
|
||||
myUser := &AcmeUser{
|
||||
@@ -131,7 +173,10 @@ func NewRegisterClient(acmeAccount *model.WebsiteAcmeAccount, proxy *dto.SystemP
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var reg *registration.Resource
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
var reg *legoacme.ExtendedAccount
|
||||
if acmeAccount.Type == "zerossl" || acmeAccount.Type == "google" || acmeAccount.Type == "freessl" || (acmeAccount.Type == "custom" && acmeAccount.UseEAB) {
|
||||
if acmeAccount.Type == "zerossl" {
|
||||
var res *zeroSSLRes
|
||||
@@ -152,12 +197,12 @@ func NewRegisterClient(acmeAccount *model.WebsiteAcmeAccount, proxy *dto.SystemP
|
||||
Kid: acmeAccount.EabKid,
|
||||
HmacEncoded: acmeAccount.EabHmacKey,
|
||||
}
|
||||
reg, err = client.Registration.RegisterWithExternalAccountBinding(eabOptions)
|
||||
reg, err = client.Registration.RegisterWithExternalAccountBinding(ctx, eabOptions)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
reg, err = client.Registration.Register(registration.RegisterOptions{TermsOfServiceAgreed: true})
|
||||
reg, err = client.Registration.Register(ctx, registration.RegisterOptions{TermsOfServiceAgreed: true})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -205,13 +250,14 @@ func NewConfigWithProxy(user registration.User, accountType, customCaURL string,
|
||||
proxyUser = systemProxy.User
|
||||
proxyPassword = systemProxy.Password
|
||||
}
|
||||
// lego v5 removed lego.CertificateConfig.KeyType; the key type is now
|
||||
// taken from the user's account for each ObtainRequest call.
|
||||
return &lego.Config{
|
||||
CADirURL: caDirURL,
|
||||
UserAgent: "1Panel",
|
||||
User: user,
|
||||
HTTPClient: createHTTPClientWithProxy(proxyURL, proxyUser, proxyPassword),
|
||||
Certificate: lego.CertificateConfig{
|
||||
KeyType: certcrypto.RSA2048,
|
||||
Timeout: 60 * time.Second,
|
||||
},
|
||||
}
|
||||
@@ -312,38 +358,21 @@ func getZeroSSLEabCredentials(email string) (*zeroSSLRes, error) {
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func GetPrivateKeyByType(keyType, sslPrivateKey string) (crypto.PrivateKey, error) {
|
||||
var (
|
||||
privateKey crypto.PrivateKey
|
||||
err error
|
||||
)
|
||||
kType := KeyType(keyType)
|
||||
// GetPrivateKeyByType returns a crypto.Signer (lego v5 changed from crypto.PrivateKey).
|
||||
func GetPrivateKeyByType(keyType, sslPrivateKey string) (crypto.Signer, error) {
|
||||
kType := normalizeKeyType(keyType)
|
||||
if sslPrivateKey == "" {
|
||||
privateKey, err = certcrypto.GeneratePrivateKey(kType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
generated, genErr := certcrypto.GeneratePrivateKey(kType)
|
||||
if genErr != nil {
|
||||
return nil, genErr
|
||||
}
|
||||
return privateKey, nil
|
||||
}
|
||||
block, _ := pem.Decode([]byte(sslPrivateKey))
|
||||
if block == nil {
|
||||
return nil, buserr.New("invalid PEM block")
|
||||
}
|
||||
var privKey crypto.PrivateKey
|
||||
switch kType {
|
||||
case certcrypto.EC256, certcrypto.EC384:
|
||||
privKey, err = x509.ParseECPrivateKey(block.Bytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case certcrypto.RSA2048, certcrypto.RSA3072, certcrypto.RSA4096:
|
||||
privKey, err = x509.ParsePKCS1PrivateKey(block.Bytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
signer, ok := generated.(crypto.Signer)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("generated key does not implement crypto.Signer")
|
||||
}
|
||||
return signer, nil
|
||||
}
|
||||
privateKey = privKey
|
||||
return privateKey, nil
|
||||
return parsePrivateKeyPEM([]byte(sslPrivateKey))
|
||||
}
|
||||
|
||||
func getWebsiteSSLDomains(websiteSSL *model.WebsiteSSL) []string {
|
||||
@@ -359,19 +388,19 @@ const (
|
||||
retryDelayOn503 = 30 * time.Second
|
||||
)
|
||||
|
||||
// isHTTP503Error checks if an error is an HTTP 503 Service Unavailable error
|
||||
// isHTTP503Error checks if an error is an HTTP 503 Service Unavailable error.
|
||||
func isHTTP503Error(err error) bool {
|
||||
if err == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
// Check for golang.org/x/crypto/acme.Error (used in manual_client.go)
|
||||
// Check for golang.org/x/crypto/acme.Error (used in manual_client.go).
|
||||
var acmeErr *acme.Error
|
||||
if errors.As(err, &acmeErr) {
|
||||
return acmeErr.StatusCode == http.StatusServiceUnavailable
|
||||
}
|
||||
|
||||
// Check error message for 503 (fallback for lego library errors)
|
||||
// Check error message for 503 (fallback for lego library errors).
|
||||
errMsg := err.Error()
|
||||
return strings.Contains(errMsg, "503") ||
|
||||
strings.Contains(errMsg, "Service busy")
|
||||
|
||||
@@ -1,24 +1,33 @@
|
||||
package ssl
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto"
|
||||
"crypto/rand"
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"net"
|
||||
"os"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/agent/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/agent/app/model"
|
||||
"github.com/1Panel-dev/1Panel/agent/global"
|
||||
"github.com/go-acme/lego/v4/certificate"
|
||||
"github.com/go-acme/lego/v4/challenge/dns01"
|
||||
"github.com/go-acme/lego/v4/lego"
|
||||
"github.com/go-acme/lego/v4/providers/http/webroot"
|
||||
"github.com/go-acme/lego/v5/certificate"
|
||||
"github.com/go-acme/lego/v5/challenge/dns01"
|
||||
"github.com/go-acme/lego/v5/lego"
|
||||
"github.com/go-acme/lego/v5/providers/http/webroot"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// dnsChallengeMu serializes DNS-01 issuance flows because lego v5 keeps the
|
||||
// recursive-nameserver Client and the LEGO_DISABLE_CNAME_SUPPORT switch in
|
||||
// process-wide globals. Without this lock, two concurrent SSL applications
|
||||
// with different nameserver/CNAME settings would clobber each other and
|
||||
// occasionally fail propagation checks against the wrong resolver.
|
||||
var dnsChallengeMu sync.Mutex
|
||||
|
||||
type AcmeClientOption func(*AcmeClientOptions)
|
||||
|
||||
type AcmeClientOptions struct {
|
||||
@@ -30,6 +39,11 @@ type AcmeClient struct {
|
||||
Client *lego.Client
|
||||
User *AcmeUser
|
||||
ProxyURL string
|
||||
|
||||
// dnsChallengeLocked records whether this client currently holds
|
||||
// dnsChallengeMu. It is set by UseDns and cleared by ObtainSSL/
|
||||
// ObtainIPSSL once the DNS-01 flow finishes. UseHTTP does not touch it.
|
||||
dnsChallengeLocked bool
|
||||
}
|
||||
|
||||
func NewAcmeClient(acmeAccount *model.WebsiteAcmeAccount, systemProxy *dto.SystemProxy) (*AcmeClient, error) {
|
||||
@@ -56,19 +70,47 @@ func (c *AcmeClient) UseDns(dnsType DnsType, params string, websiteSSL model.Web
|
||||
if websiteSSL.Nameserver2 != "" {
|
||||
nameservers = append(nameservers, websiteSSL.Nameserver2)
|
||||
}
|
||||
|
||||
// Hold the global DNS-01 lock for the entire flow that follows, including
|
||||
// the Obtain call. lego v5 reads dns01.DefaultClient() inside its own
|
||||
// propagation-precheck loop, so the lock cannot be released right after
|
||||
// SetDefaultClient/SetDNS01Provider; it has to span the whole DNS-01
|
||||
// challenge. ObtainSSL / ObtainIPSSL release it once the request returns.
|
||||
dnsChallengeMu.Lock()
|
||||
c.dnsChallengeLocked = true
|
||||
|
||||
if websiteSSL.DisableCNAME {
|
||||
_ = os.Setenv("LEGO_DISABLE_CNAME_SUPPORT", "true")
|
||||
} else {
|
||||
_ = os.Setenv("LEGO_DISABLE_CNAME_SUPPORT", "false")
|
||||
}
|
||||
|
||||
return c.Client.Challenge.SetDNS01Provider(p,
|
||||
dns01.CondOption(len(nameservers) > 0,
|
||||
dns01.AddRecursiveNameservers(nameservers)),
|
||||
dns01.CondOption(websiteSSL.SkipDNS,
|
||||
dns01.DisableAuthoritativeNssPropagationRequirement()),
|
||||
dns01.AddDNSTimeout(dnsTimeOut),
|
||||
)
|
||||
// lego v5 removed dns01.AddRecursiveNameservers and dns01.AddDNSTimeout;
|
||||
// configure them via dns01.NewClient(&dns01.Options{...}) + SetDefaultClient.
|
||||
dns01.SetDefaultClient(dns01.NewClient(&dns01.Options{
|
||||
RecursiveNameservers: nameservers,
|
||||
Timeout: dnsTimeOut,
|
||||
}))
|
||||
|
||||
var opts []dns01.ChallengeOption
|
||||
if websiteSSL.SkipDNS {
|
||||
opts = append(opts, dns01.DisableAuthoritativeNssPropagationRequirement())
|
||||
}
|
||||
|
||||
if err := c.Client.Challenge.SetDNS01Provider(p, opts...); err != nil {
|
||||
c.releaseDNSLock()
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// releaseDNSLock releases dnsChallengeMu if it was acquired by UseDns.
|
||||
// Safe to call multiple times; calls after the first one are no-ops.
|
||||
func (c *AcmeClient) releaseDNSLock() {
|
||||
if c.dnsChallengeLocked {
|
||||
c.dnsChallengeLocked = false
|
||||
dnsChallengeMu.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
func (c *AcmeClient) UseHTTP(path string) error {
|
||||
@@ -84,18 +126,25 @@ func (c *AcmeClient) UseHTTP(path string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *AcmeClient) ObtainSSL(domains []string, privateKey crypto.PrivateKey) (certificate.Resource, error) {
|
||||
func (c *AcmeClient) ObtainSSL(domains []string, privateKey crypto.Signer) (certificate.Resource, error) {
|
||||
defer c.releaseDNSLock()
|
||||
// lego v5 disables Common Name by default; explicitly enable it to keep
|
||||
// the v4 behaviour, so legacy Java/router clients that still rely on the
|
||||
// CommonName field do not fail TLS handshake.
|
||||
request := certificate.ObtainRequest{
|
||||
Domains: domains,
|
||||
Bundle: true,
|
||||
PrivateKey: privateKey,
|
||||
Domains: domains,
|
||||
Bundle: true,
|
||||
PrivateKey: privateKey,
|
||||
EnableCommonName: true,
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
var certificates *certificate.Resource
|
||||
var err error
|
||||
|
||||
for attempt := 1; attempt <= maxRetryAttempts; attempt++ {
|
||||
certificates, err = c.Client.Certificate.Obtain(request)
|
||||
certificates, err = c.Client.Certificate.Obtain(ctx, request)
|
||||
if err == nil {
|
||||
return *certificates, nil
|
||||
}
|
||||
@@ -114,7 +163,8 @@ func (c *AcmeClient) ObtainSSL(domains []string, privateKey crypto.PrivateKey) (
|
||||
return certificate.Resource{}, err
|
||||
}
|
||||
|
||||
func (c *AcmeClient) ObtainIPSSL(ipAddress string, privKey crypto.PrivateKey) (certificate.Resource, error) {
|
||||
func (c *AcmeClient) ObtainIPSSL(ipAddress string, privKey crypto.Signer) (certificate.Resource, error) {
|
||||
defer c.releaseDNSLock()
|
||||
csrTemplate := &x509.CertificateRequest{
|
||||
Subject: pkix.Name{
|
||||
CommonName: "",
|
||||
@@ -142,9 +192,11 @@ func (c *AcmeClient) ObtainIPSSL(ipAddress string, privKey crypto.PrivateKey) (c
|
||||
Bundle: true,
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
var certificates *certificate.Resource
|
||||
for attempt := 1; attempt <= maxRetryAttempts; attempt++ {
|
||||
certificates, err = c.Client.Certificate.ObtainForCSR(req)
|
||||
certificates, err = c.Client.Certificate.ObtainForCSR(ctx, req)
|
||||
if err == nil {
|
||||
return *certificates, nil
|
||||
}
|
||||
@@ -163,5 +215,5 @@ func (c *AcmeClient) ObtainIPSSL(ipAddress string, privKey crypto.PrivateKey) (c
|
||||
}
|
||||
|
||||
func (c *AcmeClient) RevokeSSL(pemSSL []byte) error {
|
||||
return c.Client.Certificate.Revoke(pemSSL)
|
||||
return c.Client.Certificate.Revoke(context.Background(), pemSSL)
|
||||
}
|
||||
|
||||
@@ -2,40 +2,41 @@ package ssl
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/go-acme/lego/v4/challenge"
|
||||
"github.com/go-acme/lego/v4/providers/dns/acmedns"
|
||||
"github.com/go-acme/lego/v4/providers/dns/alidns"
|
||||
"github.com/go-acme/lego/v4/providers/dns/aliesa"
|
||||
"github.com/go-acme/lego/v4/providers/dns/baiducloud"
|
||||
"github.com/go-acme/lego/v4/providers/dns/clouddns"
|
||||
"github.com/go-acme/lego/v4/providers/dns/cloudflare"
|
||||
"github.com/go-acme/lego/v4/providers/dns/cloudns"
|
||||
"github.com/go-acme/lego/v4/providers/dns/dnspod"
|
||||
"github.com/go-acme/lego/v4/providers/dns/dynu"
|
||||
"github.com/go-acme/lego/v4/providers/dns/freemyip"
|
||||
"github.com/go-acme/lego/v4/providers/dns/godaddy"
|
||||
"github.com/go-acme/lego/v4/providers/dns/huaweicloud"
|
||||
"github.com/go-acme/lego/v4/providers/dns/namecheap"
|
||||
"github.com/go-acme/lego/v4/providers/dns/namedotcom"
|
||||
"github.com/go-acme/lego/v4/providers/dns/namesilo"
|
||||
"github.com/go-acme/lego/v4/providers/dns/ovh"
|
||||
"github.com/go-acme/lego/v4/providers/dns/porkbun"
|
||||
"github.com/go-acme/lego/v4/providers/dns/rainyun"
|
||||
"github.com/go-acme/lego/v4/providers/dns/regru"
|
||||
"github.com/go-acme/lego/v4/providers/dns/route53"
|
||||
"github.com/go-acme/lego/v4/providers/dns/spaceship"
|
||||
"github.com/go-acme/lego/v4/providers/dns/technitium"
|
||||
"github.com/go-acme/lego/v4/providers/dns/tencentcloud"
|
||||
"github.com/go-acme/lego/v4/providers/dns/vercel"
|
||||
"github.com/go-acme/lego/v4/providers/dns/volcengine"
|
||||
"github.com/go-acme/lego/v4/providers/dns/westcn"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/go-acme/lego/v5/challenge"
|
||||
"github.com/go-acme/lego/v5/providers/dns/acmedns"
|
||||
"github.com/go-acme/lego/v5/providers/dns/alidns"
|
||||
"github.com/go-acme/lego/v5/providers/dns/aliesa"
|
||||
"github.com/go-acme/lego/v5/providers/dns/baiducloud"
|
||||
"github.com/go-acme/lego/v5/providers/dns/clouddns"
|
||||
"github.com/go-acme/lego/v5/providers/dns/cloudflare"
|
||||
"github.com/go-acme/lego/v5/providers/dns/cloudns"
|
||||
"github.com/go-acme/lego/v5/providers/dns/dynadot"
|
||||
"github.com/go-acme/lego/v5/providers/dns/dynu"
|
||||
"github.com/go-acme/lego/v5/providers/dns/freemyip"
|
||||
"github.com/go-acme/lego/v5/providers/dns/godaddy"
|
||||
"github.com/go-acme/lego/v5/providers/dns/huaweicloud"
|
||||
"github.com/go-acme/lego/v5/providers/dns/namecheap"
|
||||
"github.com/go-acme/lego/v5/providers/dns/namedotcom"
|
||||
"github.com/go-acme/lego/v5/providers/dns/namesilo"
|
||||
"github.com/go-acme/lego/v5/providers/dns/ovh"
|
||||
"github.com/go-acme/lego/v5/providers/dns/porkbun"
|
||||
"github.com/go-acme/lego/v5/providers/dns/rainyun"
|
||||
"github.com/go-acme/lego/v5/providers/dns/regru"
|
||||
"github.com/go-acme/lego/v5/providers/dns/route53"
|
||||
"github.com/go-acme/lego/v5/providers/dns/spaceship"
|
||||
"github.com/go-acme/lego/v5/providers/dns/technitium"
|
||||
"github.com/go-acme/lego/v5/providers/dns/tencentcloud"
|
||||
"github.com/go-acme/lego/v5/providers/dns/vercel"
|
||||
"github.com/go-acme/lego/v5/providers/dns/volcengine"
|
||||
"github.com/go-acme/lego/v5/providers/dns/westcn"
|
||||
)
|
||||
|
||||
type DnsType string
|
||||
|
||||
const (
|
||||
DnsPod DnsType = "DnsPod"
|
||||
AliYun DnsType = "AliYun"
|
||||
AliESA DnsType = "AliESA"
|
||||
AWSRoute53 DnsType = "AWSRoute53"
|
||||
@@ -56,11 +57,12 @@ const (
|
||||
ClouDNS DnsType = "ClouDNS"
|
||||
RegRu DnsType = "RegRu"
|
||||
Dynu DnsType = "Dynu"
|
||||
Dynadot DnsType = "Dynadot"
|
||||
BaiduCloud DnsType = "BaiduCloud"
|
||||
Ovh DnsType = "Ovh"
|
||||
AcmeDNS DnsType = "AcmeDNS"
|
||||
PorkBun DnsType = "PorkBun"
|
||||
Technitium DnsType = "Technitium"
|
||||
Technitium DnsType = "Technitium"
|
||||
)
|
||||
|
||||
type DNSParam struct {
|
||||
@@ -103,13 +105,6 @@ func getDNSProviderConfig(dnsType DnsType, params string) (challenge.Provider, e
|
||||
return nil, err
|
||||
}
|
||||
switch dnsType {
|
||||
case DnsPod:
|
||||
config := dnspod.NewDefaultConfig()
|
||||
config.LoginToken = param.ID + "," + param.Token
|
||||
config.PropagationTimeout = propagationTimeout
|
||||
config.PollingInterval = pollingInterval
|
||||
config.TTL = ttl
|
||||
p, err = dnspod.NewDNSProviderConfig(config)
|
||||
case AliYun:
|
||||
config := alidns.NewDefaultConfig()
|
||||
config.SecretKey = param.SecretKey
|
||||
@@ -274,6 +269,14 @@ func getDNSProviderConfig(dnsType DnsType, params string) (challenge.Provider, e
|
||||
config.PollingInterval = pollingInterval
|
||||
config.TTL = ttl
|
||||
p, err = dynu.NewDNSProviderConfig(config)
|
||||
case Dynadot:
|
||||
config := dynadot.NewDefaultConfig()
|
||||
config.APIKey = param.APIkey
|
||||
config.APISecret = param.APISecret
|
||||
config.PropagationTimeout = propagationTimeout
|
||||
config.PollingInterval = pollingInterval
|
||||
config.TTL = ttl
|
||||
p, err = dynadot.NewDNSProviderConfig(config)
|
||||
case BaiduCloud:
|
||||
config := baiducloud.NewDefaultConfig()
|
||||
config.AccessKeyID = param.AccessKey
|
||||
@@ -311,6 +314,16 @@ func getDNSProviderConfig(dnsType DnsType, params string) (challenge.Provider, e
|
||||
config.PollingInterval = pollingInterval
|
||||
config.TTL = ttl
|
||||
p, err = technitium.NewDNSProviderConfig(config)
|
||||
default:
|
||||
// Surfaces clear errors for legacy values (e.g. "DnsPod", which lego v5
|
||||
// removed) and for any future provider that the frontend can pick but
|
||||
// the backend has not yet wired up. Without this default branch, p and
|
||||
// err would both stay nil and the DNS-01 step would fail far away from
|
||||
// the real cause.
|
||||
if dnsType == "DnsPod" {
|
||||
return nil, fmt.Errorf("DNS provider %q has been removed in lego v5; please switch this DNS account to TencentCloud, which manages DNSPod-hosted zones via the same underlying API", dnsType)
|
||||
}
|
||||
return nil, fmt.Errorf("unsupported DNS provider %q", dnsType)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"github.com/1Panel-dev/1Panel/agent/app/model"
|
||||
"github.com/go-acme/lego/v4/certificate"
|
||||
"github.com/go-acme/lego/v5/certificate"
|
||||
"github.com/miekg/dns"
|
||||
"golang.org/x/crypto/acme"
|
||||
"log"
|
||||
@@ -31,30 +31,16 @@ type RequestCertRequest struct {
|
||||
}
|
||||
|
||||
func NewCustomAcmeClient(acmeAccount *model.WebsiteAcmeAccount, logger *log.Logger) (*ManualClient, error) {
|
||||
var (
|
||||
key crypto.PrivateKey
|
||||
err error
|
||||
)
|
||||
switch KeyType(acmeAccount.KeyType) {
|
||||
case KeyEC256, KeyEC384:
|
||||
block, _ := pem.Decode([]byte(acmeAccount.PrivateKey))
|
||||
key, err = x509.ParseECPrivateKey(block.Bytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case KeyRSA2048, KeyRSA3072, KeyRSA4096:
|
||||
block, _ := pem.Decode([]byte(acmeAccount.PrivateKey))
|
||||
key, err = x509.ParsePKCS1PrivateKey(block.Bytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
key, err := parsePrivateKeyPEM([]byte(acmeAccount.PrivateKey))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if logger == nil {
|
||||
logger = log.Default()
|
||||
}
|
||||
|
||||
client := &acme.Client{
|
||||
Key: key.(crypto.Signer),
|
||||
Key: key,
|
||||
DirectoryURL: getCaDirURL(acmeAccount.Type, acmeAccount.CaDirURL),
|
||||
}
|
||||
return &ManualClient{
|
||||
@@ -355,7 +341,7 @@ func (c *ManualClient) RequestCertificate(ctx context.Context, websiteSSL *model
|
||||
}
|
||||
c.logger.Printf("[INFO] acme: Server responded with a certificate.")
|
||||
resource := certificate.Resource{
|
||||
Domain: domains[0],
|
||||
Domains: domains,
|
||||
CertURL: certURL,
|
||||
CertStableURL: certURL,
|
||||
PrivateKey: []byte(privateKeyPEM),
|
||||
|
||||
@@ -43,5 +43,5 @@ type WebsiteCA struct {
|
||||
CSR string `gorm:"not null;" json:"csr"`
|
||||
Name string `gorm:"not null;" json:"name"`
|
||||
PrivateKey string `gorm:"not null" json:"privateKey"`
|
||||
KeyType string `gorm:"not null;default:2048" json:"keyType"`
|
||||
KeyType string `gorm:"not null;default:RSA2048" json:"keyType"`
|
||||
}
|
||||
|
||||
@@ -407,7 +407,7 @@ func (u *SettingService) UpdateSSL(c *gin.Context, req dto.SSLUpdate) error {
|
||||
params["domains"] = req.Domain
|
||||
params["time"] = 10
|
||||
params["unit"] = "year"
|
||||
params["keyType"] = "P256"
|
||||
params["keyType"] = "EC256"
|
||||
params["id"] = ca.ID
|
||||
jsonData, err := json.Marshal(params)
|
||||
if err != nil {
|
||||
|
||||
@@ -38646,12 +38646,12 @@ const docTemplate = `{
|
||||
},
|
||||
"keyType": {
|
||||
"enum": [
|
||||
"P256",
|
||||
"P384",
|
||||
"2048",
|
||||
"3072",
|
||||
"4096",
|
||||
"8192"
|
||||
"EC256",
|
||||
"EC384",
|
||||
"RSA2048",
|
||||
"RSA3072",
|
||||
"RSA4096",
|
||||
"RSA8192"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
@@ -38720,12 +38720,12 @@ const docTemplate = `{
|
||||
},
|
||||
"keyType": {
|
||||
"enum": [
|
||||
"P256",
|
||||
"P384",
|
||||
"2048",
|
||||
"3072",
|
||||
"4096",
|
||||
"8192"
|
||||
"EC256",
|
||||
"EC384",
|
||||
"RSA2048",
|
||||
"RSA3072",
|
||||
"RSA4096",
|
||||
"RSA8192"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
@@ -38773,12 +38773,12 @@ const docTemplate = `{
|
||||
},
|
||||
"keyType": {
|
||||
"enum": [
|
||||
"P256",
|
||||
"P384",
|
||||
"2048",
|
||||
"3072",
|
||||
"4096",
|
||||
"8192"
|
||||
"EC256",
|
||||
"EC384",
|
||||
"RSA2048",
|
||||
"RSA3072",
|
||||
"RSA4096",
|
||||
"RSA8192"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
|
||||
@@ -38642,12 +38642,12 @@
|
||||
},
|
||||
"keyType": {
|
||||
"enum": [
|
||||
"P256",
|
||||
"P384",
|
||||
"2048",
|
||||
"3072",
|
||||
"4096",
|
||||
"8192"
|
||||
"EC256",
|
||||
"EC384",
|
||||
"RSA2048",
|
||||
"RSA3072",
|
||||
"RSA4096",
|
||||
"RSA8192"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
@@ -38716,12 +38716,12 @@
|
||||
},
|
||||
"keyType": {
|
||||
"enum": [
|
||||
"P256",
|
||||
"P384",
|
||||
"2048",
|
||||
"3072",
|
||||
"4096",
|
||||
"8192"
|
||||
"EC256",
|
||||
"EC384",
|
||||
"RSA2048",
|
||||
"RSA3072",
|
||||
"RSA4096",
|
||||
"RSA8192"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
@@ -38769,12 +38769,12 @@
|
||||
},
|
||||
"keyType": {
|
||||
"enum": [
|
||||
"P256",
|
||||
"P384",
|
||||
"2048",
|
||||
"3072",
|
||||
"4096",
|
||||
"8192"
|
||||
"EC256",
|
||||
"EC384",
|
||||
"RSA2048",
|
||||
"RSA3072",
|
||||
"RSA4096",
|
||||
"RSA8192"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
|
||||
@@ -168,11 +168,11 @@ export const AcmeAccountTypes = [
|
||||
];
|
||||
|
||||
export const KeyTypes = [
|
||||
{ label: 'EC 256', value: 'P256' },
|
||||
{ label: 'EC 384', value: 'P384' },
|
||||
{ label: 'RSA 2048', value: '2048' },
|
||||
{ label: 'RSA 3072', value: '3072' },
|
||||
{ label: 'RSA 4096', value: '4096' },
|
||||
{ label: 'EC 256', value: 'EC256' },
|
||||
{ label: 'EC 384', value: 'EC384' },
|
||||
{ label: 'RSA 2048', value: 'RSA2048' },
|
||||
{ label: 'RSA 3072', value: 'RSA3072' },
|
||||
{ label: 'RSA 4096', value: 'RSA4096' },
|
||||
];
|
||||
|
||||
export const DNSTypes = [
|
||||
@@ -273,8 +273,13 @@ export const DNSTypes = [
|
||||
value: 'PorkBun',
|
||||
},
|
||||
{
|
||||
label: 'DNSPod (' + i18n.global.t('ssl.deprecated') + ')',
|
||||
label: 'DNSPod',
|
||||
value: 'DnsPod',
|
||||
deprecated: true,
|
||||
},
|
||||
{
|
||||
label: 'Dynadot',
|
||||
value: 'Dynadot',
|
||||
},
|
||||
{
|
||||
label: 'Technitium',
|
||||
|
||||
@@ -3629,6 +3629,11 @@ const message = {
|
||||
deprecated: 'will be deprecated',
|
||||
deprecatedHelper:
|
||||
'Maintenance has been stopped and may be abandoned in a future version. Please use Tencent Cloud method for analysis',
|
||||
dnsPodRemoved: 'removed',
|
||||
dnsPodRemovedTip:
|
||||
'DnsPod has been removed in lego v5; this account cannot be used for new certificates or renewals. Please switch to a TencentCloud DNS account.',
|
||||
dnsPodRemovedSSLTip:
|
||||
'This certificate is bound to a DnsPod DNS account, which is no longer usable in lego v5. Auto-renewal will fail. Please switch the DNS account to TencentCloud.',
|
||||
disableCNAME: 'Disable CNAME',
|
||||
disableCNAMEHelper: 'Check here if the domain name has a CNAME record and the request fails.',
|
||||
nameserver: 'DNS server',
|
||||
|
||||
@@ -3680,6 +3680,11 @@ const message = {
|
||||
cfHelper: 'No uses la clave API Global',
|
||||
deprecated: 'será obsoleto',
|
||||
deprecatedHelper: 'El soporte se ha detenido y puede eliminarse en el futuro. Usa el método Tencent Cloud.',
|
||||
dnsPodRemoved: 'eliminado',
|
||||
dnsPodRemovedTip:
|
||||
'DnsPod ha sido eliminado en lego v5; esta cuenta no puede usarse para emisión o renovación de certificados. Cambia a una cuenta DNS de TencentCloud.',
|
||||
dnsPodRemovedSSLTip:
|
||||
'La cuenta DnsPod asociada a este certificado ya no es válida en lego v5; la renovación automática fallará. Cambia la cuenta DNS a TencentCloud.',
|
||||
disableCNAME: 'Deshabilitar CNAME',
|
||||
disableCNAMEHelper: 'Marca si el dominio tiene un CNAME y falla la solicitud.',
|
||||
nameserver: 'Servidor DNS',
|
||||
|
||||
@@ -3667,6 +3667,11 @@ const message = {
|
||||
deprecated: '非推奨されます',
|
||||
deprecatedHelper:
|
||||
'メンテナンスは停止されており、将来のバージョンでは放棄される可能性があります。分析にはTencent Cloudメソッドを使用してください',
|
||||
dnsPodRemoved: '削除済み',
|
||||
dnsPodRemovedTip:
|
||||
'DnsPod は lego v5 で削除されました。このアカウントは証明書の申請/更新に使用できません。Tencent Cloud DNS アカウントに切り替えてください。',
|
||||
dnsPodRemovedSSLTip:
|
||||
'この証明書がバインドされている DnsPod アカウントは lego v5 では使用できません。自動更新は失敗します。DNS アカウントを Tencent Cloud に切り替えてください。',
|
||||
disableCNAME: 'cnameを無効にします',
|
||||
disableCNAMEHelper: 'ドメイン名にCNAMEレコードがあり、リクエストが失敗するかどうかを確認してください。',
|
||||
nameserver: 'DNSサーバー',
|
||||
|
||||
@@ -3583,6 +3583,11 @@ const message = {
|
||||
deprecated: '더 이상 지원되지 않습니다.',
|
||||
deprecatedHelper:
|
||||
'유지 관리가 중단되었으며 향후 버전에서 제외될 수 있습니다. Tencent Cloud 방법을 사용하여 분석하세요.',
|
||||
dnsPodRemoved: '제거됨',
|
||||
dnsPodRemovedTip:
|
||||
'DnsPod는 lego v5에서 제거되었습니다. 이 계정은 인증서 신청/갱신에 사용할 수 없습니다. Tencent Cloud DNS 계정으로 전환해 주세요.',
|
||||
dnsPodRemovedSSLTip:
|
||||
'이 인증서에 연결된 DnsPod 계정은 lego v5에서 사용할 수 없습니다. 자동 갱신이 실패합니다. DNS 계정을 Tencent Cloud로 전환해 주세요.',
|
||||
disableCNAME: 'CNAME 비활성화',
|
||||
disableCNAMEHelper: '도메인 이름에 CNAME 레코드가 있고 요청이 실패할 경우 선택하세요.',
|
||||
nameserver: 'DNS 서버',
|
||||
|
||||
@@ -3717,6 +3717,11 @@ const message = {
|
||||
deprecated: 'akan dihentikan',
|
||||
deprecatedHelper:
|
||||
'Penyelenggaraan telah dihentikan dan mungkin akan dibuang dalam versi masa hadapan. Sila gunakan kaedah Tencent Cloud untuk analisis',
|
||||
dnsPodRemoved: 'dialih keluar',
|
||||
dnsPodRemovedTip:
|
||||
'DnsPod telah dialih keluar dalam lego v5; akaun ini tidak boleh digunakan untuk permohonan/pembaharuan sijil. Sila tukar kepada akaun TencentCloud DNS.',
|
||||
dnsPodRemovedSSLTip:
|
||||
'Akaun DnsPod yang dikaitkan dengan sijil ini tidak lagi boleh digunakan dalam lego v5; pembaharuan automatik akan gagal. Sila tukar akaun DNS kepada TencentCloud.',
|
||||
disableCNAME: 'Lumpuhkan CNAME',
|
||||
disableCNAMEHelper: 'Semak di sini jika nama domain mempunyai rekod CNAME dan permintaan gagal.',
|
||||
nameserver: 'Pelayan DNS',
|
||||
|
||||
@@ -3853,6 +3853,11 @@ const message = {
|
||||
deprecated: 'será descontinuado',
|
||||
deprecatedHelper:
|
||||
'A manutenção foi interrompida e pode ser abandonada em uma versão futura. Use o método Tencent Cloud para análise',
|
||||
dnsPodRemoved: 'removido',
|
||||
dnsPodRemovedTip:
|
||||
'O DnsPod foi removido no lego v5; esta conta não pode ser usada para emissão/renovação de certificados. Por favor, mude para uma conta DNS do TencentCloud.',
|
||||
dnsPodRemovedSSLTip:
|
||||
'A conta DnsPod vinculada a este certificado não é mais válida no lego v5; a renovação automática falhará. Por favor, troque a conta DNS para TencentCloud.',
|
||||
disableCNAME: 'Desativar CNAME',
|
||||
disableCNAMEHelper: 'Marque esta opção se o domínio tiver um registro CNAME e a solicitação falhar.',
|
||||
nameserver: 'Servidor DNS',
|
||||
|
||||
@@ -3709,6 +3709,11 @@ const message = {
|
||||
deprecated: 'будет устарелым',
|
||||
deprecatedHelper:
|
||||
'Обслуживание остановлено и может быть удалено в будущей версии. Пожалуйста, используйте метод Tencent Cloud для анализа',
|
||||
dnsPodRemoved: 'удалён',
|
||||
dnsPodRemovedTip:
|
||||
'DnsPod удалён в lego v5; эта учётная запись не может использоваться для выпуска или продления сертификатов. Пожалуйста, переключитесь на учётную запись TencentCloud DNS.',
|
||||
dnsPodRemovedSSLTip:
|
||||
'Учётная запись DnsPod, привязанная к этому сертификату, недоступна в lego v5; автопродление будет завершаться с ошибкой. Пожалуйста, переключите DNS-аккаунт на TencentCloud.',
|
||||
disableCNAME: 'Отключить CNAME',
|
||||
disableCNAMEHelper: 'Отметьте здесь, если доменное имя имеет запись CNAME и запрос не удается.',
|
||||
nameserver: 'DNS сервер',
|
||||
|
||||
@@ -3710,6 +3710,11 @@ const message = {
|
||||
deprecated: 'kaldırılacak',
|
||||
deprecatedHelper:
|
||||
'Bakım durduruldu ve gelecek bir sürümde terk edilebilir. Lütfen analiz için Tencent Cloud yöntemini kullanın',
|
||||
dnsPodRemoved: 'kaldırıldı',
|
||||
dnsPodRemovedTip:
|
||||
'DnsPod, lego v5 sürümünde kaldırıldı; bu hesap sertifika başvurusu/yenilemesi için kullanılamaz. Lütfen TencentCloud DNS hesabına geçin.',
|
||||
dnsPodRemovedSSLTip:
|
||||
'Bu sertifikaya bağlı DnsPod hesabı lego v5 sürümünde kullanılamaz; otomatik yenileme başarısız olur. Lütfen DNS hesabını TencentCloud’a değiştirin.',
|
||||
disableCNAME: 'CNAME’yi devre dışı bırak',
|
||||
disableCNAMEHelper: 'Alan adında bir CNAME kaydı varsa ve istek başarısız olursa burayı işaretleyin.',
|
||||
nameserver: 'DNS sunucusu',
|
||||
|
||||
@@ -3381,6 +3381,11 @@ const message = {
|
||||
cfHelper: '請勿使用 Global API Key',
|
||||
deprecated: '即將廢棄',
|
||||
deprecatedHelper: '已經停止維護,可能會在以後的某個版本廢棄,請使用騰訊雲方式解析',
|
||||
dnsPodRemoved: '已移除',
|
||||
dnsPodRemovedTip:
|
||||
'DnsPod 已被 lego v5 移除,當前帳號無法用於證書申請/續簽,請改用騰訊雲 DNS 帳號',
|
||||
dnsPodRemovedSSLTip:
|
||||
'此證書綁定的 DnsPod 帳號在 lego v5 已不可用,自動續簽將失敗,請將 DNS 帳號切換到騰訊雲',
|
||||
disableCNAME: '停用 CNAME',
|
||||
disableCNAMEHelper: '有 CNAME 設定的域名,如果申請失敗,可以勾選此處',
|
||||
nameserver: 'DNS 伺服器',
|
||||
|
||||
@@ -3368,6 +3368,11 @@ const message = {
|
||||
cfHelper: '请勿使用 Global API Key',
|
||||
deprecated: '即将废弃',
|
||||
deprecatedHelper: '已经停止维护,可能会在以后的某个版本废弃,请使用腾讯云方式解析',
|
||||
dnsPodRemoved: '已移除',
|
||||
dnsPodRemovedTip:
|
||||
'DnsPod 已被 lego v5 移除,当前账号无法用于证书申请/续签,请改用腾讯云 DNS 账号',
|
||||
dnsPodRemovedSSLTip:
|
||||
'此证书绑定的 DnsPod 账号在 lego v5 已不可用,自动续签将失败,请将 DNS 账号切换到腾讯云',
|
||||
disableCNAME: '禁用 CNAME',
|
||||
disableCNAMEHelper: '有 CNAME 配置的域名,如果申请失败,可以勾选此处',
|
||||
nameserver: 'DNS 服务器',
|
||||
|
||||
@@ -111,7 +111,7 @@ const initData = () => ({
|
||||
type: 'letsencrypt',
|
||||
eabKid: '',
|
||||
eabHmacKey: '',
|
||||
keyType: 'P256',
|
||||
keyType: 'EC256',
|
||||
useProxy: false,
|
||||
caDirURL: '',
|
||||
useEAB: false,
|
||||
|
||||
@@ -72,7 +72,7 @@ const rules = ref({
|
||||
|
||||
const initData = () => ({
|
||||
name: '',
|
||||
keyType: 'P256',
|
||||
keyType: 'EC256',
|
||||
commonName: '',
|
||||
country: 'CN',
|
||||
organization: '',
|
||||
|
||||
@@ -103,7 +103,7 @@ const rules = ref({
|
||||
});
|
||||
|
||||
const initData = () => ({
|
||||
keyType: 'P256',
|
||||
keyType: 'EC256',
|
||||
domains: '',
|
||||
id: 0,
|
||||
time: 10,
|
||||
|
||||
@@ -242,7 +242,7 @@ const initData = () => ({
|
||||
acmeAccountId: undefined,
|
||||
dnsAccountId: undefined,
|
||||
autoRenew: true,
|
||||
keyType: 'P256',
|
||||
keyType: 'EC256',
|
||||
pushDir: false,
|
||||
dir: '',
|
||||
description: '',
|
||||
|
||||
@@ -11,12 +11,13 @@
|
||||
<el-option
|
||||
v-for="(type, index) in DNSTypes"
|
||||
:key="index"
|
||||
:label="type.label"
|
||||
:label="type.deprecated ? `${type.label} (${$t('ssl.dnsPodRemoved')})` : type.label"
|
||||
:value="type.value"
|
||||
:disabled="type.deprecated && accountData.mode === 'create'"
|
||||
></el-option>
|
||||
</el-select>
|
||||
<span class="input-help text-red-500" v-if="account.type === 'DnsPod'">
|
||||
{{ $t('ssl.deprecatedHelper') }}
|
||||
{{ $t('ssl.dnsPodRemovedTip') }}
|
||||
</span>
|
||||
</el-form-item>
|
||||
<div
|
||||
@@ -46,14 +47,6 @@
|
||||
<el-input v-model.trim="account.authorization['secretKey']"></el-input>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div v-if="account.type === 'DnsPod'">
|
||||
<el-form-item label="ID" prop="authorization.id">
|
||||
<el-input v-model.trim="account.authorization['id']"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="Token" prop="authorization.token">
|
||||
<el-input v-model.trim="account.authorization['token']"></el-input>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div v-if="account.type === 'Volcengine'">
|
||||
<el-form-item label="Access key" prop="authorization.accessKey">
|
||||
<el-input v-model.trim="account.authorization['accessKey']"></el-input>
|
||||
@@ -93,6 +86,7 @@
|
||||
account.type === 'Godaddy' ||
|
||||
account.type === 'RainYun' ||
|
||||
account.type === 'Spaceship' ||
|
||||
account.type === 'Dynadot' ||
|
||||
account.type === 'Dynu'
|
||||
"
|
||||
>
|
||||
@@ -104,7 +98,7 @@
|
||||
<el-form-item
|
||||
label="API Secret"
|
||||
prop="authorization.apiSecret"
|
||||
v-if="account.type === 'Godaddy' || account.type === 'Spaceship'"
|
||||
v-if="account.type === 'Godaddy' || account.type === 'Spaceship' || account.type === 'Dynadot'"
|
||||
>
|
||||
<el-input v-model.trim="account.authorization['apiSecret']"></el-input>
|
||||
</el-form-item>
|
||||
@@ -260,7 +254,7 @@ const resetForm = () => {
|
||||
account.value = {
|
||||
id: 0,
|
||||
name: '',
|
||||
type: 'DnsPod',
|
||||
type: 'AliYun',
|
||||
authorization: {},
|
||||
};
|
||||
accountForm.value?.resetFields();
|
||||
|
||||
@@ -16,6 +16,11 @@
|
||||
<el-table-column :label="$t('commons.table.type')" prop="type">
|
||||
<template #default="{ row }">
|
||||
<span>{{ getDNSName(row.type) }}</span>
|
||||
<el-tooltip v-if="row.type === 'DnsPod'" :content="$t('ssl.dnsPodRemovedTip')" placement="top">
|
||||
<el-tag type="danger" size="small" class="ml-2">
|
||||
{{ $t('ssl.dnsPodRemoved') }}
|
||||
</el-tag>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<fu-table-operations
|
||||
|
||||
@@ -52,7 +52,20 @@
|
||||
show-overflow-tooltip
|
||||
prop="primaryDomain"
|
||||
min-width="150px"
|
||||
></el-table-column>
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<span>{{ row.primaryDomain }}</span>
|
||||
<el-tooltip
|
||||
v-if="row.dnsAccount && row.dnsAccount.type === 'DnsPod'"
|
||||
:content="$t('ssl.dnsPodRemovedSSLTip')"
|
||||
placement="top"
|
||||
>
|
||||
<el-tag type="danger" size="small" class="ml-2">
|
||||
DnsPod {{ $t('ssl.dnsPodRemoved') }}
|
||||
</el-tag>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('website.otherDomains')"
|
||||
show-overflow-tooltip
|
||||
|
||||
Reference in New Issue
Block a user