From 6301fede62292a02d2b65253a0422b7c500be9d9 Mon Sep 17 00:00:00 2001 From: zhengkunwang <31820853+zhengkunwang223@users.noreply.github.com> Date: Tue, 14 Nov 2023 18:44:09 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E8=AF=81=E4=B9=A6=E5=A2=9E=E5=8A=A0=20?= =?UTF-8?q?ZeroSSL=20BuyPass=20=20Google=20=E7=94=B3=E8=AF=B7=20(#2951)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refs https://github.com/1Panel-dev/1Panel/issues/215 --- backend/app/dto/request/website_ssl.go | 5 +- backend/app/model/website_acme_account.go | 3 + backend/app/service/website_acme_account.go | 25 +- backend/app/service/website_ssl.go | 6 +- backend/constant/errs.go | 9 +- backend/i18n/lang/en.yaml | 1 + backend/i18n/lang/zh-Hant.yaml | 1 + backend/i18n/lang/zh.yaml | 1 + backend/init/migration/migrate.go | 2 + backend/init/migration/migrations/v_1_9.go | 17 ++ backend/utils/ssl/acme.go | 155 ++++++++---- backend/utils/ssl/acme_test.go | 224 ++++++++++++------ backend/utils/ssl/client.go | 41 ++-- frontend/src/api/modules/website.ts | 2 +- frontend/src/global/mimetype.ts | 7 + frontend/src/lang/modules/en.ts | 1 + frontend/src/lang/modules/tw.ts | 1 + frontend/src/lang/modules/zh.ts | 1 + .../website/ssl/acme-account/create/index.vue | 45 +++- .../views/website/ssl/acme-account/index.vue | 34 ++- frontend/src/views/website/ssl/index.vue | 2 +- go.mod | 15 +- go.sum | 36 +-- 23 files changed, 438 insertions(+), 196 deletions(-) create mode 100644 backend/init/migration/migrations/v_1_9.go diff --git a/backend/app/dto/request/website_ssl.go b/backend/app/dto/request/website_ssl.go index f148efe3b..42a6d7e41 100644 --- a/backend/app/dto/request/website_ssl.go +++ b/backend/app/dto/request/website_ssl.go @@ -26,7 +26,10 @@ type WebsiteSSLRenew struct { } type WebsiteAcmeAccountCreate struct { - Email string `json:"email" validate:"required"` + Email string `json:"email" validate:"required"` + Type string `json:"type" validate:"required,oneof=letsencrypt zerossl buypass google"` + EabKid string `json:"eabKid"` + EabHmacKey string `json:"eabHmacKey"` } type WebsiteDnsAccountCreate struct { diff --git a/backend/app/model/website_acme_account.go b/backend/app/model/website_acme_account.go index f03696a0b..d0e468f5d 100644 --- a/backend/app/model/website_acme_account.go +++ b/backend/app/model/website_acme_account.go @@ -5,6 +5,9 @@ type WebsiteAcmeAccount struct { Email string `gorm:"type:varchar(256);not null" json:"email"` URL string `gorm:"type:varchar(256);not null" json:"url"` PrivateKey string `gorm:"type:longtext;not null" json:"-"` + Type string `gorm:"type:varchar(64);not null;default:letsencrypt" json:"type"` + EabKid string `gorm:"type:varchar(256);" json:"eabKid"` + EabHmacKey string `gorm:"type:varchar(256);" json:"eabHmacKey"` } func (w WebsiteAcmeAccount) TableName() string { diff --git a/backend/app/service/website_acme_account.go b/backend/app/service/website_acme_account.go index 0b166c34d..8b1718b56 100644 --- a/backend/app/service/website_acme_account.go +++ b/backend/app/service/website_acme_account.go @@ -40,19 +40,28 @@ func (w WebsiteAcmeAccountService) Create(create request.WebsiteAcmeAccountCreat return response.WebsiteAcmeAccountDTO{}, buserr.New(constant.ErrEmailIsExist) } - client, err := ssl.NewAcmeClient(create.Email, "") + if create.Type == "google" && (create.EabKid == "" || create.EabHmacKey == "") { + return response.WebsiteAcmeAccountDTO{}, buserr.New(constant.ErrEabKidOrEabHmacKeyCannotBlank) + } else { + create.EabKid = "" + create.EabHmacKey = "" + } + + acmeAccount := &model.WebsiteAcmeAccount{ + Email: create.Email, + Type: create.Type, + } + client, err := ssl.NewAcmeClient(acmeAccount) if err != nil { return response.WebsiteAcmeAccountDTO{}, err } - acmeAccount := model.WebsiteAcmeAccount{ - Email: create.Email, - URL: client.User.Registration.URI, - PrivateKey: string(ssl.GetPrivateKey(client.User.GetPrivateKey())), - } - if err := websiteAcmeRepo.Create(acmeAccount); err != nil { + acmeAccount.PrivateKey = string(ssl.GetPrivateKey(client.User.GetPrivateKey())) + acmeAccount.URL = client.User.Registration.URI + + if err := websiteAcmeRepo.Create(*acmeAccount); err != nil { return response.WebsiteAcmeAccountDTO{}, err } - return response.WebsiteAcmeAccountDTO{WebsiteAcmeAccount: acmeAccount}, nil + return response.WebsiteAcmeAccountDTO{WebsiteAcmeAccount: *acmeAccount}, nil } func (w WebsiteAcmeAccountService) Delete(id uint) error { diff --git a/backend/app/service/website_ssl.go b/backend/app/service/website_ssl.go index a5a768990..c3239bc49 100644 --- a/backend/app/service/website_ssl.go +++ b/backend/app/service/website_ssl.go @@ -95,7 +95,7 @@ func (w WebsiteSSLService) Create(create request.WebsiteSSLCreate) (request.Webs if err != nil { return res, err } - client, err := ssl.NewPrivateKeyClient(acmeAccount.Email, acmeAccount.PrivateKey) + client, err := ssl.NewAcmeClient(acmeAccount) if err != nil { return res, err } @@ -174,7 +174,7 @@ func (w WebsiteSSLService) Renew(sslId uint) error { return err } - client, err := ssl.NewPrivateKeyClient(acmeAccount.Email, acmeAccount.PrivateKey) + client, err := ssl.NewAcmeClient(acmeAccount) if err != nil { return err } @@ -242,7 +242,7 @@ func (w WebsiteSSLService) GetDNSResolve(req request.WebsiteDNSReq) ([]response. return nil, err } - client, err := ssl.NewPrivateKeyClient(acmeAccount.Email, acmeAccount.PrivateKey) + client, err := ssl.NewAcmeClient(acmeAccount) if err != nil { return nil, err } diff --git a/backend/constant/errs.go b/backend/constant/errs.go index db5b97f37..2bd1313f0 100644 --- a/backend/constant/errs.go +++ b/backend/constant/errs.go @@ -78,10 +78,11 @@ var ( // ssl var ( - ErrSSLCannotDelete = "ErrSSLCannotDelete" - ErrAccountCannotDelete = "ErrAccountCannotDelete" - ErrSSLApply = "ErrSSLApply" - ErrEmailIsExist = "ErrEmailIsExist" + ErrSSLCannotDelete = "ErrSSLCannotDelete" + ErrAccountCannotDelete = "ErrAccountCannotDelete" + ErrSSLApply = "ErrSSLApply" + ErrEmailIsExist = "ErrEmailIsExist" + ErrEabKidOrEabHmacKeyCannotBlank = "ErrEabKidOrEabHmacKeyCannotBlank" ) // file diff --git a/backend/i18n/lang/en.yaml b/backend/i18n/lang/en.yaml index b919e5318..01f40b34e 100644 --- a/backend/i18n/lang/en.yaml +++ b/backend/i18n/lang/en.yaml @@ -91,6 +91,7 @@ ErrSSLKeyNotFound: 'The private key file does not exist' ErrSSLCertificateNotFound: 'The certificate file does not exist' ErrSSLKeyFormat: 'Private key file verification error' ErrSSLCertificateFormat: 'Certificate file format error, please use pem format' +ErrEabKidOrEabHmacKeyCannotBlank: 'EabKid or EabHmacKey cannot be empty' #mysql ErrUserIsExist: "The current user already exists. Please enter a new user" diff --git a/backend/i18n/lang/zh-Hant.yaml b/backend/i18n/lang/zh-Hant.yaml index efcf0981e..87de11519 100644 --- a/backend/i18n/lang/zh-Hant.yaml +++ b/backend/i18n/lang/zh-Hant.yaml @@ -91,6 +91,7 @@ ErrSSLKeyNotFound: '私鑰文件不存在' ErrSSLCertificateNotFound: '證書文件不存在' ErrSSLKeyFormat: '私鑰文件校驗錯誤' ErrSSLCertificateFormat: '證書文件格式錯誤,請使用 pem 格式' +ErrEabKidOrEabHmacKeyCannotBlank: 'EabKid 或 EabHmacKey 不能為空' #mysql ErrUserIsExist: "當前用戶已存在,請重新輸入" diff --git a/backend/i18n/lang/zh.yaml b/backend/i18n/lang/zh.yaml index 3eb223da9..3a3583dfc 100644 --- a/backend/i18n/lang/zh.yaml +++ b/backend/i18n/lang/zh.yaml @@ -91,6 +91,7 @@ ErrSSLKeyNotFound: '私钥文件不存在' ErrSSLCertificateNotFound: '证书文件不存在' ErrSSLKeyFormat: '私钥文件校验失败' ErrSSLCertificateFormat: '证书文件格式错误,请使用 pem 格式' +ErrEabKidOrEabHmacKeyCannotBlank: 'EabKid 或 EabHmacKey 不能为空' #mysql ErrUserIsExist: "当前用户已存在,请重新输入" diff --git a/backend/init/migration/migrate.go b/backend/init/migration/migrate.go index 1c45853ff..1f0d1f635 100644 --- a/backend/init/migration/migrate.go +++ b/backend/init/migration/migrate.go @@ -52,6 +52,8 @@ func Init() { migrations.AddBindAddress, migrations.AddCommandGroup, migrations.AddAppSyncStatus, + + migrations.UpdateAcmeAccount, }) if err := m.Migrate(); err != nil { global.LOG.Error(err) diff --git a/backend/init/migration/migrations/v_1_9.go b/backend/init/migration/migrations/v_1_9.go new file mode 100644 index 000000000..be29d53b3 --- /dev/null +++ b/backend/init/migration/migrations/v_1_9.go @@ -0,0 +1,17 @@ +package migrations + +import ( + "github.com/1Panel-dev/1Panel/backend/app/model" + "github.com/go-gormigrate/gormigrate/v2" + "gorm.io/gorm" +) + +var UpdateAcmeAccount = &gormigrate.Migration{ + ID: "20231115-update-acme-account", + Migrate: func(tx *gorm.DB) error { + if err := tx.AutoMigrate(&model.WebsiteAcmeAccount{}); err != nil { + return err + } + return nil + }, +} diff --git a/backend/utils/ssl/acme.go b/backend/utils/ssl/acme.go index 8e9763805..36470d669 100644 --- a/backend/utils/ssl/acme.go +++ b/backend/utils/ssl/acme.go @@ -5,10 +5,16 @@ import ( "crypto/rand" "crypto/rsa" "crypto/x509" + "encoding/json" "encoding/pem" + "fmt" + "github.com/1Panel-dev/1Panel/backend/app/model" "github.com/go-acme/lego/v4/certcrypto" "github.com/go-acme/lego/v4/lego" "github.com/go-acme/lego/v4/registration" + "io" + "net/http" + "net/url" ) type domainError struct { @@ -16,6 +22,12 @@ type domainError struct { Error error } +type zeroSSLRes struct { + Success bool `json:"success"` + EabKid string `json:"eab_kid"` + EabHmacKey string `json:"eab_hmac_key"` +} + func GetPrivateKey(priKey crypto.PrivateKey) []byte { rsaKey := priKey.(*rsa.PrivateKey) derStream := x509.MarshalPKCS1PrivateKey(rsaKey) @@ -26,24 +38,64 @@ func GetPrivateKey(priKey crypto.PrivateKey) []byte { return pem.EncodeToMemory(block) } -func NewRegisterClient(email string) (*AcmeClient, error) { - priKey, err := rsa.GenerateKey(rand.Reader, 2048) - if err != nil { - panic(err) +func NewRegisterClient(acmeAccount *model.WebsiteAcmeAccount) (*AcmeClient, error) { + var ( + priKey *rsa.PrivateKey + err error + ) + + if acmeAccount.PrivateKey != "" { + block, _ := pem.Decode([]byte(acmeAccount.PrivateKey)) + priKey, err = x509.ParsePKCS1PrivateKey(block.Bytes) + if err != nil { + return nil, err + } + } else { + priKey, err = rsa.GenerateKey(rand.Reader, 2048) + if err != nil { + return nil, err + } } myUser := &AcmeUser{ - Email: email, + Email: acmeAccount.Email, Key: priKey, } - config := newConfig(myUser) + config := newConfig(myUser, acmeAccount.Type) client, err := lego.NewClient(config) if err != nil { return nil, err } - reg, err := client.Registration.Register(registration.RegisterOptions{TermsOfServiceAgreed: true}) - if err != nil { - return nil, err + var reg *registration.Resource + if acmeAccount.Type == "zerossl" || acmeAccount.Type == "google" { + if acmeAccount.Type == "zerossl" { + var res *zeroSSLRes + res, err = getZeroSSLEabCredentials(acmeAccount.Email) + if err != nil { + return nil, err + } + if res.Success { + acmeAccount.EabKid = res.EabKid + acmeAccount.EabHmacKey = res.EabHmacKey + } else { + return nil, fmt.Errorf("get zero ssl eab credentials failed") + } + } + + eabOptions := registration.RegisterEABOptions{ + TermsOfServiceAgreed: true, + Kid: acmeAccount.EabKid, + HmacEncoded: acmeAccount.EabHmacKey, + } + reg, err = client.Registration.RegisterWithExternalAccountBinding(eabOptions) + if err != nil { + return nil, err + } + } else { + reg, err = client.Registration.Register(registration.RegisterOptions{TermsOfServiceAgreed: true}) + if err != nil { + return nil, err + } } myUser.Registration = reg @@ -56,41 +108,58 @@ func NewRegisterClient(email string) (*AcmeClient, error) { return acmeClient, nil } -func NewPrivateKeyClient(email string, privateKey string) (*AcmeClient, error) { - block, _ := pem.Decode([]byte(privateKey)) - priKey, err := x509.ParsePKCS1PrivateKey(block.Bytes) - if err != nil { - return nil, err - } - myUser := &AcmeUser{ - Email: email, - Key: priKey, - } - config := newConfig(myUser) - client, err := lego.NewClient(config) - if err != nil { - return nil, err - } - reg, err := client.Registration.ResolveAccountByKey() - if err != nil { - return nil, err - } - myUser.Registration = reg - - acmeClient := &AcmeClient{ - User: myUser, - Client: client, - Config: config, - } - - return acmeClient, nil -} - -func newConfig(user *AcmeUser) *lego.Config { +func newConfig(user *AcmeUser, accountType string) *lego.Config { config := lego.NewConfig(user) - config.CADirURL = "https://acme-v02.api.letsencrypt.org/directory" - //config.CADirURL = "https://acme-staging-v02.api.letsencrypt.org/directory" - config.UserAgent = "acm_go/0.0.1" + switch accountType { + case "letsEncrypt": + config.CADirURL = "https://acme-v02.api.letsencrypt.org/directory" + case "zeroSSL": + config.CADirURL = "https://acme.zerossl.com/v2/DV90" + case "buyPass": + config.CADirURL = "https://api.buypass.com/acme/directory" + case "google": + config.CADirURL = "https://dv.acme-v02.api.pki.goog/directory" + } + + config.UserAgent = "1Panel" config.Certificate.KeyType = certcrypto.RSA2048 return config } + +func getZeroSSLEabCredentials(email string) (*zeroSSLRes, error) { + baseURL := "https://api.zerossl.com/acme/eab-credentials-email" + params := url.Values{} + params.Add("email", email) + requestURL := fmt.Sprintf("%s?%s", baseURL, params.Encode()) + + req, err := http.NewRequest("POST", requestURL, nil) + if err != nil { + return nil, err + } + + req.Header.Set("Content-Type", "application/json") + + client := &http.Client{} + resp, err := client.Do(req) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + if resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("server returned non-200 status: %d %s", resp.StatusCode, http.StatusText(resp.StatusCode)) + } + + var result zeroSSLRes + err = json.Unmarshal(body, &result) + if err != nil { + return nil, err + } + + return &result, nil +} diff --git a/backend/utils/ssl/acme_test.go b/backend/utils/ssl/acme_test.go index 93caecd26..61be54fa9 100644 --- a/backend/utils/ssl/acme_test.go +++ b/backend/utils/ssl/acme_test.go @@ -2,12 +2,17 @@ package ssl import ( "bytes" + "crypto" + "crypto/ecdsa" + "crypto/elliptic" "crypto/rand" "crypto/rsa" "crypto/x509" + "crypto/x509/pkix" "encoding/json" "encoding/pem" "fmt" + "github.com/go-acme/lego/v4/providers/dns/cloudflare" "os" "path" "testing" @@ -23,6 +28,8 @@ import ( "github.com/go-acme/lego/v4/challenge/dns01" "github.com/go-acme/lego/v4/lego" "github.com/go-acme/lego/v4/registration" + + "log" ) type AppList struct { @@ -171,50 +178,11 @@ func TestCreatePrivate(t *testing.T) { func TestSSL(t *testing.T) { - //// 本地ACME测试用 - //httpClient := &http.Client{ - // Transport: &http.Transport{ - // TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, - // }} - - //priKey, err := rsa.GenerateKey(rand.Reader, 2048) - //if err != nil { - // panic(err) - //} - //derStream := x509.MarshalPKCS1PrivateKey(priKey) - //block := &pem.Block{ - // Type: "privateKey", - // Bytes: derStream, - //} - //file, err := os.Create("private.key") - //if err != nil { - // return - //} - //privateByte := pem.EncodeToMemory(block) - // - //fmt.Println(string(privateByte)) - // - //if err = pem.Encode(file, block); err != nil { - // return - //} - - key, err := os.ReadFile("private.key") + priKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) if err != nil { - panic(err) + log.Fatalf("Failed to generate private key: %v", err) } - block2, _ := pem.Decode(key) - priKey, err := x509.ParsePKCS1PrivateKey(block2.Bytes) - if err != nil { - panic(err) - } - - //block, _ := pem.Decode([]byte("vcCzoue3m0ufCzVx673quKBYQOho4uULpwj_P6tR60Q")) - //priKey, err := x509.ParsePKCS1PrivateKey(block.Bytes) - //if err != nil { - // panic(err) - //} - myUser := AcmeUser{ Email: "you2@yours.com", Key: priKey, @@ -223,6 +191,7 @@ func TestSSL(t *testing.T) { config := lego.NewConfig(&myUser) //config.CADirURL = "https://acme-v02.api.letsencrypt.org/directory" config.CADirURL = "https://acme-staging-v02.api.letsencrypt.org/directory" + config.CADirURL = "https://acme.zerossl.com/v2/DV90" config.UserAgent = "acm_go/0.0.1" config.Certificate.KeyType = certcrypto.RSA2048 @@ -238,11 +207,6 @@ func TestSSL(t *testing.T) { panic(err) } - //reg, err := client.Registration.ResolveAccountByKey() - //if err != nil { - // panic(err) - //} - myUser.Registration = reg //获取证书 @@ -256,35 +220,14 @@ func TestSSL(t *testing.T) { //} //申请证书 + ewDomain := "tuxpanel.com" request := certificate.ObtainRequest{ - Domains: []string{"1panel.cloud"}, + Domains: []string{ewDomain}, // 证书链 Bundle: true, } - //dns01.NewDNSProviderManual() - - //dnsPodConfig := dnspod.NewDefaultConfig() - //dnsPodConfig.LoginToken = "1,1" - //provider, err := dnspod.1(dnsPodConfig) - //if err != nil { - // panic(err) - //} - // - //alidnsConfig := alidns.NewDefaultConfig() - //alidnsConfig.SecretKey = "1" - //alidnsConfig.APIKey = "1" - //p, err := alidns.NewDNSProviderConfig(alidnsConfig) - //if err != nil { - // panic(err) - //} - - //p, err := dns01.NewDNSProviderManual() - //if err != nil { - // panic(err) - //} - err = client.Challenge.SetDNS01Provider(&manualDnsProvider{}, dns01.AddDNSTimeout(6*time.Minute)) if err != nil { panic(err) @@ -294,7 +237,7 @@ func TestSSL(t *testing.T) { if err != nil { panic(err) } - order, err := core.Orders.New([]string{"1panel.cloud"}) + order, err := core.Orders.New([]string{ewDomain}) if err != nil { panic(err) } @@ -303,7 +246,6 @@ func TestSSL(t *testing.T) { if err != nil { panic(err) } - //core.Challenges.New() domain := challenge.GetTargetedDomain(auth) chlng, err := challenge.FindChallenge(challenge.DNS01, auth) @@ -373,3 +315,143 @@ func TestSSL(t *testing.T) { fmt.Println(cert2) } + +func generateCSR(privateKey crypto.PrivateKey, domain string) ([]byte, error) { + // 创建证书请求的模板 + template := x509.CertificateRequest{ + Subject: pkix.Name{ + CommonName: domain, + }, + SignatureAlgorithm: x509.ECDSAWithSHA256, + } + + // 生成 CSR + csrBytes, err := x509.CreateCertificateRequest(rand.Reader, &template, privateKey) + if err != nil { + return nil, err + } + + // 将 CSR 编码为 PEM 格式 + csrPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE REQUEST", Bytes: csrBytes}) + + // 这里可以将 CSR 写入文件或者返回 + err = os.WriteFile("csr.pem", csrPEM, 0644) + if err != nil { + return nil, err + } + + return csrPEM, nil +} + +func TestZeroSSL(t *testing.T) { + + //switch accountType { + //case "letsencrypt": + // config.CADirURL = "https://acme-staging-v02.api.letsencrypt.org/directory" + //case "zerossl": + // config.CADirURL = "https://acme.zerossl.com/v2/DV90" + //case "buypass": + // config.CADirURL = "https://api.test4.buypass.no/acme/directory" + //} + + domain := "1panel.store" + acmeServer := "https://acme.zerossl.com/v2/DV90" + + //acmeServer = "https://api.test4.buypass.no/acme/directory" + // + //acmeServer = "https://api.buypass.com/acme/directory" + + priKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + if err != nil { + log.Fatalf("Failed to generate private key: %v", err) + } + + user := AcmeUser{ + Email: "zhengkunwang123@sina.com", + Key: priKey, + } + + config := lego.NewConfig(&user) + + // 设置ACME服务器URL + config.CADirURL = acmeServer + config.Certificate.KeyType = certcrypto.RSA2048 + config.UserAgent = "acm_go/0.0.1" + + // 创建ACME客户端 + client, err := lego.NewClient(config) + if err != nil { + log.Fatal(err) + } + + // ZeroSSl + + kid := "xv1T5Ybi4G2otJlbCTVHjg" + hmacEncoded := "pc-mEroSmg2quRpVr7e4L5YWzhm5mSDlk4_ivMUBzAkDjbym3Y6g7RLhR1joQH-JP94qy3PEczKVfw7QSLoh8A" + + eabOptions := registration.RegisterEABOptions{ + TermsOfServiceAgreed: true, + Kid: kid, + HmacEncoded: hmacEncoded, + } + + reg, err := client.Registration.RegisterWithExternalAccountBinding(eabOptions) + if err != nil { + log.Fatal(err) + } + + // ZeroSSl + + //reg, err := client.Registration.Register(registration.RegisterOptions{TermsOfServiceAgreed: true}) + //if err != nil { + // log.Fatal(err) + //} + + user.Registration = reg + + cloudflareConfig := cloudflare.NewDefaultConfig() + cloudflareConfig.AuthEmail = "zhengkunwang123@sina.com" + cloudflareConfig.AuthKey = "c29c0d604897ec1c5c7f14746623524bf040a" + p, err := cloudflare.NewDNSProviderConfig(cloudflareConfig) + if err != nil { + log.Fatal(err) + } + + if err := client.Challenge.SetDNS01Provider(p, dns01.AddDNSTimeout(3*time.Minute)); err != nil { + log.Fatal(err) + } + + // 申请证书 + pk, err := certcrypto.GeneratePrivateKey(certcrypto.EC256) + if err != nil { + return + } + + request := certificate.ObtainRequest{ + Domains: []string{domain}, + Bundle: true, + PrivateKey: pk, + } + certificates, err := client.Certificate.Obtain(request) + if err != nil { + log.Fatal(err) + } + + // 保存证书 + err = os.WriteFile("certificate.crt", certificates.Certificate, 0644) + if err != nil { + log.Fatal(err) + } + err = os.WriteFile("private.key", certificates.PrivateKey, 0644) + if err != nil { + log.Fatal(err) + } +} + +func TestGetEABCre(t *testing.T) { + res, err := getZeroSSLEabCredentials("zen@11.com") + if err != nil { + panic(err) + } + fmt.Printf("%v", res) +} diff --git a/backend/utils/ssl/client.go b/backend/utils/ssl/client.go index b1a465a6d..9f849a26a 100644 --- a/backend/utils/ssl/client.go +++ b/backend/utils/ssl/client.go @@ -3,6 +3,7 @@ package ssl import ( "crypto" "encoding/json" + "github.com/1Panel-dev/1Panel/backend/app/model" "github.com/go-acme/lego/v4/acme" "github.com/go-acme/lego/v4/acme/api" "github.com/go-acme/lego/v4/certificate" @@ -41,23 +42,15 @@ type AcmeClient struct { User *AcmeUser } -func NewAcmeClient(email, privateKey string) (*AcmeClient, error) { - if email == "" { +func NewAcmeClient(acmeAccount *model.WebsiteAcmeAccount) (*AcmeClient, error) { + if acmeAccount.Email == "" { return nil, errors.New("email can not blank") } - if privateKey == "" { - client, err := NewRegisterClient(email) - if err != nil { - return nil, err - } - return client, nil - } else { - client, err := NewPrivateKeyClient(email, privateKey) - if err != nil { - return nil, err - } - return client, nil + client, err := NewRegisterClient(acmeAccount) + if err != nil { + return nil, err } + return client, nil } type DnsType string @@ -78,22 +71,25 @@ type DNSParam struct { } func (c *AcmeClient) UseDns(dnsType DnsType, params string) error { - var param DNSParam - if err := json.Unmarshal([]byte(params), ¶m); err != nil { + var ( + param DNSParam + p challenge.Provider + err error + ) + + if err = json.Unmarshal([]byte(params), ¶m); err != nil { return err } - var p challenge.Provider - var err error - if dnsType == DnsPod { + switch dnsType { + case DnsPod: dnsPodConfig := dnspod.NewDefaultConfig() dnsPodConfig.LoginToken = param.ID + "," + param.Token p, err = dnspod.NewDNSProviderConfig(dnsPodConfig) if err != nil { return err } - } - if dnsType == AliYun { + case AliYun: alidnsConfig := alidns.NewDefaultConfig() alidnsConfig.SecretKey = param.SecretKey alidnsConfig.APIKey = param.AccessKey @@ -101,8 +97,7 @@ func (c *AcmeClient) UseDns(dnsType DnsType, params string) error { if err != nil { return err } - } - if dnsType == CloudFlare { + case CloudFlare: cloudflareConfig := cloudflare.NewDefaultConfig() cloudflareConfig.AuthEmail = param.Email cloudflareConfig.AuthKey = param.APIkey diff --git a/frontend/src/api/modules/website.ts b/frontend/src/api/modules/website.ts index cf535ec54..b49649dbc 100644 --- a/frontend/src/api/modules/website.ts +++ b/frontend/src/api/modules/website.ts @@ -85,7 +85,7 @@ export const SearchAcmeAccount = (req: ReqPage) => { }; export const CreateAcmeAccount = (req: Website.AcmeAccountCreate) => { - return http.post(`/websites/acme`, req); + return http.post(`/websites/acme`, req, TimeoutEnum.T_10M); }; export const DeleteAcmeAccount = (req: Website.DelReq) => { diff --git a/frontend/src/global/mimetype.ts b/frontend/src/global/mimetype.ts index d82a5c528..e065cab3b 100644 --- a/frontend/src/global/mimetype.ts +++ b/frontend/src/global/mimetype.ts @@ -122,3 +122,10 @@ export const Units = [ { label: i18n.global.t('commons.units.month'), value: 'M' }, { label: i18n.global.t('commons.units.year'), value: 'y' }, ]; + +export const AcmeAccountTypes = [ + { label: "Let's Encrypt", value: 'letsencrypt' }, + { label: 'ZeroSSL', value: 'zerossl' }, + { label: 'Buypass', value: 'buypass' }, + { label: 'Google Cloud', value: 'google' }, +]; diff --git a/frontend/src/lang/modules/en.ts b/frontend/src/lang/modules/en.ts index c5762bd54..70e7aadcf 100644 --- a/frontend/src/lang/modules/en.ts +++ b/frontend/src/lang/modules/en.ts @@ -1664,6 +1664,7 @@ const message = { openrestryHelper: 'OpenResty default HTTP port: {0} HTTPS port: {1}, which may affect website domain name access and HTTPS forced redirect', primaryDomainHelper: 'Support domain name: port', + acmeAccountType: 'Account Type', }, php: { short_open_tag: 'Short tag support', diff --git a/frontend/src/lang/modules/tw.ts b/frontend/src/lang/modules/tw.ts index 8a79c1eb4..c0137b517 100644 --- a/frontend/src/lang/modules/tw.ts +++ b/frontend/src/lang/modules/tw.ts @@ -1577,6 +1577,7 @@ const message = { runDirHelper2: '請確保二級運行目錄位於 index 目錄下', openrestryHelper: 'OpenResty 默認 HTTP 端口:{0} HTTPS 端口:{1},可能影響網站域名訪問和 HTTPS 強制跳轉', primaryDomainHelper: '支援網域:port', + acmeAccountType: '賬號類型', }, php: { short_open_tag: '短標簽支持', diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts index 77ae4485c..4263273bd 100644 --- a/frontend/src/lang/modules/zh.ts +++ b/frontend/src/lang/modules/zh.ts @@ -1577,6 +1577,7 @@ const message = { runDirHelper2: '请确保二级运行目录位于 index 目录下', openrestryHelper: 'OpenResty 默认 HTTP 端口:{0} HTTPS 端口 :{1},可能影响网站域名访问和 HTTPS 强制跳转', primaryDomainHelper: '支持域名:端口', + acmeAccountType: '账号类型', }, php: { short_open_tag: '短标签支持', diff --git a/frontend/src/views/website/ssl/acme-account/create/index.vue b/frontend/src/views/website/ssl/acme-account/create/index.vue index e8522e496..5897ac17f 100644 --- a/frontend/src/views/website/ssl/acme-account/create/index.vue +++ b/frontend/src/views/website/ssl/acme-account/create/index.vue @@ -12,6 +12,24 @@ + + + + + +
+ + + + + + +
@@ -32,17 +50,26 @@ import { Rules } from '@/global/form-rules'; import { CreateAcmeAccount } from '@/api/modules/website'; import i18n from '@/lang'; import { MsgSuccess } from '@/utils/message'; +import { AcmeAccountTypes } from '@/global/mimetype'; -let open = ref(); -let loading = ref(false); -let accountForm = ref(); -let rules = ref({ +const open = ref(); +const loading = ref(false); +const accountForm = ref(); +const rules = ref({ email: [Rules.requiredInput, Rules.email], -}); -let account = ref({ - email: '', + type: [Rules.requiredSelect], + eabKid: [Rules.requiredInput], + eabHmacKey: [Rules.requiredInput], }); +const initData = () => ({ + email: '', + type: 'letsencrypt', + eabKid: '', + eabHmacKey: '', +}); + +const account = ref(initData()); const em = defineEmits(['close']); const handleClose = () => { @@ -53,9 +80,7 @@ const handleClose = () => { const resetForm = () => { accountForm.value.resetFields(); - account.value = { - email: '', - }; + account.value = initData(); }; const acceptParams = () => { diff --git a/frontend/src/views/website/ssl/acme-account/index.vue b/frontend/src/views/website/ssl/acme-account/index.vue index 20f6f2b3c..33a0c89d2 100644 --- a/frontend/src/views/website/ssl/acme-account/index.vue +++ b/frontend/src/views/website/ssl/acme-account/index.vue @@ -3,12 +3,25 @@ - +
+ +
- + + + + { }); }; +const getAccountType = (type: string) => { + for (const i of AcmeAccountTypes) { + if (i.value === type) { + return i.label; + } + } +}; + defineExpose({ acceptParams, }); diff --git a/frontend/src/views/website/ssl/index.vue b/frontend/src/views/website/ssl/index.vue index 60705ceaa..7f2e3e3d9 100644 --- a/frontend/src/views/website/ssl/index.vue +++ b/frontend/src/views/website/ssl/index.vue @@ -104,8 +104,8 @@ import { Website } from '@/api/interface/website'; import { MsgSuccess } from '@/utils/message'; import { GlobalStore } from '@/store'; import SSLUpload from './upload/index.vue'; -const globalStore = GlobalStore(); +const globalStore = GlobalStore(); const paginationConfig = reactive({ cacheSizeKey: 'ssl-page-size', currentPage: 1, diff --git a/go.mod b/go.mod index 7064ca966..29af37f51 100644 --- a/go.mod +++ b/go.mod @@ -16,12 +16,12 @@ require ( github.com/gin-contrib/i18n v0.0.1 github.com/gin-gonic/gin v1.9.1 github.com/glebarez/sqlite v1.8.0 - github.com/go-acme/lego/v4 v4.9.0 + github.com/go-acme/lego/v4 v4.14.2 github.com/go-gormigrate/gormigrate/v2 v2.0.2 github.com/go-playground/validator/v10 v10.14.0 github.com/go-sql-driver/mysql v1.7.0 github.com/goh-chunlin/go-onedrive v1.1.1 - github.com/golang-jwt/jwt/v4 v4.4.2 + github.com/golang-jwt/jwt/v4 v4.5.0 github.com/google/uuid v1.3.1 github.com/gorilla/websocket v1.5.0 github.com/jinzhu/copier v0.3.5 @@ -73,11 +73,11 @@ require ( github.com/bodgit/sevenzip v1.3.0 // indirect github.com/bodgit/windows v1.0.0 // indirect github.com/bytedance/sonic v1.9.1 // indirect - github.com/cenkalti/backoff/v4 v4.2.0 // indirect + github.com/cenkalti/backoff/v4 v4.2.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect github.com/clbanning/mxj v1.8.5-0.20200714211355-ff02cfb8ea28 // indirect - github.com/cloudflare/cloudflare-go v0.49.0 // indirect + github.com/cloudflare/cloudflare-go v0.70.0 // indirect github.com/connesc/cipherio v0.2.1 // indirect github.com/containerd/console v1.0.3 // indirect github.com/containerd/containerd v1.7.7 // indirect @@ -101,6 +101,7 @@ require ( github.com/gabriel-vasile/mimetype v1.4.2 // indirect github.com/gin-contrib/sse v0.1.0 // indirect github.com/glebarez/go-sqlite v1.21.1 // indirect + github.com/go-jose/go-jose/v3 v3.0.0 // indirect github.com/go-logr/logr v1.2.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.2.6 // indirect @@ -131,7 +132,7 @@ require ( github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/hashicorp/go-retryablehttp v0.7.2 // indirect + github.com/hashicorp/go-retryablehttp v0.7.4 // indirect github.com/hashicorp/go-version v1.6.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/imdario/mergo v0.3.16 // indirect @@ -152,7 +153,7 @@ require ( github.com/mattn/go-isatty v0.0.19 // indirect github.com/mattn/go-shellwords v1.0.12 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect - github.com/miekg/dns v1.1.50 // indirect + github.com/miekg/dns v1.1.55 // indirect github.com/miekg/pkcs11 v1.1.1 // indirect github.com/minio/md5-simd v1.1.2 // indirect github.com/minio/sha256-simd v1.0.0 // indirect @@ -221,7 +222,7 @@ require ( golang.org/x/sync v0.4.0 // indirect golang.org/x/term v0.13.0 // indirect golang.org/x/time v0.3.0 // indirect - golang.org/x/tools v0.7.0 // indirect + golang.org/x/tools v0.10.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d // indirect google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d // indirect diff --git a/go.sum b/go.sum index f64049fdf..58955b3e5 100644 --- a/go.sum +++ b/go.sum @@ -52,7 +52,7 @@ github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935 github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/toml v1.2.0 h1:Rt8g24XnyGTyglgET/PRUNlrUeu9F5L+7FilkXfZgs0= +github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc= github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= @@ -102,8 +102,8 @@ github.com/bugsnag/panicwrap v1.2.0 h1:OzrKrRvXis8qEvOkfcxNcYbOd2O7xXS2nnKMEMABF github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s= github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= -github.com/cenkalti/backoff/v4 v4.2.0 h1:HN5dHm3WBOgndBH6E8V0q2jIYIR3s9yglV8k/+MN3u4= -github.com/cenkalti/backoff/v4 v4.2.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= +github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= @@ -120,8 +120,8 @@ github.com/clbanning/mxj v1.8.5-0.20200714211355-ff02cfb8ea28/go.mod h1:BVjHeAH+ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004/go.mod h1:yMWuSON2oQp+43nFtAV/uvKQIFpSPerB57DCt9t8sSA= github.com/cloudflare/cfssl v0.0.0-20181213083726-b94e044bb51e h1:Qux+lbuMaRzkQyTdzgtz8MgzPtzmaPQy6DXmxpdxT3U= -github.com/cloudflare/cloudflare-go v0.49.0 h1:KqJYk/YQ5ZhmyYz1oa4kGDskfF1gVuZfqesaJ/XDLto= -github.com/cloudflare/cloudflare-go v0.49.0/go.mod h1:h0QgcIZ3qEXwFiwfBO8sQxjVdYsLX+PfD7NFEnANaKg= +github.com/cloudflare/cloudflare-go v0.70.0 h1:4opGbUygM8DjirUuaz23jn3akuAcnOCEx+0nQtQEcFo= +github.com/cloudflare/cloudflare-go v0.70.0/go.mod h1:VW6GuazkaZ4xEDkFt24lkXQUsE8q7BiGqDniC2s8WEM= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -238,13 +238,15 @@ github.com/glebarez/go-sqlite v1.21.1 h1:7MZyUPh2XTrHS7xNEHQbrhfMZuPSzhkm2A1qgg0 github.com/glebarez/go-sqlite v1.21.1/go.mod h1:ISs8MF6yk5cL4n/43rSOmVMGJJjHYr7L2MbZZ5Q4E2E= github.com/glebarez/sqlite v1.8.0 h1:02X12E2I/4C1n+v90yTqrjRa8yuo7c3KeHI3FRznCvc= github.com/glebarez/sqlite v1.8.0/go.mod h1:bpET16h1za2KOOMb8+jCp6UBP/iahDpfPQqSaYLTLx8= -github.com/go-acme/lego/v4 v4.9.0 h1:8Hjj44IqRS7cigshMyFQ+0pIZvwgkG/+9A0UnNh7G8A= -github.com/go-acme/lego/v4 v4.9.0/go.mod h1:g3JRUyWS3L/VObpp4bCxzJftKyf/Wba8QrSSnoiqjg4= +github.com/go-acme/lego/v4 v4.14.2 h1:/D/jqRgLi8Cbk33sLGtu2pX2jEg3bGJWHyV8kFuUHGM= +github.com/go-acme/lego/v4 v4.14.2/go.mod h1:kBXxbeTg0x9AgaOYjPSwIeJy3Y33zTz+tMD16O4MO6c= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gormigrate/gormigrate/v2 v2.0.2 h1:YV4Lc5yMQX8ahVW0ENPq6sPhrhdkGukc6fPRYmZ1R6Y= github.com/go-gormigrate/gormigrate/v2 v2.0.2/go.mod h1:vld36QpBTfTzLealsHsmQQJK5lSwJt6wiORv+oFX8/I= +github.com/go-jose/go-jose/v3 v3.0.0 h1:s6rrhirfEP/CGIoc6p+PZAeogN2SxKav6Wp7+dyMWVo= +github.com/go-jose/go-jose/v3 v3.0.0/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= @@ -305,8 +307,8 @@ github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69 github.com/goh-chunlin/go-onedrive v1.1.1 h1:HGtHk5iG0MZ92zYUtaY04czfZPBIJUr12UuFc+PW8m4= github.com/goh-chunlin/go-onedrive v1.1.1/go.mod h1:N8qIGHD7tryO734epiBKk5oXcpGwxKET/u3LuBHciTs= github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A= -github.com/golang-jwt/jwt/v4 v4.4.2 h1:rcc4lwaZgFMCZ5jxF9ABolDcIHdBytAFgqFPbSJQAYs= -github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= +github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY= github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang-sql/sqlexp v0.0.0-20170517235910-f1bb20e5a188 h1:+eHOFJl1BaXrQxKX+T06f78590z4qA2ZzBTqahsKSE4= @@ -428,8 +430,8 @@ github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrj github.com/hashicorp/go-hclog v1.2.0 h1:La19f8d7WIlm4ogzNHB0JGqs5AUDAZ2UfCY4sJXcJdM= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-retryablehttp v0.7.2 h1:AcYqCvkpalPnPF2pn0KamgwamS42TqUDDYFRKq/RAd0= -github.com/hashicorp/go-retryablehttp v0.7.2/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8= +github.com/hashicorp/go-retryablehttp v0.7.4 h1:ZQgVdpTdAL7WpMIwLzCfbalOcSUdkDZnpUv3/+BxzFA= +github.com/hashicorp/go-retryablehttp v0.7.4/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8= github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= @@ -542,8 +544,8 @@ github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zk github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/mholt/archiver/v4 v4.0.0-alpha.8 h1:tRGQuDVPh66WCOelqe6LIGh0gwmfwxUrSSDunscGsRM= github.com/mholt/archiver/v4 v4.0.0-alpha.8/go.mod h1:5f7FUYGXdJWUjESffJaYR4R60VhnHxb2X3T1teMyv5A= -github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA= -github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= +github.com/miekg/dns v1.1.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo= +github.com/miekg/dns v1.1.55/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= github.com/miekg/pkcs11 v1.0.2/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= github.com/miekg/pkcs11 v1.1.1 h1:Ugu9pdy6vAYku5DEpVWVFPYnzV+bxB+iRdbuFSu7TvU= github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= @@ -797,7 +799,6 @@ github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= @@ -840,6 +841,7 @@ golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -969,7 +971,6 @@ golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1060,12 +1061,11 @@ golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= -golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= +golang.org/x/tools v0.10.0 h1:tvDr/iQoUqNdohiYm0LmmKcBk+q86lb9EprIUFhHHGg= +golang.org/x/tools v0.10.0/go.mod h1:UJwyiVBsOA2uwvK/e5OY3GTpDUJriEd+/YlqAwLPmyM= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=