Initial code commit
This commit is contained in:
94
internal/providers/letsencrypt/namecheap_dns.go
Normal file
94
internal/providers/letsencrypt/namecheap_dns.go
Normal file
@@ -0,0 +1,94 @@
|
||||
package letsencrypt
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/go-acme/lego/v4/challenge/dns01"
|
||||
"sslh-multiplex-lab/internal/providers/namecheap"
|
||||
)
|
||||
|
||||
type NamecheapDNSProvider struct {
|
||||
namecheapClient *namecheap.Client
|
||||
domain string
|
||||
txtRecords map[string]string
|
||||
}
|
||||
|
||||
func NewNamecheapDNSProvider(namecheapClient *namecheap.Client, domain string) *NamecheapDNSProvider {
|
||||
return &NamecheapDNSProvider{
|
||||
namecheapClient: namecheapClient,
|
||||
domain: domain,
|
||||
txtRecords: make(map[string]string),
|
||||
}
|
||||
}
|
||||
|
||||
func (p *NamecheapDNSProvider) Present(domain, token, keyAuth string) error {
|
||||
fqdn, value := dns01.GetRecord(domain, keyAuth)
|
||||
|
||||
subdomain := extractSubdomain(fqdn, p.domain)
|
||||
if subdomain == "" {
|
||||
return fmt.Errorf("failed to extract subdomain from %s for domain %s", fqdn, p.domain)
|
||||
}
|
||||
|
||||
p.txtRecords[subdomain] = value
|
||||
|
||||
_, err := p.namecheapClient.CreateOrUpdateDNSRecord(p.domain, subdomain, "TXT", value, 300)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create TXT record for %s: %w", subdomain, err)
|
||||
}
|
||||
|
||||
time.Sleep(10 * time.Second)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *NamecheapDNSProvider) CleanUp(domain, token, keyAuth string) error {
|
||||
fqdn, _ := dns01.GetRecord(domain, keyAuth)
|
||||
|
||||
subdomain := extractSubdomain(fqdn, p.domain)
|
||||
if subdomain == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
records, err := p.namecheapClient.ListDNSRecords(p.domain)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to list DNS records: %w", err)
|
||||
}
|
||||
|
||||
for _, record := range records {
|
||||
if record.Name == subdomain && record.Type == "TXT" {
|
||||
if err := p.namecheapClient.DeleteDNSRecord(p.domain, record.ID); err != nil {
|
||||
return fmt.Errorf("failed to delete TXT record for %s: %w", subdomain, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete(p.txtRecords, subdomain)
|
||||
return nil
|
||||
}
|
||||
|
||||
func extractSubdomain(fqdn, domain string) string {
|
||||
if len(fqdn) <= len(domain) {
|
||||
return ""
|
||||
}
|
||||
|
||||
suffix := "." + domain
|
||||
if !endsWith(fqdn, suffix) {
|
||||
return ""
|
||||
}
|
||||
|
||||
subdomain := fqdn[:len(fqdn)-len(suffix)]
|
||||
if subdomain == "_acme-challenge" {
|
||||
return "_acme-challenge"
|
||||
}
|
||||
|
||||
if len(subdomain) > len("_acme-challenge.") && subdomain[:len("_acme-challenge.")] == "_acme-challenge." {
|
||||
return subdomain
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func endsWith(s, suffix string) bool {
|
||||
return len(s) >= len(suffix) && s[len(s)-len(suffix):] == suffix
|
||||
}
|
||||
Reference in New Issue
Block a user