From b489f5cf2f305b2f61234bb7adf59a810723016a Mon Sep 17 00:00:00 2001 From: zhengkunwang <31820853+zhengkunwang223@users.noreply.github.com> Date: Tue, 7 May 2024 18:26:34 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E8=AF=81=E4=B9=A6=E7=94=B3=E8=AF=B7?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E9=85=8D=E7=BD=AE=EF=BC=8C=E6=8F=90=E9=AB=98?= =?UTF-8?q?=E7=94=B3=E8=AF=B7=E6=88=90=E5=8A=9F=E7=8E=87=20(#4903)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/app/dto/request/website_ssl.go | 8 ++++ backend/app/model/website_ssl.go | 4 ++ backend/app/service/website_ssl.go | 16 +++++++- backend/init/migration/migrate.go | 2 + backend/init/migration/migrations/v_1_10.go | 10 +++++ backend/utils/common/common.go | 4 ++ backend/utils/ssl/client.go | 17 ++++++++- frontend/src/api/interface/website.ts | 5 ++- frontend/src/global/form-rules.ts | 19 ++++++++++ frontend/src/lang/modules/en.ts | 4 ++ frontend/src/lang/modules/tw.ts | 4 ++ frontend/src/lang/modules/zh.ts | 4 ++ .../src/views/website/ssl/apply/index.vue | 9 +---- .../src/views/website/ssl/create/index.vue | 38 +++++++++++++++++++ .../website/ssl/dns-account/create/index.vue | 1 - .../src/views/website/ssl/obtain/index.vue | 8 +--- 16 files changed, 133 insertions(+), 20 deletions(-) diff --git a/backend/app/dto/request/website_ssl.go b/backend/app/dto/request/website_ssl.go index b161d323d..726512c13 100644 --- a/backend/app/dto/request/website_ssl.go +++ b/backend/app/dto/request/website_ssl.go @@ -20,6 +20,10 @@ type WebsiteSSLCreate struct { Dir string `json:"dir"` ID uint `json:"id"` Description string `json:"description"` + DisableCNAME bool `json:"disableCNAME"` + SkipDNS bool `json:"skipDNS"` + Nameserver1 string `json:"nameserver1"` + Nameserver2 string `json:"nameserver2"` } type WebsiteDNSReq struct { @@ -79,6 +83,10 @@ type WebsiteSSLUpdate struct { Apply bool `json:"apply"` PushDir bool `json:"pushDir"` Dir string `json:"dir"` + DisableCNAME bool `json:"disableCNAME"` + SkipDNS bool `json:"skipDNS"` + Nameserver1 string `json:"nameserver1"` + Nameserver2 string `json:"nameserver2"` } type WebsiteSSLUpload struct { diff --git a/backend/app/model/website_ssl.go b/backend/app/model/website_ssl.go index b971f8603..a7ad31c0a 100644 --- a/backend/app/model/website_ssl.go +++ b/backend/app/model/website_ssl.go @@ -29,6 +29,10 @@ type WebsiteSSL struct { PushDir bool `json:"pushDir"` Dir string `json:"dir"` Description string `json:"description"` + SkipDNS bool `json:"skipDNS"` + Nameserver1 string `json:"nameserver1"` + Nameserver2 string `json:"nameserver2"` + DisableCNAME bool `json:"disableCNAME"` AcmeAccount WebsiteAcmeAccount `json:"acmeAccount" gorm:"-:migration"` DnsAccount WebsiteDnsAccount `json:"dnsAccount" gorm:"-:migration"` diff --git a/backend/app/service/website_ssl.go b/backend/app/service/website_ssl.go index 164c36058..39c162a89 100644 --- a/backend/app/service/website_ssl.go +++ b/backend/app/service/website_ssl.go @@ -102,6 +102,12 @@ func (w WebsiteSSLService) Search(search request.WebsiteSSLSearch) ([]response.W } func (w WebsiteSSLService) Create(create request.WebsiteSSLCreate) (request.WebsiteSSLCreate, error) { + if create.Nameserver1 != "" && !common.IsValidIP(create.Nameserver1) { + return create, buserr.New("ErrParseIP") + } + if create.Nameserver2 != "" && !common.IsValidIP(create.Nameserver2) { + return create, buserr.New("ErrParseIP") + } var res request.WebsiteSSLCreate acmeAccount, err := websiteAcmeRepo.GetFirst(commonRepo.WithByID(create.AcmeAccountID)) if err != nil { @@ -116,6 +122,10 @@ func (w WebsiteSSLService) Create(create request.WebsiteSSLCreate) (request.Webs KeyType: create.KeyType, PushDir: create.PushDir, Description: create.Description, + Nameserver1: create.Nameserver1, + Nameserver2: create.Nameserver2, + SkipDNS: create.SkipDNS, + DisableCNAME: create.DisableCNAME, } if create.PushDir { if !files.NewFileOp().Stat(create.Dir) { @@ -191,7 +201,7 @@ func (w WebsiteSSLService) ObtainSSL(apply request.WebsiteSSLApply) error { if err != nil { return err } - if err = client.UseDns(ssl.DnsType(dnsAccount.Type), dnsAccount.Authorization, apply.SkipDNSCheck, apply.Nameservers); err != nil { + if err = client.UseDns(ssl.DnsType(dnsAccount.Type), dnsAccount.Authorization, *websiteSSL); err != nil { return err } case constant.Http: @@ -374,6 +384,10 @@ func (w WebsiteSSLService) Update(update request.WebsiteSSLUpdate) error { updateParams["provider"] = update.Provider updateParams["key_type"] = update.KeyType updateParams["push_dir"] = update.PushDir + updateParams["disable_cname"] = update.DisableCNAME + updateParams["skip_dns"] = update.SkipDNS + updateParams["nameserver1"] = update.Nameserver1 + updateParams["nameserver2"] = update.Nameserver2 acmeAccount, err := websiteAcmeRepo.GetFirst(commonRepo.WithByID(update.AcmeAccountID)) if err != nil { diff --git a/backend/init/migration/migrate.go b/backend/init/migration/migrate.go index cb29f6289..45468d033 100644 --- a/backend/init/migration/migrate.go +++ b/backend/init/migration/migrate.go @@ -82,6 +82,8 @@ func Init() { migrations.UpdateXpackHideMenu, migrations.AddMenuTabsSetting, migrations.AddDeveloperSetting, + + migrations.AddWebsiteSSLColumn, }) if err := m.Migrate(); err != nil { global.LOG.Error(err) diff --git a/backend/init/migration/migrations/v_1_10.go b/backend/init/migration/migrations/v_1_10.go index 7ee32a68b..4562d4941 100644 --- a/backend/init/migration/migrations/v_1_10.go +++ b/backend/init/migration/migrations/v_1_10.go @@ -154,3 +154,13 @@ var AddDeveloperSetting = &gormigrate.Migration{ return nil }, } + +var AddWebsiteSSLColumn = &gormigrate.Migration{ + ID: "20240508-update-website-ssl", + Migrate: func(tx *gorm.DB) error { + if err := tx.AutoMigrate(&model.WebsiteSSL{}); err != nil { + return err + } + return nil + }, +} diff --git a/backend/utils/common/common.go b/backend/utils/common/common.go index 5395e70c4..1f20a2681 100644 --- a/backend/utils/common/common.go +++ b/backend/utils/common/common.go @@ -317,3 +317,7 @@ func SplitStr(str string, spi ...string) []string { } return results } + +func IsValidIP(ip string) bool { + return net.ParseIP(ip) != nil +} diff --git a/backend/utils/ssl/client.go b/backend/utils/ssl/client.go index fcf1b7efa..615827f16 100644 --- a/backend/utils/ssl/client.go +++ b/backend/utils/ssl/client.go @@ -3,6 +3,7 @@ package ssl import ( "crypto" "encoding/json" + "os" "time" "github.com/1Panel-dev/1Panel/backend/app/model" @@ -84,7 +85,7 @@ type DNSParam struct { SecretID string `json:"secretID"` } -func (c *AcmeClient) UseDns(dnsType DnsType, params string, skipDNSCheck bool, nameservers []string) error { +func (c *AcmeClient) UseDns(dnsType DnsType, params string, websiteSSL model.WebsiteSSL) error { var ( param DNSParam p challenge.Provider @@ -162,11 +163,23 @@ func (c *AcmeClient) UseDns(dnsType DnsType, params string, skipDNSCheck bool, n if err != nil { return err } + var nameservers []string + if websiteSSL.Nameserver1 != "" { + nameservers = append(nameservers, websiteSSL.Nameserver1) + } + if websiteSSL.Nameserver2 != "" { + nameservers = append(nameservers, websiteSSL.Nameserver2) + } + 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(skipDNSCheck, + dns01.CondOption(websiteSSL.SkipDNS, dns01.DisableCompletePropagationRequirement()), dns01.AddDNSTimeout(10*time.Minute), ) diff --git a/frontend/src/api/interface/website.ts b/frontend/src/api/interface/website.ts index a6a349760..2b1538d1f 100644 --- a/frontend/src/api/interface/website.ts +++ b/frontend/src/api/interface/website.ts @@ -173,6 +173,10 @@ export namespace Website { pushDir: boolean; dir: string; keyType: string; + nameserver1: string; + nameserver2: string; + disableCNAME: boolean; + skipDNS: boolean; } export interface SSLDTO extends SSL { @@ -452,7 +456,6 @@ export namespace Website { export interface SSLObtain { ID: number; - skipDNSCheck: boolean; } export interface CA extends CommonModel { diff --git a/frontend/src/global/form-rules.ts b/frontend/src/global/form-rules.ts index d7e6ef212..04589df85 100644 --- a/frontend/src/global/form-rules.ts +++ b/frontend/src/global/form-rules.ts @@ -22,6 +22,20 @@ const checkIp = (rule: any, value: any, callback: any) => { } }; +const checkIpv4 = (rule: any, value: any, callback: any) => { + if (value === '' || typeof value === 'undefined' || value == null) { + callback(); + } else { + const reg = + /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/; + if (!reg.test(value) && value !== '') { + callback(new Error(i18n.global.t('commons.rule.ip'))); + } else { + callback(); + } + } +}; + const checkIpV6 = (rule: any, value: any, callback: any) => { if (value === '' || typeof value === 'undefined' || value == null) { callback(new Error(i18n.global.t('commons.rule.requiredInput'))); @@ -533,6 +547,7 @@ interface CommonRule { floatNumber: FormItemRule; ip: FormItemRule; ipV6: FormItemRule; + ipv4: FormItemRule; ipV4V6OrDomain: FormItemRule; host: FormItemRule; illegal: FormItemRule; @@ -768,4 +783,8 @@ export const Rules: CommonRule = { validator: checkHttpOrHttps, trigger: 'blur', }, + ipv4: { + validator: checkIpv4, + trigger: 'blur', + }, }; diff --git a/frontend/src/lang/modules/en.ts b/frontend/src/lang/modules/en.ts index d2f53c618..ef6852fca 100644 --- a/frontend/src/lang/modules/en.ts +++ b/frontend/src/lang/modules/en.ts @@ -2062,6 +2062,10 @@ 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', + disableCNAME: 'Disable CNAME', + disableCNAMEHelper: 'Domain name with CNAME configuration, if the application fails, you can check here', + nameserver: 'DNS server', + nameserverHelper: 'Use a custom DNS server to verify domain names', }, firewall: { create: 'Create rule', diff --git a/frontend/src/lang/modules/tw.ts b/frontend/src/lang/modules/tw.ts index 4d344fa01..aa68a7466 100644 --- a/frontend/src/lang/modules/tw.ts +++ b/frontend/src/lang/modules/tw.ts @@ -1929,6 +1929,10 @@ const message = { cfHelper: '請勿使用 Global API Key', deprecated: '即將廢棄', deprecatedHelper: '已經停止維護,可能會在以後的某個版本廢棄,請使用騰訊雲方式解析', + disableCNAME: '停用 CNAME', + disableCNAMEHelper: '有 CNAME 配置的域名,如果申請失敗,可以勾選此處', + nameserver: 'DNS 伺服器', + nameserverHelper: '使用自訂的 DNS 伺服器來校驗網域名稱', }, firewall: { create: '創建規則', diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts index e071df02f..a68a50a79 100644 --- a/frontend/src/lang/modules/zh.ts +++ b/frontend/src/lang/modules/zh.ts @@ -1929,6 +1929,10 @@ const message = { cfHelper: '请勿使用 Global API Key', deprecated: '即将废弃', deprecatedHelper: '已经停止维护,可能会在以后的某个版本废弃,请使用腾讯云方式解析', + disableCNAME: '禁用 CNAME', + disableCNAMEHelper: '有 CNAME 配置的域名,如果申请失败,可以勾选此处', + nameserver: 'DNS 服务器', + nameserverHelper: '使用自定义的 DNS 服务器来校验域名', }, firewall: { create: '创建规则', diff --git a/frontend/src/views/website/ssl/apply/index.vue b/frontend/src/views/website/ssl/apply/index.vue index 941fcfebd..9ef492c37 100644 --- a/frontend/src/views/website/ssl/apply/index.vue +++ b/frontend/src/views/website/ssl/apply/index.vue @@ -31,11 +31,6 @@ -
- {{ $t('ssl.skipDNSCheck') }} - {{ $t('ssl.skipDNSCheckHelper') }} -
-