cpanel: remove custom DNS call (#2102)
This commit is contained in:
parent
83ff393131
commit
c5a95c4cd0
6 changed files with 74 additions and 188 deletions
|
@ -621,7 +621,6 @@ func displayDNSHelp(w io.Writer, name string) error {
|
||||||
|
|
||||||
ew.writeln(`Credentials:`)
|
ew.writeln(`Credentials:`)
|
||||||
ew.writeln(` - "CPANEL_BASE_URL": API server URL`)
|
ew.writeln(` - "CPANEL_BASE_URL": API server URL`)
|
||||||
ew.writeln(` - "CPANEL_NAMESERVER": Nameserver`)
|
|
||||||
ew.writeln(` - "CPANEL_TOKEN": API token`)
|
ew.writeln(` - "CPANEL_TOKEN": API token`)
|
||||||
ew.writeln(` - "CPANEL_USERNAME": username`)
|
ew.writeln(` - "CPANEL_USERNAME": username`)
|
||||||
ew.writeln()
|
ew.writeln()
|
||||||
|
|
|
@ -31,7 +31,6 @@ Here is an example bash command using the CPanel/WHM provider:
|
||||||
CPANEL_USERNAME = "yyyy"
|
CPANEL_USERNAME = "yyyy"
|
||||||
CPANEL_TOKEN = "xxxx"
|
CPANEL_TOKEN = "xxxx"
|
||||||
CPANEL_BASE_URL = "https://example.com:2083" \
|
CPANEL_BASE_URL = "https://example.com:2083" \
|
||||||
CPANEL_NAMESERVER = "ns1.example.com:53" \
|
|
||||||
lego --email you@example.com --dns cpanel --domains my.example.org run
|
lego --email you@example.com --dns cpanel --domains my.example.org run
|
||||||
|
|
||||||
## WHM
|
## WHM
|
||||||
|
@ -40,7 +39,6 @@ CPANEL_MODE = whm
|
||||||
CPANEL_USERNAME = "yyyy"
|
CPANEL_USERNAME = "yyyy"
|
||||||
CPANEL_TOKEN = "xxxx"
|
CPANEL_TOKEN = "xxxx"
|
||||||
CPANEL_BASE_URL = "https://example.com:2087" \
|
CPANEL_BASE_URL = "https://example.com:2087" \
|
||||||
CPANEL_NAMESERVER = "ns1.example.com:53" \
|
|
||||||
lego --email you@example.com --dns cpanel --domains my.example.org run
|
lego --email you@example.com --dns cpanel --domains my.example.org run
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -52,7 +50,6 @@ lego --email you@example.com --dns cpanel --domains my.example.org run
|
||||||
| Environment Variable Name | Description |
|
| Environment Variable Name | Description |
|
||||||
|-----------------------|-------------|
|
|-----------------------|-------------|
|
||||||
| `CPANEL_BASE_URL` | API server URL |
|
| `CPANEL_BASE_URL` | API server URL |
|
||||||
| `CPANEL_NAMESERVER` | Nameserver |
|
|
||||||
| `CPANEL_TOKEN` | API token |
|
| `CPANEL_TOKEN` | API token |
|
||||||
| `CPANEL_USERNAME` | username |
|
| `CPANEL_USERNAME` | username |
|
||||||
|
|
||||||
|
|
|
@ -21,11 +21,10 @@ import (
|
||||||
const (
|
const (
|
||||||
envNamespace = "CPANEL_"
|
envNamespace = "CPANEL_"
|
||||||
|
|
||||||
EnvMode = envNamespace + "MODE"
|
EnvMode = envNamespace + "MODE"
|
||||||
EnvUsername = envNamespace + "USERNAME"
|
EnvUsername = envNamespace + "USERNAME"
|
||||||
EnvToken = envNamespace + "TOKEN"
|
EnvToken = envNamespace + "TOKEN"
|
||||||
EnvBaseURL = envNamespace + "BASE_URL"
|
EnvBaseURL = envNamespace + "BASE_URL"
|
||||||
EnvNameserver = envNamespace + "NAMESERVER"
|
|
||||||
|
|
||||||
EnvTTL = envNamespace + "TTL"
|
EnvTTL = envNamespace + "TTL"
|
||||||
EnvPropagationTimeout = envNamespace + "PROPAGATION_TIMEOUT"
|
EnvPropagationTimeout = envNamespace + "PROPAGATION_TIMEOUT"
|
||||||
|
@ -46,7 +45,6 @@ type Config struct {
|
||||||
Username string
|
Username string
|
||||||
Token string
|
Token string
|
||||||
BaseURL string
|
BaseURL string
|
||||||
Nameserver string
|
|
||||||
TTL int
|
TTL int
|
||||||
PropagationTimeout time.Duration
|
PropagationTimeout time.Duration
|
||||||
PollingInterval time.Duration
|
PollingInterval time.Duration
|
||||||
|
@ -58,7 +56,7 @@ func NewDefaultConfig() *Config {
|
||||||
return &Config{
|
return &Config{
|
||||||
Mode: env.GetOrDefaultString(EnvMode, "cpanel"),
|
Mode: env.GetOrDefaultString(EnvMode, "cpanel"),
|
||||||
TTL: env.GetOrDefaultInt(EnvTTL, 300),
|
TTL: env.GetOrDefaultInt(EnvTTL, 300),
|
||||||
PropagationTimeout: env.GetOrDefaultSecond(EnvPropagationTimeout, dns01.DefaultPropagationTimeout),
|
PropagationTimeout: env.GetOrDefaultSecond(EnvPropagationTimeout, 2*time.Minute),
|
||||||
PollingInterval: env.GetOrDefaultSecond(EnvPollingInterval, dns01.DefaultPollingInterval),
|
PollingInterval: env.GetOrDefaultSecond(EnvPollingInterval, dns01.DefaultPollingInterval),
|
||||||
HTTPClient: &http.Client{
|
HTTPClient: &http.Client{
|
||||||
Timeout: env.GetOrDefaultSecond(EnvHTTPTimeout, 30*time.Second),
|
Timeout: env.GetOrDefaultSecond(EnvHTTPTimeout, 30*time.Second),
|
||||||
|
@ -68,16 +66,15 @@ func NewDefaultConfig() *Config {
|
||||||
|
|
||||||
// DNSProvider implements the challenge.Provider interface.
|
// DNSProvider implements the challenge.Provider interface.
|
||||||
type DNSProvider struct {
|
type DNSProvider struct {
|
||||||
config *Config
|
config *Config
|
||||||
client apiClient
|
client apiClient
|
||||||
dnsClient *shared.DNSClient
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDNSProvider returns a DNSProvider instance configured for CPanel.
|
// NewDNSProvider returns a DNSProvider instance configured for CPanel.
|
||||||
// Credentials must be passed in the environment variables:
|
// Credentials must be passed in the environment variables:
|
||||||
// CPANEL_USERNAME, CPANEL_TOKEN, CPANEL_BASE_URL, CPANEL_NAMESERVER.
|
// CPANEL_USERNAME, CPANEL_TOKEN, CPANEL_BASE_URL, CPANEL_NAMESERVER.
|
||||||
func NewDNSProvider() (*DNSProvider, error) {
|
func NewDNSProvider() (*DNSProvider, error) {
|
||||||
values, err := env.Get(EnvUsername, EnvToken, EnvBaseURL, EnvNameserver)
|
values, err := env.Get(EnvUsername, EnvToken, EnvBaseURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cpanel: %w", err)
|
return nil, fmt.Errorf("cpanel: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -86,7 +83,6 @@ func NewDNSProvider() (*DNSProvider, error) {
|
||||||
config.Username = values[EnvUsername]
|
config.Username = values[EnvUsername]
|
||||||
config.Token = values[EnvToken]
|
config.Token = values[EnvToken]
|
||||||
config.BaseURL = values[EnvBaseURL]
|
config.BaseURL = values[EnvBaseURL]
|
||||||
config.Nameserver = values[EnvNameserver]
|
|
||||||
|
|
||||||
return NewDNSProviderConfig(config)
|
return NewDNSProviderConfig(config)
|
||||||
}
|
}
|
||||||
|
@ -101,7 +97,7 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
|
||||||
return nil, errors.New("cpanel: some credentials information are missing")
|
return nil, errors.New("cpanel: some credentials information are missing")
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.BaseURL == "" || config.Nameserver == "" {
|
if config.BaseURL == "" {
|
||||||
return nil, errors.New("cpanel: server information are missing")
|
return nil, errors.New("cpanel: server information are missing")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,9 +107,8 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return &DNSProvider{
|
return &DNSProvider{
|
||||||
config: config,
|
config: config,
|
||||||
client: client,
|
client: client,
|
||||||
dnsClient: shared.NewDNSClient(10 * time.Second),
|
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,21 +123,19 @@ func (d *DNSProvider) Present(domain, _, keyAuth string) error {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
info := dns01.GetChallengeInfo(domain, keyAuth)
|
info := dns01.GetChallengeInfo(domain, keyAuth)
|
||||||
|
|
||||||
effectiveDomain := strings.TrimPrefix(info.EffectiveFQDN, "_acme-challenge.")
|
authZone, err := dns01.FindZoneByFqdn(info.EffectiveFQDN)
|
||||||
|
|
||||||
soa, err := d.dnsClient.SOACall(effectiveDomain, d.config.Nameserver)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("cpanel[mode=%s]: could not find SOA for domain %q (%s) in %s: %w", d.config.Mode, domain, info.EffectiveFQDN, d.config.Nameserver, err)
|
return fmt.Errorf("arvancloud: could not find zone for domain %q (%s): %w", domain, info.EffectiveFQDN, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
zone := dns01.UnFqdn(soa.Hdr.Name)
|
zone := dns01.UnFqdn(authZone)
|
||||||
|
|
||||||
zoneInfo, err := d.client.FetchZoneInformation(ctx, zone)
|
zoneInfo, err := d.client.FetchZoneInformation(ctx, zone)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("cpanel[mode=%s]: fetch zone information: %w", d.config.Mode, err)
|
return fmt.Errorf("cpanel[mode=%s]: fetch zone information: %w", d.config.Mode, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
serial, err := getZoneSerial(soa.Hdr.Name, zoneInfo)
|
serial, err := getZoneSerial(authZone, zoneInfo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("cpanel[mode=%s]: get zone serial: %w", d.config.Mode, err)
|
return fmt.Errorf("cpanel[mode=%s]: get zone serial: %w", d.config.Mode, err)
|
||||||
}
|
}
|
||||||
|
@ -204,19 +197,19 @@ func (d *DNSProvider) CleanUp(domain, _, keyAuth string) error {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
info := dns01.GetChallengeInfo(domain, keyAuth)
|
info := dns01.GetChallengeInfo(domain, keyAuth)
|
||||||
|
|
||||||
soa, err := d.dnsClient.SOACall(strings.TrimPrefix(info.EffectiveFQDN, "_acme-challenge."), d.config.Nameserver)
|
authZone, err := dns01.FindZoneByFqdn(info.EffectiveFQDN)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("cpanel[mode=%s]: could not find SOA for domain %q (%s) in %s: %w", d.config.Mode, domain, info.EffectiveFQDN, d.config.Nameserver, err)
|
return fmt.Errorf("arvancloud: could not find zone for domain %q (%s): %w", domain, info.EffectiveFQDN, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
zone := dns01.UnFqdn(soa.Hdr.Name)
|
zone := dns01.UnFqdn(authZone)
|
||||||
|
|
||||||
zoneInfo, err := d.client.FetchZoneInformation(ctx, zone)
|
zoneInfo, err := d.client.FetchZoneInformation(ctx, zone)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("cpanel[mode=%s]: fetch zone information: %w", d.config.Mode, err)
|
return fmt.Errorf("cpanel[mode=%s]: fetch zone information: %w", d.config.Mode, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
serial, err := getZoneSerial(soa.Hdr.Name, zoneInfo)
|
serial, err := getZoneSerial(authZone, zoneInfo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("cpanel[mode=%s]: get zone serial: %w", d.config.Mode, err)
|
return fmt.Errorf("cpanel[mode=%s]: get zone serial: %w", d.config.Mode, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,6 @@ Example = '''
|
||||||
CPANEL_USERNAME = "yyyy"
|
CPANEL_USERNAME = "yyyy"
|
||||||
CPANEL_TOKEN = "xxxx"
|
CPANEL_TOKEN = "xxxx"
|
||||||
CPANEL_BASE_URL = "https://example.com:2083" \
|
CPANEL_BASE_URL = "https://example.com:2083" \
|
||||||
CPANEL_NAMESERVER = "ns1.example.com:53" \
|
|
||||||
lego --email you@example.com --dns cpanel --domains my.example.org run
|
lego --email you@example.com --dns cpanel --domains my.example.org run
|
||||||
|
|
||||||
## WHM
|
## WHM
|
||||||
|
@ -19,7 +18,6 @@ CPANEL_MODE = whm
|
||||||
CPANEL_USERNAME = "yyyy"
|
CPANEL_USERNAME = "yyyy"
|
||||||
CPANEL_TOKEN = "xxxx"
|
CPANEL_TOKEN = "xxxx"
|
||||||
CPANEL_BASE_URL = "https://example.com:2087" \
|
CPANEL_BASE_URL = "https://example.com:2087" \
|
||||||
CPANEL_NAMESERVER = "ns1.example.com:53" \
|
|
||||||
lego --email you@example.com --dns cpanel --domains my.example.org run
|
lego --email you@example.com --dns cpanel --domains my.example.org run
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
@ -28,7 +26,6 @@ lego --email you@example.com --dns cpanel --domains my.example.org run
|
||||||
CPANEL_USERNAME = "username"
|
CPANEL_USERNAME = "username"
|
||||||
CPANEL_TOKEN = "API token"
|
CPANEL_TOKEN = "API token"
|
||||||
CPANEL_BASE_URL = "API server URL"
|
CPANEL_BASE_URL = "API server URL"
|
||||||
CPANEL_NAMESERVER = "Nameserver"
|
|
||||||
[Configuration.Additional]
|
[Configuration.Additional]
|
||||||
CPANEL_MODE = "use cpanel API or WHM API (Default: cpanel)"
|
CPANEL_MODE = "use cpanel API or WHM API (Default: cpanel)"
|
||||||
CPANEL_POLLING_INTERVAL = "Time between DNS propagation check"
|
CPANEL_POLLING_INTERVAL = "Time between DNS propagation check"
|
||||||
|
|
|
@ -16,8 +16,7 @@ var envTest = tester.NewEnvTest(
|
||||||
EnvMode,
|
EnvMode,
|
||||||
EnvUsername,
|
EnvUsername,
|
||||||
EnvToken,
|
EnvToken,
|
||||||
EnvBaseURL,
|
EnvBaseURL).
|
||||||
EnvNameserver).
|
|
||||||
WithDomain(envDomain)
|
WithDomain(envDomain)
|
||||||
|
|
||||||
func TestNewDNSProvider(t *testing.T) {
|
func TestNewDNSProvider(t *testing.T) {
|
||||||
|
@ -30,62 +29,47 @@ func TestNewDNSProvider(t *testing.T) {
|
||||||
{
|
{
|
||||||
desc: "success cpanel mode (default)",
|
desc: "success cpanel mode (default)",
|
||||||
envVars: map[string]string{
|
envVars: map[string]string{
|
||||||
EnvUsername: "user",
|
EnvUsername: "user",
|
||||||
EnvToken: "secret",
|
EnvToken: "secret",
|
||||||
EnvBaseURL: "https://example.com",
|
EnvBaseURL: "https://example.com",
|
||||||
EnvNameserver: "ns.example.com:53",
|
|
||||||
},
|
},
|
||||||
expectedMode: "cpanel",
|
expectedMode: "cpanel",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
desc: "success whm mode",
|
desc: "success whm mode",
|
||||||
envVars: map[string]string{
|
envVars: map[string]string{
|
||||||
EnvMode: "whm",
|
EnvMode: "whm",
|
||||||
EnvUsername: "user",
|
EnvUsername: "user",
|
||||||
EnvToken: "secret",
|
EnvToken: "secret",
|
||||||
EnvBaseURL: "https://example.com",
|
EnvBaseURL: "https://example.com",
|
||||||
EnvNameserver: "ns.example.com:53",
|
|
||||||
},
|
},
|
||||||
expectedMode: "whm",
|
expectedMode: "whm",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
desc: "missing user",
|
desc: "missing user",
|
||||||
envVars: map[string]string{
|
envVars: map[string]string{
|
||||||
EnvToken: "secret",
|
EnvToken: "secret",
|
||||||
EnvBaseURL: "https://example.com",
|
EnvBaseURL: "https://example.com",
|
||||||
EnvNameserver: "ns.example.com:53",
|
|
||||||
},
|
},
|
||||||
expected: "cpanel: some credentials information are missing: CPANEL_USERNAME",
|
expected: "cpanel: some credentials information are missing: CPANEL_USERNAME",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
desc: "missing token",
|
desc: "missing token",
|
||||||
envVars: map[string]string{
|
envVars: map[string]string{
|
||||||
EnvUsername: "user",
|
EnvUsername: "user",
|
||||||
EnvBaseURL: "https://example.com",
|
EnvBaseURL: "https://example.com",
|
||||||
EnvNameserver: "ns.example.com:53",
|
|
||||||
},
|
},
|
||||||
expected: "cpanel: some credentials information are missing: CPANEL_TOKEN",
|
expected: "cpanel: some credentials information are missing: CPANEL_TOKEN",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
desc: "missing base URL",
|
desc: "missing base URL",
|
||||||
envVars: map[string]string{
|
envVars: map[string]string{
|
||||||
EnvUsername: "user",
|
EnvUsername: "user",
|
||||||
EnvToken: "secret",
|
EnvToken: "secret",
|
||||||
EnvBaseURL: "",
|
EnvBaseURL: "",
|
||||||
EnvNameserver: "ns.example.com:53",
|
|
||||||
},
|
},
|
||||||
expected: "cpanel: some credentials information are missing: CPANEL_BASE_URL",
|
expected: "cpanel: some credentials information are missing: CPANEL_BASE_URL",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
desc: "missing nameserver",
|
|
||||||
envVars: map[string]string{
|
|
||||||
EnvUsername: "user",
|
|
||||||
EnvToken: "secret",
|
|
||||||
EnvBaseURL: "https://example.com",
|
|
||||||
EnvNameserver: "",
|
|
||||||
},
|
|
||||||
expected: "cpanel: some credentials information are missing: CPANEL_NAMESERVER",
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
@ -111,74 +95,58 @@ func TestNewDNSProvider(t *testing.T) {
|
||||||
|
|
||||||
func TestNewDNSProviderConfig(t *testing.T) {
|
func TestNewDNSProviderConfig(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
desc string
|
desc string
|
||||||
mode string
|
mode string
|
||||||
username string
|
username string
|
||||||
token string
|
token string
|
||||||
baseURL string
|
baseURL string
|
||||||
nameserver string
|
expected string
|
||||||
expected string
|
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
desc: "success",
|
desc: "success",
|
||||||
mode: "whm",
|
mode: "whm",
|
||||||
username: "user",
|
username: "user",
|
||||||
token: "secret",
|
token: "secret",
|
||||||
baseURL: "https://example.com",
|
baseURL: "https://example.com",
|
||||||
nameserver: "ns.example.com:53",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
desc: "missing mode",
|
desc: "missing mode",
|
||||||
username: "user",
|
username: "user",
|
||||||
token: "secret",
|
token: "secret",
|
||||||
baseURL: "https://example.com",
|
baseURL: "https://example.com",
|
||||||
nameserver: "ns.example.com:53",
|
expected: `cpanel: create client error: unsupported mode: ""`,
|
||||||
expected: `cpanel: create client error: unsupported mode: ""`,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
desc: "invalid mode",
|
desc: "invalid mode",
|
||||||
mode: "test",
|
mode: "test",
|
||||||
username: "user",
|
username: "user",
|
||||||
token: "secret",
|
token: "secret",
|
||||||
baseURL: "https://example.com",
|
baseURL: "https://example.com",
|
||||||
nameserver: "ns.example.com:53",
|
expected: `cpanel: create client error: unsupported mode: "test"`,
|
||||||
expected: `cpanel: create client error: unsupported mode: "test"`,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
desc: "missing username",
|
desc: "missing username",
|
||||||
mode: "whm",
|
mode: "whm",
|
||||||
username: "",
|
username: "",
|
||||||
token: "secret",
|
token: "secret",
|
||||||
baseURL: "https://example.com",
|
baseURL: "https://example.com",
|
||||||
nameserver: "ns.example.com:53",
|
expected: "cpanel: some credentials information are missing",
|
||||||
expected: "cpanel: some credentials information are missing",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
desc: "missing token",
|
desc: "missing token",
|
||||||
mode: "whm",
|
mode: "whm",
|
||||||
username: "user",
|
username: "user",
|
||||||
token: "",
|
token: "",
|
||||||
baseURL: "https://example.com",
|
baseURL: "https://example.com",
|
||||||
nameserver: "ns.example.com:53",
|
expected: "cpanel: some credentials information are missing",
|
||||||
expected: "cpanel: some credentials information are missing",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
desc: "missing base URL",
|
desc: "missing base URL",
|
||||||
mode: "whm",
|
mode: "whm",
|
||||||
username: "user",
|
username: "user",
|
||||||
token: "secret",
|
token: "secret",
|
||||||
baseURL: "",
|
baseURL: "",
|
||||||
nameserver: "ns.example.com:53",
|
expected: "cpanel: server information are missing",
|
||||||
expected: "cpanel: server information are missing",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
desc: "missing nameserver",
|
|
||||||
mode: "whm",
|
|
||||||
username: "user",
|
|
||||||
token: "secret",
|
|
||||||
baseURL: "https://example.com",
|
|
||||||
nameserver: "",
|
|
||||||
expected: "cpanel: server information are missing",
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,7 +157,6 @@ func TestNewDNSProviderConfig(t *testing.T) {
|
||||||
config.Username = test.username
|
config.Username = test.username
|
||||||
config.Token = test.token
|
config.Token = test.token
|
||||||
config.BaseURL = test.baseURL
|
config.BaseURL = test.baseURL
|
||||||
config.Nameserver = test.nameserver
|
|
||||||
|
|
||||||
p, err := NewDNSProviderConfig(config)
|
p, err := NewDNSProviderConfig(config)
|
||||||
|
|
||||||
|
|
|
@ -1,67 +0,0 @@
|
||||||
package shared
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"strconv"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/miekg/dns"
|
|
||||||
)
|
|
||||||
|
|
||||||
type DNSClient struct {
|
|
||||||
timeout time.Duration
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewDNSClient(timeout time.Duration) *DNSClient {
|
|
||||||
return &DNSClient{timeout: timeout}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d DNSClient) SOACall(fqdn, nameserver string) (*dns.SOA, error) {
|
|
||||||
m := new(dns.Msg)
|
|
||||||
m.SetQuestion(fqdn, dns.TypeSOA)
|
|
||||||
m.SetEdns0(4096, false)
|
|
||||||
|
|
||||||
in, err := d.sendDNSQuery(m, nameserver)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(in.Answer) == 0 {
|
|
||||||
if len(in.Ns) > 0 {
|
|
||||||
if soa, ok := in.Ns[0].(*dns.SOA); ok && fqdn != soa.Hdr.Name {
|
|
||||||
return d.SOACall(soa.Hdr.Name, nameserver)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil, fmt.Errorf("empty answer for %s in %s", fqdn, nameserver)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, rr := range in.Answer {
|
|
||||||
if soa, ok := rr.(*dns.SOA); ok {
|
|
||||||
return soa, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil, fmt.Errorf("SOA not found for %s in %s", fqdn, nameserver)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d DNSClient) sendDNSQuery(m *dns.Msg, ns string) (*dns.Msg, error) {
|
|
||||||
if ok, _ := strconv.ParseBool(os.Getenv("LEGO_EXPERIMENTAL_DNS_TCP_ONLY")); ok {
|
|
||||||
tcp := &dns.Client{Net: "tcp", Timeout: d.timeout}
|
|
||||||
in, _, err := tcp.Exchange(m, ns)
|
|
||||||
|
|
||||||
return in, err
|
|
||||||
}
|
|
||||||
|
|
||||||
udp := &dns.Client{Net: "udp", Timeout: d.timeout}
|
|
||||||
in, _, err := udp.Exchange(m, ns)
|
|
||||||
|
|
||||||
if in != nil && in.Truncated {
|
|
||||||
tcp := &dns.Client{Net: "tcp", Timeout: d.timeout}
|
|
||||||
// If the TCP request succeeds, the err will reset to nil
|
|
||||||
in, _, err = tcp.Exchange(m, ns)
|
|
||||||
}
|
|
||||||
|
|
||||||
return in, err
|
|
||||||
}
|
|
Loading…
Reference in a new issue