2020-11-26 16:39:06 +08:00
|
|
|
package acme
|
|
|
|
|
|
|
|
|
|
import (
|
2023-08-11 16:13:33 +08:00
|
|
|
"fmt"
|
2024-07-27 14:15:25 +08:00
|
|
|
"os"
|
|
|
|
|
"strings"
|
|
|
|
|
"sync"
|
|
|
|
|
"time"
|
|
|
|
|
|
2020-11-26 16:39:06 +08:00
|
|
|
"github.com/TeaOSLab/EdgeAPI/internal/dnsclients"
|
2021-06-02 18:13:48 +08:00
|
|
|
"github.com/TeaOSLab/EdgeAPI/internal/dnsclients/dnstypes"
|
2020-11-26 16:39:06 +08:00
|
|
|
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
|
|
|
|
"github.com/go-acme/lego/v4/challenge/dns01"
|
2022-11-17 17:33:59 +08:00
|
|
|
"github.com/iwind/TeaGo/lists"
|
2020-11-26 16:39:06 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type DNSProvider struct {
|
2021-09-08 18:23:37 +08:00
|
|
|
raw dnsclients.ProviderInterface
|
|
|
|
|
dnsDomain string
|
2022-11-17 17:33:59 +08:00
|
|
|
|
|
|
|
|
locker sync.Mutex
|
|
|
|
|
deletedRecordNames []string
|
2020-11-26 16:39:06 +08:00
|
|
|
}
|
|
|
|
|
|
2021-09-08 18:23:37 +08:00
|
|
|
func NewDNSProvider(raw dnsclients.ProviderInterface, dnsDomain string) *DNSProvider {
|
|
|
|
|
return &DNSProvider{
|
|
|
|
|
raw: raw,
|
|
|
|
|
dnsDomain: dnsDomain,
|
|
|
|
|
}
|
2020-11-26 16:39:06 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (this *DNSProvider) Present(domain, token, keyAuth string) error {
|
2022-11-17 17:33:59 +08:00
|
|
|
_ = os.Setenv("LEGO_DISABLE_CNAME_SUPPORT", "true")
|
2024-05-12 09:33:51 +08:00
|
|
|
var info = dns01.GetChallengeInfo(domain, keyAuth)
|
|
|
|
|
|
|
|
|
|
var fqdn = info.EffectiveFQDN
|
|
|
|
|
var value = info.Value
|
2020-11-26 16:39:06 +08:00
|
|
|
|
|
|
|
|
// 设置记录
|
2022-08-28 20:02:13 +08:00
|
|
|
var index = strings.Index(fqdn, "."+this.dnsDomain)
|
2020-11-26 16:39:06 +08:00
|
|
|
if index < 0 {
|
|
|
|
|
return errors.New("invalid fqdn value")
|
|
|
|
|
}
|
2022-08-28 20:02:13 +08:00
|
|
|
var recordName = fqdn[:index]
|
2022-11-17 17:33:59 +08:00
|
|
|
|
|
|
|
|
// 先删除老的
|
|
|
|
|
this.locker.Lock()
|
|
|
|
|
var wasDeleted = lists.ContainsString(this.deletedRecordNames, recordName)
|
|
|
|
|
this.locker.Unlock()
|
|
|
|
|
|
|
|
|
|
if !wasDeleted {
|
|
|
|
|
records, err := this.raw.QueryRecords(this.dnsDomain, recordName, dnstypes.RecordTypeTXT)
|
2020-11-26 16:39:06 +08:00
|
|
|
if err != nil {
|
2023-08-11 16:13:33 +08:00
|
|
|
return fmt.Errorf("query DNS record failed: %w", err)
|
2020-11-26 16:39:06 +08:00
|
|
|
}
|
2022-11-17 17:33:59 +08:00
|
|
|
for _, record := range records {
|
|
|
|
|
err = this.raw.DeleteRecord(this.dnsDomain, record)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
2020-11-26 16:39:06 +08:00
|
|
|
}
|
2022-11-17 17:33:59 +08:00
|
|
|
this.locker.Lock()
|
|
|
|
|
this.deletedRecordNames = append(this.deletedRecordNames, recordName)
|
|
|
|
|
this.locker.Unlock()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 添加新的
|
|
|
|
|
err := this.raw.AddRecord(this.dnsDomain, &dnstypes.Record{
|
|
|
|
|
Id: "",
|
|
|
|
|
Name: recordName,
|
|
|
|
|
Type: dnstypes.RecordTypeTXT,
|
|
|
|
|
Value: value,
|
|
|
|
|
Route: this.raw.DefaultRoute(),
|
2024-05-12 09:33:51 +08:00
|
|
|
TTL: this.raw.MinTTL(),
|
2022-11-17 17:33:59 +08:00
|
|
|
})
|
|
|
|
|
if err != nil {
|
2023-08-11 16:13:33 +08:00
|
|
|
return fmt.Errorf("create DNS record failed: %w", err)
|
2020-11-26 16:39:06 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-12 16:25:05 +08:00
|
|
|
func (this *DNSProvider) Timeout() (timeout, interval time.Duration) {
|
|
|
|
|
return 2 * time.Minute, 2 * time.Second
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-26 16:39:06 +08:00
|
|
|
func (this *DNSProvider) CleanUp(domain, token, keyAuth string) error {
|
|
|
|
|
return nil
|
|
|
|
|
}
|