mirror of
https://github.com/caddyserver/caddy.git
synced 2025-12-08 06:09:53 +00:00
Merge f2a098e21a into 31960dc998
This commit is contained in:
commit
e0dfbeee7b
10 changed files with 546 additions and 1 deletions
|
|
@ -64,6 +64,7 @@ func init() {
|
||||||
RegisterGlobalOption("preferred_chains", parseOptPreferredChains)
|
RegisterGlobalOption("preferred_chains", parseOptPreferredChains)
|
||||||
RegisterGlobalOption("persist_config", parseOptPersistConfig)
|
RegisterGlobalOption("persist_config", parseOptPersistConfig)
|
||||||
RegisterGlobalOption("dns", parseOptDNS)
|
RegisterGlobalOption("dns", parseOptDNS)
|
||||||
|
RegisterGlobalOption("tls_resolvers", parseOptTLSResolvers)
|
||||||
RegisterGlobalOption("ech", parseOptECH)
|
RegisterGlobalOption("ech", parseOptECH)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -305,6 +306,15 @@ func parseOptSingleString(d *caddyfile.Dispenser, _ any) (any, error) {
|
||||||
return val, nil
|
return val, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func parseOptTLSResolvers(d *caddyfile.Dispenser, _ any) (any, error) {
|
||||||
|
d.Next() // consume option name
|
||||||
|
resolvers := d.RemainingArgs()
|
||||||
|
if len(resolvers) == 0 {
|
||||||
|
return nil, d.ArgErr()
|
||||||
|
}
|
||||||
|
return resolvers, nil
|
||||||
|
}
|
||||||
|
|
||||||
func parseOptDefaultBind(d *caddyfile.Dispenser, _ any) (any, error) {
|
func parseOptDefaultBind(d *caddyfile.Dispenser, _ any) (any, error) {
|
||||||
d.Next() // consume option name
|
d.Next() // consume option name
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,11 @@
|
||||||
package httpcaddyfile
|
package httpcaddyfile
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
|
"github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
|
||||||
|
"github.com/caddyserver/caddy/v2/modules/caddytls"
|
||||||
_ "github.com/caddyserver/caddy/v2/modules/logging"
|
_ "github.com/caddyserver/caddy/v2/modules/logging"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -62,3 +64,105 @@ func TestGlobalLogOptionSyntax(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGlobalResolversOption(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
input string
|
||||||
|
expectResolvers []string
|
||||||
|
expectError bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "single resolver",
|
||||||
|
input: `{
|
||||||
|
tls_resolvers 1.1.1.1
|
||||||
|
}
|
||||||
|
example.com {
|
||||||
|
}`,
|
||||||
|
expectResolvers: []string{"1.1.1.1"},
|
||||||
|
expectError: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "two resolvers",
|
||||||
|
input: `{
|
||||||
|
tls_resolvers 1.1.1.1 8.8.8.8
|
||||||
|
}
|
||||||
|
example.com {
|
||||||
|
}`,
|
||||||
|
expectResolvers: []string{"1.1.1.1", "8.8.8.8"},
|
||||||
|
expectError: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "multiple resolvers",
|
||||||
|
input: `{
|
||||||
|
tls_resolvers 1.1.1.1 8.8.8.8 9.9.9.9
|
||||||
|
}
|
||||||
|
example.com {
|
||||||
|
}`,
|
||||||
|
expectResolvers: []string{"1.1.1.1", "8.8.8.8", "9.9.9.9"},
|
||||||
|
expectError: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "no resolvers specified",
|
||||||
|
input: `{
|
||||||
|
}
|
||||||
|
example.com {
|
||||||
|
}`,
|
||||||
|
expectResolvers: nil,
|
||||||
|
expectError: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range tests {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
adapter := caddyfile.Adapter{
|
||||||
|
ServerType: ServerType{},
|
||||||
|
}
|
||||||
|
|
||||||
|
out, _, err := adapter.Adapt([]byte(tc.input), nil)
|
||||||
|
|
||||||
|
if (err != nil) != tc.expectError {
|
||||||
|
t.Errorf("error expectation failed. Expected error: %v, got: %v", tc.expectError, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if tc.expectError {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse the output JSON to check resolvers
|
||||||
|
var config struct {
|
||||||
|
Apps struct {
|
||||||
|
TLS *caddytls.TLS `json:"tls"`
|
||||||
|
} `json:"apps"`
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := json.Unmarshal(out, &config); err != nil {
|
||||||
|
t.Errorf("failed to unmarshal output: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if resolvers match expected
|
||||||
|
if config.Apps.TLS == nil {
|
||||||
|
if tc.expectResolvers != nil {
|
||||||
|
t.Errorf("Expected TLS config with resolvers %v, but TLS config is nil", tc.expectResolvers)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
actualResolvers := config.Apps.TLS.Resolvers
|
||||||
|
if len(tc.expectResolvers) == 0 && len(actualResolvers) == 0 {
|
||||||
|
return // Both empty, ok
|
||||||
|
}
|
||||||
|
if len(actualResolvers) != len(tc.expectResolvers) {
|
||||||
|
t.Errorf("Expected %d resolvers, got %d. Expected: %v, got: %v", len(tc.expectResolvers), len(actualResolvers), tc.expectResolvers, actualResolvers)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for j, expected := range tc.expectResolvers {
|
||||||
|
if actualResolvers[j] != expected {
|
||||||
|
t.Errorf("Resolver %d mismatch. Expected: %s, got: %s", j, expected, actualResolvers[j])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -362,6 +362,11 @@ func (st ServerType) buildTLSApp(
|
||||||
tlsApp.DNSRaw = caddyconfig.JSONModuleObject(globalDNS, "name", globalDNS.(caddy.Module).CaddyModule().ID.Name(), nil)
|
tlsApp.DNSRaw = caddyconfig.JSONModuleObject(globalDNS, "name", globalDNS.(caddy.Module).CaddyModule().ID.Name(), nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set up "global" (to the TLS app) DNS resolvers config
|
||||||
|
if globalResolvers, ok := options["tls_resolvers"]; ok && globalResolvers != nil {
|
||||||
|
tlsApp.Resolvers = globalResolvers.([]string)
|
||||||
|
}
|
||||||
|
|
||||||
// set up ECH from Caddyfile options
|
// set up ECH from Caddyfile options
|
||||||
if ech, ok := options["ech"].(*caddytls.ECH); ok {
|
if ech, ok := options["ech"].(*caddytls.ECH); ok {
|
||||||
tlsApp.EncryptedClientHello = ech
|
tlsApp.EncryptedClientHello = ech
|
||||||
|
|
@ -624,6 +629,15 @@ func fillInGlobalACMEDefaults(issuer certmagic.Issuer, options map[string]any) e
|
||||||
if globalCertLifetime != nil && acmeIssuer.CertificateLifetime == 0 {
|
if globalCertLifetime != nil && acmeIssuer.CertificateLifetime == 0 {
|
||||||
acmeIssuer.CertificateLifetime = globalCertLifetime.(caddy.Duration)
|
acmeIssuer.CertificateLifetime = globalCertLifetime.(caddy.Duration)
|
||||||
}
|
}
|
||||||
|
// apply global resolvers if DNS challenge is configured and resolvers are not already set
|
||||||
|
globalResolvers := options["tls_resolvers"]
|
||||||
|
if globalResolvers != nil && acmeIssuer.Challenges != nil && acmeIssuer.Challenges.DNS != nil {
|
||||||
|
// Check if DNS challenge is actually configured
|
||||||
|
hasDNSChallenge := globalACMEDNSok || acmeIssuer.Challenges.DNS.ProviderRaw != nil
|
||||||
|
if hasDNSChallenge && len(acmeIssuer.Challenges.DNS.Resolvers) == 0 {
|
||||||
|
acmeIssuer.Challenges.DNS.Resolvers = globalResolvers.([]string)
|
||||||
|
}
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,77 @@
|
||||||
|
{
|
||||||
|
email test@example.com
|
||||||
|
dns mock
|
||||||
|
tls_resolvers 1.1.1.1 8.8.8.8
|
||||||
|
acme_dns
|
||||||
|
}
|
||||||
|
|
||||||
|
example.com {
|
||||||
|
}
|
||||||
|
----------
|
||||||
|
{
|
||||||
|
"apps": {
|
||||||
|
"http": {
|
||||||
|
"servers": {
|
||||||
|
"srv0": {
|
||||||
|
"listen": [
|
||||||
|
":443"
|
||||||
|
],
|
||||||
|
"routes": [
|
||||||
|
{
|
||||||
|
"match": [
|
||||||
|
{
|
||||||
|
"host": [
|
||||||
|
"example.com"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"terminal": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tls": {
|
||||||
|
"automation": {
|
||||||
|
"policies": [
|
||||||
|
{
|
||||||
|
"issuers": [
|
||||||
|
{
|
||||||
|
"challenges": {
|
||||||
|
"dns": {
|
||||||
|
"resolvers": [
|
||||||
|
"1.1.1.1",
|
||||||
|
"8.8.8.8"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"email": "test@example.com",
|
||||||
|
"module": "acme"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ca": "https://acme.zerossl.com/v2/DV90",
|
||||||
|
"challenges": {
|
||||||
|
"dns": {
|
||||||
|
"resolvers": [
|
||||||
|
"1.1.1.1",
|
||||||
|
"8.8.8.8"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"email": "test@example.com",
|
||||||
|
"module": "acme"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"dns": {
|
||||||
|
"name": "mock"
|
||||||
|
},
|
||||||
|
"resolvers": [
|
||||||
|
"1.1.1.1",
|
||||||
|
"8.8.8.8"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
{
|
||||||
|
tls_resolvers 1.1.1.1 8.8.8.8
|
||||||
|
}
|
||||||
|
|
||||||
|
example.com {
|
||||||
|
}
|
||||||
|
----------
|
||||||
|
{
|
||||||
|
"apps": {
|
||||||
|
"http": {
|
||||||
|
"servers": {
|
||||||
|
"srv0": {
|
||||||
|
"listen": [
|
||||||
|
":443"
|
||||||
|
],
|
||||||
|
"routes": [
|
||||||
|
{
|
||||||
|
"match": [
|
||||||
|
{
|
||||||
|
"host": [
|
||||||
|
"example.com"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"terminal": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tls": {
|
||||||
|
"resolvers": [
|
||||||
|
"1.1.1.1",
|
||||||
|
"8.8.8.8"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,72 @@
|
||||||
|
{
|
||||||
|
email test@example.com
|
||||||
|
dns mock
|
||||||
|
tls_resolvers 1.1.1.1 8.8.8.8
|
||||||
|
}
|
||||||
|
|
||||||
|
example.com {
|
||||||
|
tls {
|
||||||
|
dns mock
|
||||||
|
}
|
||||||
|
}
|
||||||
|
----------
|
||||||
|
{
|
||||||
|
"apps": {
|
||||||
|
"http": {
|
||||||
|
"servers": {
|
||||||
|
"srv0": {
|
||||||
|
"listen": [
|
||||||
|
":443"
|
||||||
|
],
|
||||||
|
"routes": [
|
||||||
|
{
|
||||||
|
"match": [
|
||||||
|
{
|
||||||
|
"host": [
|
||||||
|
"example.com"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"terminal": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tls": {
|
||||||
|
"automation": {
|
||||||
|
"policies": [
|
||||||
|
{
|
||||||
|
"subjects": [
|
||||||
|
"example.com"
|
||||||
|
],
|
||||||
|
"issuers": [
|
||||||
|
{
|
||||||
|
"challenges": {
|
||||||
|
"dns": {
|
||||||
|
"provider": {
|
||||||
|
"name": "mock"
|
||||||
|
},
|
||||||
|
"resolvers": [
|
||||||
|
"1.1.1.1",
|
||||||
|
"8.8.8.8"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"email": "test@example.com",
|
||||||
|
"module": "acme"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"dns": {
|
||||||
|
"name": "mock"
|
||||||
|
},
|
||||||
|
"resolvers": [
|
||||||
|
"1.1.1.1",
|
||||||
|
"8.8.8.8"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,98 @@
|
||||||
|
{
|
||||||
|
email test@example.com
|
||||||
|
dns mock
|
||||||
|
tls_resolvers 1.1.1.1 8.8.8.8
|
||||||
|
acme_dns
|
||||||
|
}
|
||||||
|
|
||||||
|
example.com {
|
||||||
|
tls {
|
||||||
|
resolvers 9.9.9.9
|
||||||
|
}
|
||||||
|
}
|
||||||
|
----------
|
||||||
|
{
|
||||||
|
"apps": {
|
||||||
|
"http": {
|
||||||
|
"servers": {
|
||||||
|
"srv0": {
|
||||||
|
"listen": [
|
||||||
|
":443"
|
||||||
|
],
|
||||||
|
"routes": [
|
||||||
|
{
|
||||||
|
"match": [
|
||||||
|
{
|
||||||
|
"host": [
|
||||||
|
"example.com"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"terminal": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tls": {
|
||||||
|
"automation": {
|
||||||
|
"policies": [
|
||||||
|
{
|
||||||
|
"subjects": [
|
||||||
|
"example.com"
|
||||||
|
],
|
||||||
|
"issuers": [
|
||||||
|
{
|
||||||
|
"challenges": {
|
||||||
|
"dns": {
|
||||||
|
"resolvers": [
|
||||||
|
"9.9.9.9"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"email": "test@example.com",
|
||||||
|
"module": "acme"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"issuers": [
|
||||||
|
{
|
||||||
|
"challenges": {
|
||||||
|
"dns": {
|
||||||
|
"resolvers": [
|
||||||
|
"1.1.1.1",
|
||||||
|
"8.8.8.8"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"email": "test@example.com",
|
||||||
|
"module": "acme"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ca": "https://acme.zerossl.com/v2/DV90",
|
||||||
|
"challenges": {
|
||||||
|
"dns": {
|
||||||
|
"resolvers": [
|
||||||
|
"1.1.1.1",
|
||||||
|
"8.8.8.8"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"email": "test@example.com",
|
||||||
|
"module": "acme"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"dns": {
|
||||||
|
"name": "mock"
|
||||||
|
},
|
||||||
|
"resolvers": [
|
||||||
|
"1.1.1.1",
|
||||||
|
"8.8.8.8"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,112 @@
|
||||||
|
{
|
||||||
|
email test@example.com
|
||||||
|
dns mock
|
||||||
|
tls_resolvers 1.1.1.1 8.8.8.8
|
||||||
|
acme_dns
|
||||||
|
}
|
||||||
|
|
||||||
|
site1.example.com {
|
||||||
|
}
|
||||||
|
|
||||||
|
site2.example.com {
|
||||||
|
tls {
|
||||||
|
resolvers 9.9.9.9 8.8.4.4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
----------
|
||||||
|
{
|
||||||
|
"apps": {
|
||||||
|
"http": {
|
||||||
|
"servers": {
|
||||||
|
"srv0": {
|
||||||
|
"listen": [
|
||||||
|
":443"
|
||||||
|
],
|
||||||
|
"routes": [
|
||||||
|
{
|
||||||
|
"match": [
|
||||||
|
{
|
||||||
|
"host": [
|
||||||
|
"site1.example.com"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"terminal": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": [
|
||||||
|
{
|
||||||
|
"host": [
|
||||||
|
"site2.example.com"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"terminal": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tls": {
|
||||||
|
"automation": {
|
||||||
|
"policies": [
|
||||||
|
{
|
||||||
|
"subjects": [
|
||||||
|
"site2.example.com"
|
||||||
|
],
|
||||||
|
"issuers": [
|
||||||
|
{
|
||||||
|
"challenges": {
|
||||||
|
"dns": {
|
||||||
|
"resolvers": [
|
||||||
|
"9.9.9.9",
|
||||||
|
"8.8.4.4"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"email": "test@example.com",
|
||||||
|
"module": "acme"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"issuers": [
|
||||||
|
{
|
||||||
|
"challenges": {
|
||||||
|
"dns": {
|
||||||
|
"resolvers": [
|
||||||
|
"1.1.1.1",
|
||||||
|
"8.8.8.8"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"email": "test@example.com",
|
||||||
|
"module": "acme"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ca": "https://acme.zerossl.com/v2/DV90",
|
||||||
|
"challenges": {
|
||||||
|
"dns": {
|
||||||
|
"resolvers": [
|
||||||
|
"1.1.1.1",
|
||||||
|
"8.8.8.8"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"email": "test@example.com",
|
||||||
|
"module": "acme"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"dns": {
|
||||||
|
"name": "mock"
|
||||||
|
},
|
||||||
|
"resolvers": [
|
||||||
|
"1.1.1.1",
|
||||||
|
"8.8.8.8"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -40,6 +40,7 @@ import (
|
||||||
"github.com/caddyserver/caddy/v2"
|
"github.com/caddyserver/caddy/v2"
|
||||||
"github.com/caddyserver/caddy/v2/modules/caddyhttp"
|
"github.com/caddyserver/caddy/v2/modules/caddyhttp"
|
||||||
"github.com/caddyserver/caddy/v2/modules/caddypki"
|
"github.com/caddyserver/caddy/v2/modules/caddypki"
|
||||||
|
"github.com/caddyserver/caddy/v2/modules/caddytls"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
|
@ -287,7 +288,19 @@ func (ash Handler) openDatabase() (*db.AuthDB, error) {
|
||||||
// makeClient creates an ACME client which will use a custom
|
// makeClient creates an ACME client which will use a custom
|
||||||
// resolver instead of net.DefaultResolver.
|
// resolver instead of net.DefaultResolver.
|
||||||
func (ash Handler) makeClient() (acme.Client, error) {
|
func (ash Handler) makeClient() (acme.Client, error) {
|
||||||
for _, v := range ash.Resolvers {
|
// If no local resolvers are configured, check for global resolvers from TLS app
|
||||||
|
resolversToUse := ash.Resolvers
|
||||||
|
if len(resolversToUse) == 0 {
|
||||||
|
tlsAppIface, err := ash.ctx.App("tls")
|
||||||
|
if err == nil {
|
||||||
|
tlsApp := tlsAppIface.(*caddytls.TLS)
|
||||||
|
if len(tlsApp.Resolvers) > 0 {
|
||||||
|
resolversToUse = tlsApp.Resolvers
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, v := range resolversToUse {
|
||||||
addr, err := caddy.ParseNetworkAddressWithDefaults(v, "udp", 53)
|
addr, err := caddy.ParseNetworkAddressWithDefaults(v, "udp", 53)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
||||||
|
|
@ -125,6 +125,13 @@ type TLS struct {
|
||||||
DNSRaw json.RawMessage `json:"dns,omitempty" caddy:"namespace=dns.providers inline_key=name"`
|
DNSRaw json.RawMessage `json:"dns,omitempty" caddy:"namespace=dns.providers inline_key=name"`
|
||||||
dns any // technically, it should be any/all of the libdns interfaces (RecordSetter, RecordAppender, etc.)
|
dns any // technically, it should be any/all of the libdns interfaces (RecordSetter, RecordAppender, etc.)
|
||||||
|
|
||||||
|
// The default DNS resolvers to use for TLS-related DNS operations, specifically
|
||||||
|
// for ACME DNS challenges and ACME server DNS validations.
|
||||||
|
// If not specified, the system default resolvers will be used.
|
||||||
|
//
|
||||||
|
// EXPERIMENTAL: Subject to change.
|
||||||
|
Resolvers []string `json:"resolvers,omitempty"`
|
||||||
|
|
||||||
certificateLoaders []CertificateLoader
|
certificateLoaders []CertificateLoader
|
||||||
automateNames map[string]struct{}
|
automateNames map[string]struct{}
|
||||||
ctx caddy.Context
|
ctx caddy.Context
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue