[SSL证书]免费证书申请增加HTTP认证方式

This commit is contained in:
刘祥超
2020-12-03 18:19:22 +08:00
parent ee296ad1c9
commit 5f0e7833a0
20 changed files with 369 additions and 57 deletions

View File

@@ -0,0 +1,54 @@
package models
import (
_ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/dbs"
)
type ACMEAuthenticationDAO dbs.DAO
func NewACMEAuthenticationDAO() *ACMEAuthenticationDAO {
return dbs.NewDAO(&ACMEAuthenticationDAO{
DAOObject: dbs.DAOObject{
DB: Tea.Env,
Table: "edgeACMEAuthentications",
Model: new(ACMEAuthentication),
PkName: "id",
},
}).(*ACMEAuthenticationDAO)
}
var SharedACMEAuthenticationDAO *ACMEAuthenticationDAO
func init() {
dbs.OnReady(func() {
SharedACMEAuthenticationDAO = NewACMEAuthenticationDAO()
})
}
// 创建认证信息
func (this *ACMEAuthenticationDAO) CreateAuth(taskId int64, domain string, token string, key string) error {
op := NewACMEAuthenticationOperator()
op.TaskId = taskId
op.Domain = domain
op.Token = token
op.Key = key
_, err := this.Save(op)
return err
}
// 根据令牌查找认证信息
func (this *ACMEAuthenticationDAO) FindAuthWithToken(token string) (*ACMEAuthentication, error) {
one, err := this.Query().
Attr("token", token).
DescPk().
Find()
if err != nil {
return nil, err
}
if one == nil {
return nil, nil
}
return one.(*ACMEAuthentication), nil
}

View File

@@ -0,0 +1,5 @@
package models
import (
_ "github.com/go-sql-driver/mysql"
)

View File

@@ -0,0 +1,24 @@
package models
// ACME认证
type ACMEAuthentication struct {
Id uint64 `field:"id"` // ID
TaskId uint64 `field:"taskId"` // 任务ID
Domain string `field:"domain"` // 域名
Token string `field:"token"` // 令牌
Key string `field:"key"` // 密钥
CreatedAt uint64 `field:"createdAt"` // 创建时间
}
type ACMEAuthenticationOperator struct {
Id interface{} // ID
TaskId interface{} // 任务ID
Domain interface{} // 域名
Token interface{} // 令牌
Key interface{} // 密钥
CreatedAt interface{} // 创建时间
}
func NewACMEAuthenticationOperator() *ACMEAuthenticationOperator {
return &ACMEAuthenticationOperator{}
}

View File

@@ -0,0 +1 @@
package models

View File

@@ -115,10 +115,11 @@ func (this *ACMETaskDAO) ListEnabledACMETasks(adminId int64, userId int64, offse
}
// 创建任务
func (this *ACMETaskDAO) CreateACMETask(adminId int64, userId int64, acmeUserId int64, dnsProviderId int64, dnsDomain string, domains []string, autoRenew bool) (int64, error) {
func (this *ACMETaskDAO) CreateACMETask(adminId int64, userId int64, authType acme.AuthType, acmeUserId int64, dnsProviderId int64, dnsDomain string, domains []string, autoRenew bool) (int64, error) {
op := NewACMETaskOperator()
op.AdminId = adminId
op.UserId = userId
op.AuthType = authType
op.AcmeUserId = acmeUserId
op.DnsProviderId = dnsProviderId
op.DnsDomain = dnsDomain
@@ -255,37 +256,55 @@ func (this *ACMETaskDAO) runTaskWithoutLog(taskId int64) (isOk bool, errMsg stri
}
}
// DNS服务商
dnsProvider, err := SharedDNSProviderDAO.FindEnabledDNSProvider(int64(task.DnsProviderId))
if err != nil {
errMsg = "查找DNS服务商账号信息时出错" + err.Error()
return
}
if dnsProvider == nil {
errMsg = "找不到DNS服务商账号"
return
}
providerInterface := dnsclients.FindProvider(dnsProvider.Type)
if providerInterface == nil {
errMsg = "暂不支持此类型的DNS服务商 '" + dnsProvider.Type + "'"
return
}
apiParams, err := dnsProvider.DecodeAPIParams()
if err != nil {
errMsg = "解析DNS服务商API参数时出错" + err.Error()
return
}
err = providerInterface.Auth(apiParams)
if err != nil {
errMsg = "校验DNS服务商API参数时出错" + err.Error()
return
var acmeTask *acme.Task = nil
if task.AuthType == acme.AuthTypeDNS {
// DNS服务商
dnsProvider, err := SharedDNSProviderDAO.FindEnabledDNSProvider(int64(task.DnsProviderId))
if err != nil {
errMsg = "查找DNS服务商账号信息时出错" + err.Error()
return
}
if dnsProvider == nil {
errMsg = "找不到DNS服务商账号"
return
}
providerInterface := dnsclients.FindProvider(dnsProvider.Type)
if providerInterface == nil {
errMsg = "暂不支持此类型的DNS服务商 '" + dnsProvider.Type + "'"
return
}
apiParams, err := dnsProvider.DecodeAPIParams()
if err != nil {
errMsg = "解析DNS服务商API参数时出错" + err.Error()
return
}
err = providerInterface.Auth(apiParams)
if err != nil {
errMsg = "校验DNS服务商API参数时出错" + err.Error()
return
}
acmeTask = &acme.Task{
User: remoteUser,
AuthType: acme.AuthTypeDNS,
DNSProvider: providerInterface,
DNSDomain: task.DnsDomain,
Domains: task.DecodeDomains(),
}
} else if task.AuthType == acme.AuthTypeHTTP {
acmeTask = &acme.Task{
User: remoteUser,
AuthType: acme.AuthTypeHTTP,
Domains: task.DecodeDomains(),
}
}
acmeRequest := acme.NewRequest(&acme.Task{
User: remoteUser,
DNSProvider: providerInterface,
DNSDomain: task.DnsDomain,
Domains: task.DecodeDomains(),
acmeRequest := acme.NewRequest(acmeTask)
acmeRequest.OnAuth(func(domain, token, keyAuth string) {
err := SharedACMEAuthenticationDAO.CreateAuth(taskId, domain, token, keyAuth)
if err != nil {
logs.Println("[ACME]write authentication to database error: " + err.Error())
}
})
certData, keyData, err := acmeRequest.Run()
if err != nil {

View File

@@ -14,6 +14,7 @@ type ACMETask struct {
State uint8 `field:"state"` // 状态
CertId uint64 `field:"certId"` // 生成的证书ID
AutoRenew uint8 `field:"autoRenew"` // 是否自动更新
AuthType string `field:"authType"` // 认证类型
}
type ACMETaskOperator struct {
@@ -29,6 +30,7 @@ type ACMETaskOperator struct {
State interface{} // 状态
CertId interface{} // 生成的证书ID
AutoRenew interface{} // 是否自动更新
AuthType interface{} // 认证类型
}
func NewACMETaskOperator() *ACMETaskOperator {

View File

@@ -637,8 +637,7 @@ func (this *NodeDAO) FindEnabledNodeDNS(nodeId int64) (*Node, error) {
one, err := this.Query().
State(NodeStateEnabled).
Pk(nodeId).
Attr("isOn", true).
Result("id", "name", "dnsRoutes", "clusterId").
Result("id", "name", "dnsRoutes", "clusterId", "isOn").
Find()
if err != nil || one == nil {
return nil, err