diff --git a/internal/const/const.go b/internal/const/const.go index 98d4b15c..2bd19890 100644 --- a/internal/const/const.go +++ b/internal/const/const.go @@ -1,7 +1,7 @@ package teaconst const ( - Version = "0.0.4" + Version = "0.0.5" ProductName = "Edge Admin" ProcessName = "edge-admin" diff --git a/internal/web/actions/default/servers/certs/acme/create.go b/internal/web/actions/default/servers/certs/acme/create.go index 5a03d26a..faae6b2c 100644 --- a/internal/web/actions/default/servers/certs/acme/create.go +++ b/internal/web/actions/default/servers/certs/acme/create.go @@ -66,6 +66,7 @@ func (this *CreateAction) RunGet(params struct{}) { func (this *CreateAction) RunPost(params struct { TaskId int64 + AuthType string AcmeUserId int64 DnsProviderId int64 DnsDomain string @@ -74,18 +75,26 @@ func (this *CreateAction) RunPost(params struct { Must *actions.Must }) { + if params.AuthType != "dns" && params.AuthType != "http" { + this.Fail("无法识别的认证方式'" + params.AuthType + "'") + } + if params.AcmeUserId <= 0 { this.Fail("请选择一个申请证书的用户") } - if params.DnsProviderId <= 0 { - this.Fail("请选择DNS服务商") - } - if len(params.DnsDomain) == 0 { - this.Fail("请输入顶级域名") - } + + // 校验DNS相关信息 dnsDomain := strings.ToLower(params.DnsDomain) - if !domainutils.ValidateDomainFormat(dnsDomain) { - this.Fail("请输入正确的顶级域名") + if params.AuthType == "dns" { + if params.DnsProviderId <= 0 { + this.Fail("请选择DNS服务商") + } + if len(params.DnsDomain) == 0 { + this.Fail("请输入顶级域名") + } + if !domainutils.ValidateDomainFormat(dnsDomain) { + this.Fail("请输入正确的顶级域名") + } } if len(params.Domains) == 0 { @@ -94,14 +103,21 @@ func (this *CreateAction) RunPost(params struct { realDomains := []string{} for _, domain := range params.Domains { domain = strings.ToLower(domain) - if !strings.HasSuffix(domain, "."+dnsDomain) && domain != dnsDomain { - this.Fail("证书域名中的" + domain + "和顶级域名不一致") + if params.AuthType == "dns" { // DNS认证 + if !strings.HasSuffix(domain, "."+dnsDomain) && domain != dnsDomain { + this.Fail("证书域名中的" + domain + "和顶级域名不一致") + } + } else if params.AuthType == "http" { // HTTP认证 + if strings.Contains(domain, "*") { + this.Fail("在HTTP认证时域名" + domain + "不能包含通配符") + } } realDomains = append(realDomains, domain) } if params.TaskId == 0 { createResp, err := this.RPC().ACMETaskRPC().CreateACMETask(this.AdminContext(), &pb.CreateACMETaskRequest{ + AuthType: params.AuthType, AcmeUserId: params.AcmeUserId, DnsProviderId: params.DnsProviderId, DnsDomain: dnsDomain, diff --git a/internal/web/actions/default/servers/certs/acme/index.go b/internal/web/actions/default/servers/certs/acme/index.go index 419faef3..f3f92a00 100644 --- a/internal/web/actions/default/servers/certs/acme/index.go +++ b/internal/web/actions/default/servers/certs/acme/index.go @@ -42,9 +42,16 @@ func (this *IndexAction) RunGet(params struct{}) { taskMaps := []maps.Map{} for _, task := range tasksResp.AcmeTasks { - if task.AcmeUser == nil || task.DnsProvider == nil { + if task.AcmeUser == nil { continue } + dnsProviderMap := maps.Map{} + if task.AuthType == "dns" && task.DnsProvider != nil { + dnsProviderMap = maps.Map{ + "id": task.DnsProvider.Id, + "name": task.DnsProvider.Name, + } + } // 证书 var certMap maps.Map = nil @@ -69,20 +76,18 @@ func (this *IndexAction) RunGet(params struct{}) { } taskMaps = append(taskMaps, maps.Map{ - "id": task.Id, + "id": task.Id, + "authType": task.AuthType, "acmeUser": maps.Map{ "id": task.AcmeUser.Id, "email": task.AcmeUser.Email, }, - "dnsProvider": maps.Map{ - "id": task.DnsProvider.Id, - "name": task.DnsProvider.Name, - }, - "dnsDomain": task.DnsDomain, - "domains": task.Domains, - "autoRenew": task.AutoRenew, - "cert": certMap, - "log": logMap, + "dnsProvider": dnsProviderMap, + "dnsDomain": task.DnsDomain, + "domains": task.Domains, + "autoRenew": task.AutoRenew, + "cert": certMap, + "log": logMap, }) } this.Data["tasks"] = taskMaps diff --git a/internal/web/actions/default/servers/certs/acme/updateTaskPopup.go b/internal/web/actions/default/servers/certs/acme/updateTaskPopup.go index efd0e9ef..b359a9f7 100644 --- a/internal/web/actions/default/servers/certs/acme/updateTaskPopup.go +++ b/internal/web/actions/default/servers/certs/acme/updateTaskPopup.go @@ -54,14 +54,14 @@ func (this *UpdateTaskPopupAction) RunGet(params struct { } this.Data["task"] = maps.Map{ - "id": task.Id, - "acmeUser": acmeUserMap, - "dnsProviderId": task.DnsProvider.Id, - "dnsDomain": task.DnsDomain, - "domains": task.Domains, - "autoRenew": task.AutoRenew, - "isOn": task.IsOn, - "dnsProvider": dnsProviderMap, + "id": task.Id, + "authType": task.AuthType, + "acmeUser": acmeUserMap, + "dnsDomain": task.DnsDomain, + "domains": task.Domains, + "autoRenew": task.AutoRenew, + "isOn": task.IsOn, + "dnsProvider": dnsProviderMap, } // 域名解析服务商 @@ -88,6 +88,7 @@ func (this *UpdateTaskPopupAction) RunGet(params struct { func (this *UpdateTaskPopupAction) RunPost(params struct { TaskId int64 + AuthType string AcmeUserId int64 DnsProviderId int64 DnsDomain string @@ -99,18 +100,25 @@ func (this *UpdateTaskPopupAction) RunPost(params struct { }) { defer this.CreateLogInfo("修改证书申请任务 %d", params.TaskId) + if params.AuthType != "dns" && params.AuthType != "http" { + this.Fail("无法识别的认证方式'" + params.AuthType + "'") + } + if params.AcmeUserId <= 0 { this.Fail("请选择一个申请证书的用户") } - if params.DnsProviderId <= 0 { - this.Fail("请选择DNS服务商") - } - if len(params.DnsDomain) == 0 { - this.Fail("请输入顶级域名") - } + dnsDomain := strings.ToLower(params.DnsDomain) - if !domainutils.ValidateDomainFormat(dnsDomain) { - this.Fail("请输入正确的顶级域名") + if params.AuthType == "dns" { + if params.DnsProviderId <= 0 { + this.Fail("请选择DNS服务商") + } + if len(params.DnsDomain) == 0 { + this.Fail("请输入顶级域名") + } + if !domainutils.ValidateDomainFormat(dnsDomain) { + this.Fail("请输入正确的顶级域名") + } } if len(params.Domains) == 0 { @@ -119,8 +127,14 @@ func (this *UpdateTaskPopupAction) RunPost(params struct { realDomains := []string{} for _, domain := range params.Domains { domain = strings.ToLower(domain) - if !strings.HasSuffix(domain, "."+dnsDomain) && domain != dnsDomain { - this.Fail("证书域名中的" + domain + "和顶级域名不一致") + if params.AuthType == "dns" { + if !strings.HasSuffix(domain, "."+dnsDomain) && domain != dnsDomain { + this.Fail("证书域名中的" + domain + "和顶级域名不一致") + } + } else if params.AuthType == "http" { // HTTP认证 + if strings.Contains(domain, "*") { + this.Fail("在HTTP认证时域名" + domain + "不能包含通配符") + } } realDomains = append(realDomains, domain) } diff --git a/internal/web/helpers/utils.go b/internal/web/helpers/utils.go index eaac2d28..bf5c01eb 100644 --- a/internal/web/helpers/utils.go +++ b/internal/web/helpers/utils.go @@ -52,7 +52,12 @@ func checkIPWithoutCache(config *systemconfigs.SecurityConfig, ipAddr string) bo } // 本地IP - ip := net.ParseIP(ipAddr).To4() + ipObj := net.ParseIP(ipAddr) + if ipObj == nil { + logs.Println("[USER_MUST_AUTH]invalid client address: " + ipAddr) + return false + } + ip := ipObj.To4() if ip == nil { logs.Println("[USER_MUST_AUTH]invalid client address: " + ipAddr) return false diff --git a/web/views/@default/servers/certs/acme/create.html b/web/views/@default/servers/certs/acme/create.html index fda844c1..aeff6722 100644 --- a/web/views/@default/servers/certs/acme/create.html +++ b/web/views/@default/servers/certs/acme/create.html @@ -9,13 +9,13 @@
- 准备工作 + 选择申请方式
选择用户
- 设置域名解析 + 填写域名信息
完成 @@ -24,9 +24,14 @@
-
此流程用于免费申请一个新的证书。
-
-
+
+ 使用HTTP认证   + 使用DNS认证 +
+
+ 使用HTTP的方式请求网址/.well-known/acme-challenge/令牌校验,该方式要求需要实现将域名解析到集群上,之后系统会自动生成网址信息。 +
+
我们在申请免费证书的过程中需要自动增加或修改相关域名的TXT记录,请先确保你已经在"域名解析" -- "DNS服务商" 中已经添加了对应的DNS服务商账号。
@@ -69,7 +74,7 @@
- + - + diff --git a/web/views/@default/servers/certs/acme/create.js b/web/views/@default/servers/certs/acme/create.js index 0d1f938c..24eb469e 100644 --- a/web/views/@default/servers/certs/acme/create.js +++ b/web/views/@default/servers/certs/acme/create.js @@ -4,6 +4,8 @@ Tea.context(function () { /** * 准备工作 */ + this.authType = "http" + this.doPrepare = function () { this.step = "user" } @@ -70,6 +72,7 @@ Tea.context(function () { this.$post("$") .params({ + authType: this.authType, acmeUserId: this.userId, dnsProviderId: this.dnsProviderId, dnsDomain: this.dnsDomain, diff --git a/web/views/@default/servers/certs/acme/index.html b/web/views/@default/servers/certs/acme/index.html index 5ef9ed61..46a97247 100644 --- a/web/views/@default/servers/certs/acme/index.html +++ b/web/views/@default/servers/certs/acme/index.html @@ -21,7 +21,12 @@ - +
选择DNS服务商 *
@@ -81,7 +86,7 @@

用于自动创建域名解析记录。

顶级域名 * @@ -92,7 +97,7 @@ 证书域名列表 * -

需要申请的证书中包含的域名列表,所有域名必须是同一个顶级域名。

+

需要申请的证书中包含的域名列表,所有域名必须是同一个顶级域名使用HTTP认证方式时,域名中不能含有通配符

{{task.acmeUser.email}}{{task.acmeUser.email}} +
+ DNS + HTTP +
+
{{domain}} diff --git a/web/views/@default/servers/certs/acme/updateTaskPopup.html b/web/views/@default/servers/certs/acme/updateTaskPopup.html index 75298b9a..917736f6 100644 --- a/web/views/@default/servers/certs/acme/updateTaskPopup.html +++ b/web/views/@default/servers/certs/acme/updateTaskPopup.html @@ -5,9 +5,10 @@ + - + - +
选择DNS服务商 *
@@ -19,7 +20,7 @@

用于自动创建域名解析记录。

顶级域名 * @@ -30,7 +31,7 @@ 证书域名列表 * -

需要申请的证书中包含的域名列表,所有域名必须是同一个顶级域名。

+

需要申请的证书中包含的域名列表,所有域名必须是同一个顶级域名使用HTTP认证方式时,域名中不能含有通配符