diff --git a/.github/workflows/boulder-ci.yml b/.github/workflows/boulder-ci.yml index f5d17af36d5..ad910c17c63 100644 --- a/.github/workflows/boulder-ci.yml +++ b/.github/workflows/boulder-ci.yml @@ -36,7 +36,7 @@ jobs: matrix: # Add additional docker image tags here and all tests will be run with the additional image. BOULDER_TOOLS_TAG: - - go1.21.5_2023-12-05 + - go1.21.5_2023-12-07 # Tests command definitions. Use the entire "docker compose" command you want to run. tests: # Run ./test.sh --help for a description of each of the flags. diff --git a/bdns/dns.go b/bdns/dns.go index 7294ebd8b34..036bef67e28 100644 --- a/bdns/dns.go +++ b/bdns/dns.go @@ -2,10 +2,13 @@ package bdns import ( "context" + "crypto/tls" "encoding/base64" "errors" "fmt" + "io" "net" + "net/http" "strconv" "strings" "sync" @@ -15,6 +18,7 @@ import ( "github.com/miekg/dns" "github.com/prometheus/client_golang/prometheus" + "github.com/letsencrypt/boulder/features" blog "github.com/letsencrypt/boulder/log" "github.com/letsencrypt/boulder/metrics" ) @@ -175,6 +179,9 @@ type exchanger interface { // New constructs a new DNS resolver object that utilizes the // provided list of DNS servers for resolution. +// +// `tlsConfig` is the configuration used for outbound DoH queries, +// if applicable. func New( readTimeout time.Duration, servers ServerProvider, @@ -182,12 +189,26 @@ func New( clk clock.Clock, maxTries int, log blog.Logger, + tlsConfig *tls.Config, ) Client { - dnsClient := new(dns.Client) - - // Set timeout for underlying net.Conn - dnsClient.ReadTimeout = readTimeout - dnsClient.Net = "udp" + var client exchanger + if features.Enabled(features.DOH) { + client = &dohExchanger{ + clk: clk, + hc: http.Client{ + Timeout: readTimeout, + Transport: &http.Transport{ + TLSClientConfig: tlsConfig, + }, + }, + } + } else { + client = &dns.Client{ + // Set timeout for underlying net.Conn + ReadTimeout: readTimeout, + Net: "udp", + } + } queryTime := prometheus.NewHistogramVec( prometheus.HistogramOpts{ @@ -220,9 +241,8 @@ func New( []string{"qtype", "resolver"}, ) stats.MustRegister(queryTime, totalLookupTime, timeoutCounter, idMismatchCounter) - return &impl{ - dnsClient: dnsClient, + dnsClient: client, servers: servers, allowRestrictedAddresses: false, maxTries: maxTries, @@ -244,8 +264,10 @@ func NewTest( stats prometheus.Registerer, clk clock.Clock, maxTries int, - log blog.Logger) Client { - resolver := New(readTimeout, servers, stats, clk, maxTries, log) + log blog.Logger, + tlsConfig *tls.Config, +) Client { + resolver := New(readTimeout, servers, stats, clk, maxTries, log, tlsConfig) resolver.(*impl).allowRestrictedAddresses = true return resolver } @@ -619,3 +641,49 @@ func logDNSError( underlying) } } + +type dohExchanger struct { + clk clock.Clock + hc http.Client +} + +// Exchange sends a DoH query to the provided DoH server and returns the response. +func (d *dohExchanger) Exchange(query *dns.Msg, server string) (*dns.Msg, time.Duration, error) { + q, err := query.Pack() + if err != nil { + return nil, 0, err + } + + // The default Unbound URL template + url := fmt.Sprintf("https://%s/dns-query", server) + req, err := http.NewRequest("POST", url, strings.NewReader(string(q))) + if err != nil { + return nil, 0, err + } + req.Header.Set("Content-Type", "application/dns-message") + req.Header.Set("Accept", "application/dns-message") + + start := d.clk.Now() + resp, err := d.hc.Do(req) + if err != nil { + return nil, d.clk.Since(start), err + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + return nil, d.clk.Since(start), fmt.Errorf("doh: http status %d", resp.StatusCode) + } + + b, err := io.ReadAll(resp.Body) + if err != nil { + return nil, d.clk.Since(start), fmt.Errorf("doh: reading response body: %w", err) + } + + response := new(dns.Msg) + err = response.Unpack(b) + if err != nil { + return nil, d.clk.Since(start), fmt.Errorf("doh: unpacking response: %w", err) + } + + return response, d.clk.Since(start), nil +} diff --git a/bdns/dns_test.go b/bdns/dns_test.go index cdaf497e4dd..0d8af818fe3 100644 --- a/bdns/dns_test.go +++ b/bdns/dns_test.go @@ -248,7 +248,7 @@ func TestDNSNoServers(t *testing.T) { staticProvider, err := NewStaticProvider([]string{}) test.AssertNotError(t, err, "Got error creating StaticProvider") - obj := NewTest(time.Hour, staticProvider, metrics.NoopRegisterer, clock.NewFake(), 1, blog.UseMock()) + obj := NewTest(time.Hour, staticProvider, metrics.NoopRegisterer, clock.NewFake(), 1, blog.UseMock(), nil) _, err = obj.LookupHost(context.Background(), "letsencrypt.org") test.AssertError(t, err, "No servers") @@ -264,7 +264,7 @@ func TestDNSOneServer(t *testing.T) { staticProvider, err := NewStaticProvider([]string{dnsLoopbackAddr}) test.AssertNotError(t, err, "Got error creating StaticProvider") - obj := NewTest(time.Second*10, staticProvider, metrics.NoopRegisterer, clock.NewFake(), 1, blog.UseMock()) + obj := NewTest(time.Second*10, staticProvider, metrics.NoopRegisterer, clock.NewFake(), 1, blog.UseMock(), nil) _, err = obj.LookupHost(context.Background(), "cps.letsencrypt.org") @@ -275,7 +275,7 @@ func TestDNSDuplicateServers(t *testing.T) { staticProvider, err := NewStaticProvider([]string{dnsLoopbackAddr, dnsLoopbackAddr}) test.AssertNotError(t, err, "Got error creating StaticProvider") - obj := NewTest(time.Second*10, staticProvider, metrics.NoopRegisterer, clock.NewFake(), 1, blog.UseMock()) + obj := NewTest(time.Second*10, staticProvider, metrics.NoopRegisterer, clock.NewFake(), 1, blog.UseMock(), nil) _, err = obj.LookupHost(context.Background(), "cps.letsencrypt.org") @@ -286,7 +286,7 @@ func TestDNSServFail(t *testing.T) { staticProvider, err := NewStaticProvider([]string{dnsLoopbackAddr}) test.AssertNotError(t, err, "Got error creating StaticProvider") - obj := NewTest(time.Second*10, staticProvider, metrics.NoopRegisterer, clock.NewFake(), 1, blog.UseMock()) + obj := NewTest(time.Second*10, staticProvider, metrics.NoopRegisterer, clock.NewFake(), 1, blog.UseMock(), nil) bad := "servfail.com" _, err = obj.LookupTXT(context.Background(), bad) @@ -304,7 +304,7 @@ func TestDNSLookupTXT(t *testing.T) { staticProvider, err := NewStaticProvider([]string{dnsLoopbackAddr}) test.AssertNotError(t, err, "Got error creating StaticProvider") - obj := NewTest(time.Second*10, staticProvider, metrics.NoopRegisterer, clock.NewFake(), 1, blog.UseMock()) + obj := NewTest(time.Second*10, staticProvider, metrics.NoopRegisterer, clock.NewFake(), 1, blog.UseMock(), nil) a, err := obj.LookupTXT(context.Background(), "letsencrypt.org") t.Logf("A: %v", a) @@ -321,7 +321,7 @@ func TestDNSLookupHost(t *testing.T) { staticProvider, err := NewStaticProvider([]string{dnsLoopbackAddr}) test.AssertNotError(t, err, "Got error creating StaticProvider") - obj := NewTest(time.Second*10, staticProvider, metrics.NoopRegisterer, clock.NewFake(), 1, blog.UseMock()) + obj := NewTest(time.Second*10, staticProvider, metrics.NoopRegisterer, clock.NewFake(), 1, blog.UseMock(), nil) ip, err := obj.LookupHost(context.Background(), "servfail.com") t.Logf("servfail.com - IP: %s, Err: %s", ip, err) @@ -389,7 +389,7 @@ func TestDNSNXDOMAIN(t *testing.T) { staticProvider, err := NewStaticProvider([]string{dnsLoopbackAddr}) test.AssertNotError(t, err, "Got error creating StaticProvider") - obj := NewTest(time.Second*10, staticProvider, metrics.NoopRegisterer, clock.NewFake(), 1, blog.UseMock()) + obj := NewTest(time.Second*10, staticProvider, metrics.NoopRegisterer, clock.NewFake(), 1, blog.UseMock(), nil) hostname := "nxdomain.letsencrypt.org" _, err = obj.LookupHost(context.Background(), hostname) @@ -405,7 +405,7 @@ func TestDNSLookupCAA(t *testing.T) { staticProvider, err := NewStaticProvider([]string{dnsLoopbackAddr}) test.AssertNotError(t, err, "Got error creating StaticProvider") - obj := NewTest(time.Second*10, staticProvider, metrics.NoopRegisterer, clock.NewFake(), 1, blog.UseMock()) + obj := NewTest(time.Second*10, staticProvider, metrics.NoopRegisterer, clock.NewFake(), 1, blog.UseMock(), nil) removeIDExp := regexp.MustCompile(" id: [[:digit:]]+") caas, resp, err := obj.LookupCAA(context.Background(), "bracewel.net") @@ -639,7 +639,7 @@ func TestRetry(t *testing.T) { staticProvider, err := NewStaticProvider([]string{dnsLoopbackAddr}) test.AssertNotError(t, err, "Got error creating StaticProvider") - testClient := NewTest(time.Second*10, staticProvider, metrics.NoopRegisterer, clock.NewFake(), tc.maxTries, blog.UseMock()) + testClient := NewTest(time.Second*10, staticProvider, metrics.NoopRegisterer, clock.NewFake(), tc.maxTries, blog.UseMock(), nil) dr := testClient.(*impl) dr.dnsClient = tc.te _, err = dr.LookupTXT(context.Background(), "example.com") @@ -670,7 +670,7 @@ func TestRetry(t *testing.T) { staticProvider, err := NewStaticProvider([]string{dnsLoopbackAddr}) test.AssertNotError(t, err, "Got error creating StaticProvider") - testClient := NewTest(time.Second*10, staticProvider, metrics.NoopRegisterer, clock.NewFake(), 3, blog.UseMock()) + testClient := NewTest(time.Second*10, staticProvider, metrics.NoopRegisterer, clock.NewFake(), 3, blog.UseMock(), nil) dr := testClient.(*impl) dr.dnsClient = &testExchanger{errs: []error{isTempErr, isTempErr, nil}} ctx, cancel := context.WithCancel(context.Background()) @@ -774,7 +774,7 @@ func TestRotateServerOnErr(t *testing.T) { fmt.Println(staticProvider.servers) maxTries := 5 - client := NewTest(time.Second*10, staticProvider, metrics.NoopRegisterer, clock.NewFake(), maxTries, blog.UseMock()) + client := NewTest(time.Second*10, staticProvider, metrics.NoopRegisterer, clock.NewFake(), maxTries, blog.UseMock(), nil) // Configure a mock exchanger that will always return a retryable error for // servers A and B. This will force server "[2606:4700:4700::1111]:53" to do diff --git a/bdns/servers.go b/bdns/servers.go index 39f63ca7bd2..dd8edee9854 100644 --- a/bdns/servers.go +++ b/bdns/servers.go @@ -109,6 +109,8 @@ type dynamicProvider struct { // service is the service name to look up SRV records for within the domain. // If this field is left unspecified 'dns' will be used as the service name. service string + // proto is the IP protocol (tcp or udp) to look up SRV records for. + proto string // domain is the name to look up SRV records within. domain string // A map of IP addresses (results of A record lookups for SRV Targets) to @@ -174,7 +176,9 @@ var _ ServerProvider = &dynamicProvider{} // at refresh intervals and uses the resulting IP/port combos to populate the // list returned by Addrs. The update process ignores the Priority and Weight // attributes of the SRV records. -func StartDynamicProvider(c *cmd.DNSProvider, refresh time.Duration) (*dynamicProvider, error) { +// +// `proto` is the IP protocol (tcp or udp) to look up SRV records for. +func StartDynamicProvider(c *cmd.DNSProvider, refresh time.Duration, proto string) (*dynamicProvider, error) { if c.SRVLookup.Domain == "" { return nil, fmt.Errorf("'domain' cannot be empty") } @@ -200,6 +204,7 @@ func StartDynamicProvider(c *cmd.DNSProvider, refresh time.Duration) (*dynamicPr dp := dynamicProvider{ dnsAuthority: dnsAuthority, service: service, + proto: proto, domain: c.SRVLookup.Domain, addrs: make(map[string][]uint16), cancel: make(chan interface{}), @@ -263,9 +268,9 @@ func (dp *dynamicProvider) update() error { } // RFC 2782 formatted SRV record being queried e.g. "_service._proto.name." - record := fmt.Sprintf("_%s._udp.%s.", dp.service, dp.domain) + record := fmt.Sprintf("_%s._%s.%s.", dp.service, dp.proto, dp.domain) - _, srvs, err := resolver.LookupSRV(ctx, dp.service, "udp", dp.domain) + _, srvs, err := resolver.LookupSRV(ctx, dp.service, dp.proto, dp.domain) if err != nil { return fmt.Errorf("during SRV lookup of %q: %w", record, err) } diff --git a/cmd/boulder-va/main.go b/cmd/boulder-va/main.go index 4fd45ea2c8e..96910abcfb8 100644 --- a/cmd/boulder-va/main.go +++ b/cmd/boulder-va/main.go @@ -85,10 +85,17 @@ func main() { } var servers bdns.ServerProvider - servers, err = bdns.StartDynamicProvider(c.VA.DNSProvider, 60*time.Second) + proto := "udp" + if features.Enabled(features.DOH) { + proto = "tcp" + } + servers, err = bdns.StartDynamicProvider(c.VA.DNSProvider, 60*time.Second, proto) cmd.FailOnError(err, "Couldn't start dynamic DNS server resolver") defer servers.Stop() + tlsConfig, err := c.VA.TLS.Load(scope) + cmd.FailOnError(err, "tlsConfig config") + var resolver bdns.Client if !c.VA.DNSAllowLoopbackAddresses { resolver = bdns.New( @@ -97,7 +104,8 @@ func main() { scope, clk, dnsTries, - logger) + logger, + tlsConfig) } else { resolver = bdns.NewTest( c.VA.DNSTimeout.Duration, @@ -105,12 +113,10 @@ func main() { scope, clk, dnsTries, - logger) + logger, + tlsConfig) } - tlsConfig, err := c.VA.TLS.Load(scope) - cmd.FailOnError(err, "tlsConfig config") - var remotes []va.RemoteVA if len(c.VA.RemoteVAs) > 0 { for _, rva := range c.VA.RemoteVAs { diff --git a/features/featureflag_string.go b/features/featureflag_string.go index 022e6bcadb1..344567aa035 100644 --- a/features/featureflag_string.go +++ b/features/featureflag_string.go @@ -29,11 +29,12 @@ func _() { _ = x[AllowNoCommonName-18] _ = x[CAAAfterValidation-19] _ = x[SHA256SubjectKeyIdentifier-20] + _ = x[DOH-21] } -const _FeatureFlag_name = "unusedStoreRevokerInfoROCSPStage6ROCSPStage7StoreLintingCertificateInsteadOfPrecertificateCAAValidationMethodsCAAAccountURILeaseCRLShardsEnforceMultiVAMultiVAFullResultsECDSAForAllServeRenewalInfoAllowUnrecognizedFeaturesExpirationMailerUsesJoinCertCheckerChecksValidationsCertCheckerRequiresValidationsCertCheckerRequiresCorrespondenceAsyncFinalizeAllowNoCommonNameCAAAfterValidationSHA256SubjectKeyIdentifier" +const _FeatureFlag_name = "unusedStoreRevokerInfoROCSPStage6ROCSPStage7StoreLintingCertificateInsteadOfPrecertificateCAAValidationMethodsCAAAccountURILeaseCRLShardsEnforceMultiVAMultiVAFullResultsECDSAForAllServeRenewalInfoAllowUnrecognizedFeaturesExpirationMailerUsesJoinCertCheckerChecksValidationsCertCheckerRequiresValidationsCertCheckerRequiresCorrespondenceAsyncFinalizeAllowNoCommonNameCAAAfterValidationSHA256SubjectKeyIdentifierDOH" -var _FeatureFlag_index = [...]uint16{0, 6, 22, 33, 44, 90, 110, 123, 137, 151, 169, 180, 196, 221, 245, 273, 303, 336, 349, 366, 384, 410} +var _FeatureFlag_index = [...]uint16{0, 6, 22, 33, 44, 90, 110, 123, 137, 151, 169, 180, 196, 221, 245, 273, 303, 336, 349, 366, 384, 410, 413} func (i FeatureFlag) String() string { if i < 0 || i >= FeatureFlag(len(_FeatureFlag_index)-1) { diff --git a/features/features.go b/features/features.go index 8839c214917..2e92993a264 100644 --- a/features/features.go +++ b/features/features.go @@ -86,11 +86,15 @@ const ( // compliant truncated SHA256 Subject Key Identifier in end-entity // certificates. SHA256SubjectKeyIdentifier + + // DOH enables DNS-over-HTTPS queries for validation + DOH ) // List of features and their default value, protected by fMu var features = map[FeatureFlag]bool{ unused: false, + DOH: false, CAAValidationMethods: false, CAAAccountURI: false, EnforceMultiVA: false, diff --git a/test/boulder-tools/install-go.sh b/test/boulder-tools/install-go.sh index 8d6ab174cf0..422ec34e125 100755 --- a/test/boulder-tools/install-go.sh +++ b/test/boulder-tools/install-go.sh @@ -19,7 +19,7 @@ go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28.0 go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2.0 go install github.com/rubenv/sql-migrate/sql-migrate@v1.1.2 go install golang.org/x/tools/cmd/stringer@latest -go install github.com/letsencrypt/pebble/cmd/pebble-challtestsrv@master +go install github.com/letsencrypt/pebble/v2/cmd/pebble-challtestsrv@66511d8 go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.53.3 go install honnef.co/go/tools/cmd/staticcheck@2023.1.5 diff --git a/test/config-next/va-remote-a.json b/test/config-next/va-remote-a.json index 71b7869b5e5..160903406c1 100644 --- a/test/config-next/va-remote-a.json +++ b/test/config-next/va-remote-a.json @@ -5,7 +5,7 @@ "dnsProvider": { "dnsAuthority": "consul.service.consul", "srvLookup": { - "service": "dns", + "service": "doh", "domain": "service.consul" } }, @@ -33,7 +33,8 @@ } }, "features": { - "CAAAfterValidation": true + "CAAAfterValidation": true, + "DOH": true }, "accountURIPrefixes": [ "http://boulder.service.consul:4000/acme/reg/", diff --git a/test/config-next/va-remote-b.json b/test/config-next/va-remote-b.json index bd1ac7ac94d..6768225a512 100644 --- a/test/config-next/va-remote-b.json +++ b/test/config-next/va-remote-b.json @@ -5,7 +5,7 @@ "dnsProvider": { "dnsAuthority": "consul.service.consul", "srvLookup": { - "service": "dns", + "service": "doh", "domain": "service.consul" } }, @@ -33,7 +33,8 @@ } }, "features": { - "CAAAfterValidation": true + "CAAAfterValidation": true, + "DOH": true }, "accountURIPrefixes": [ "http://boulder.service.consul:4000/acme/reg/", diff --git a/test/config-next/va.json b/test/config-next/va.json index 82f13f909e8..af9733a8d69 100644 --- a/test/config-next/va.json +++ b/test/config-next/va.json @@ -5,7 +5,7 @@ "dnsProvider": { "dnsAuthority": "consul.service.consul", "srvLookup": { - "service": "dns", + "service": "doh", "domain": "service.consul" } }, @@ -40,7 +40,8 @@ "features": { "EnforceMultiVA": true, "MultiVAFullResults": true, - "CAAAfterValidation": true + "CAAAfterValidation": true, + "DOH": true }, "remoteVAs": [ { diff --git a/test/consul/config.hcl b/test/consul/config.hcl index f1dbb0f6623..00a6d5e32ca 100644 --- a/test/consul/config.hcl +++ b/test/consul/config.hcl @@ -115,6 +115,22 @@ services { tags = ["udp"] // Required for SRV RR support in VA RVA. } +services { + id = "doh-a" + name = "doh" + address = "10.77.77.77" + port = 8443 + tags = ["tcp"] +} + +services { + id = "doh-b" + name = "doh" + address = "10.88.88.88" + port = 8443 + tags = ["tcp"] +} + services { id = "nonce-a" name = "nonce" diff --git a/test/grpc-creds/10.77.77.77/cert.pem b/test/grpc-creds/10.77.77.77/cert.pem new file mode 100644 index 00000000000..12804efa3b7 --- /dev/null +++ b/test/grpc-creds/10.77.77.77/cert.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDDjCCAfagAwIBAgIIQbFdR2fXsHswDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE +AxMVbWluaWNhIHJvb3QgY2EgM2I4YjJjMB4XDTIzMTIwODE4MDkzMloXDTI2MDEw +NzE4MDkzMlowFjEUMBIGA1UEAxMLMTAuNzcuNzcuNzcwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQCrE64Z4Yh4E6aQ1zQiNgCvW5LWBI9yZZybZxLV5J1C +yMtpgY3YsCPZ/6JUI4SvabenU5Pa3T407eHjmDCRNce04j4BE6e7psPjRa7hvI2A ++IvLB7eiaCnE+sdAMFsLxraWwTu67tmeRxYxWScMpULlFren3HNNqmtAN3a4yGy5 +y2pHMgCnOSE9R53tuF2uqJ8BRW44VLDt4kZ9hwm0dW8EJY8MBCACPGtW2YwBG/5E +zrRKDWSBl9g3mYOwgRdxUMV1h0eVr/llVFb+/UZCLUb5zq/zKKEkYOT4Ihr7wtin +ahLwwVwdUsMNE9NzljMC/aIR74qhBeN2xAJ3ZZQKrqL1AgMBAAGjVjBUMA4GA1Ud +DwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0T +AQH/BAIwADAVBgNVHREEDjAMhwQKTU1NhwQKWFhYMA0GCSqGSIb3DQEBCwUAA4IB +AQCOa5b+zRgQBhlPWiC04K5C/Ys3dUtqKhKrWvPIiraNi792X/T5t1ZL9liV9A6n +b10hHcCDIfyRFIJRyE8G2fyzqNlGwCr8J6puWrg4wMPt8q+6a4r2ZqaXm3aQTfGs +4Tgxz10gOVimeiUshVyrpaceyiboOKxJbBRuLNTTK9Jp74fWRd+F8KAINWN+SpF4 +6ggzXNiPYZZTBPGeAOMyf0rnf7CWAbw017uHhCiykJkMy8sZJcmQF49gDZTIN9pt +eI0SeB4ku5lgAOunqrTGyPLeVaevtcU//TdATuukhnCFes6vt/6yC+sWQEhEQw7P +y2Kp8T8KcOlTeKr8Cb07B2M0 +-----END CERTIFICATE----- diff --git a/test/grpc-creds/10.77.77.77/key.pem b/test/grpc-creds/10.77.77.77/key.pem new file mode 100644 index 00000000000..30a8d2135a4 --- /dev/null +++ b/test/grpc-creds/10.77.77.77/key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAqxOuGeGIeBOmkNc0IjYAr1uS1gSPcmWcm2cS1eSdQsjLaYGN +2LAj2f+iVCOEr2m3p1OT2t0+NO3h45gwkTXHtOI+AROnu6bD40Wu4byNgPiLywe3 +omgpxPrHQDBbC8a2lsE7uu7ZnkcWMVknDKVC5Ra3p9xzTaprQDd2uMhsuctqRzIA +pzkhPUed7bhdrqifAUVuOFSw7eJGfYcJtHVvBCWPDAQgAjxrVtmMARv+RM60Sg1k +gZfYN5mDsIEXcVDFdYdHla/5ZVRW/v1GQi1G+c6v8yihJGDk+CIa+8LYp2oS8MFc +HVLDDRPTc5YzAv2iEe+KoQXjdsQCd2WUCq6i9QIDAQABAoIBACgZH8ifLT5/1J3E +Y0rVf4manCsfvIOiv3dJTIfn4thhehQLsrSkbHLPUTwJazM2Qz6r/07gZpE/ZJ/U +7yVKBromAUR9V+ZK60Uc8yWj7ULafuGiuG8PnSK3aPZpnx1+gROKzTY+f7FylggR +Dm8PWUOa9Icay8fbdvIBTgl3qMxPOCgLyXNXNJHcKIPb71L1T5EL2H9Z5vHF9tFy +TnbpeK0GlmBHIeseVaFzruin3sqxjRftVEgTL5XhTq/9uY3EUutq8SGRoidbpp/+ +cr0I1IpFcrJVmJHKdfJkdRI2u3LtMKS3bpqJU7MKn1DRzvQatdSQwn/V8wU3iG8o +04dus60CgYEA3IBOLJRfMFgj6LbMSySoP8JIzVvnBHIMXGd7mzuYUlV2GjVO5oD2 +nh4Q3eGDT2TZ1GbaGGHLhpCXIx87oSXHZz+vw+sDh+WHEApLKZMRZLMxAbNcsPQL +fhcmaQVkfxaV78rrt8TYuLDIU//bOTwGJ48Maj92RT1z5hOOiBkdQe8CgYEAxp5p +Au9kiJFEIgHVtEN+1qHfnwZJI0xOkDfsd+a1J6PZLimHAfiYETAHfJq1cMC4Mt/G +4l/WDqwcWXI/9A/gN7NRv0miQ+tDyVHntohaGoU+0hm6QfXag6VloWs/X8mlzCeu +46AXAni4lbW9nNWwImEL1uSC/Oo5vB45OpHR/VsCgYAivfyTPZV58olF43dw54ey +9BOwd6iApM+Zx5xMKymm31xKaNfTrcIty6LwstWTrto7gzEd4lrFCwclO4iTrXYr +qHczMVZPFTUgq96H4Go/KZSxJeeW4fzlkxQ0O+tHsvFQ5PIa9GMJRqFpyshpzjFS +DlHwc6tY4YPfXnl4rCxV9QKBgAsrwbA+kqLzuKdI/yICYdHkjNU+30Iy+oA2BQDB +YxL1rjNgdo1v0+2zi9hAQ1AyJqoF2APHbByrJXUKbfpmIjA/z6s4kv3K76cVCjlD +9f1j3SKn+8fV8hJRbSPlCk1y4/ZVjQqUaHblH0ycSivWAPAOEUJm288pxVGFSaa3 +qN3dAoGBAIGSn1PSjIVqypCQBBydedS4WDjqwkLoL0bOOZRLxgk+dtfD2l8wKqWp +Helyqym23d58QPb0ZwMU3g/0pZXDqX+w+bnUvAvjfADmFNe6T1nWYiu9Mn5YHAyO +G5s2aHfB8aSIqQSRASlWgFEmftfpuapRGAmOyZr2JYZuaELkvPmP +-----END RSA PRIVATE KEY----- diff --git a/test/grpc-creds/generate.sh b/test/grpc-creds/generate.sh index 64983455d54..24c5fe09d45 100755 --- a/test/grpc-creds/generate.sh +++ b/test/grpc-creds/generate.sh @@ -21,5 +21,7 @@ for SERVICE in publisher nonce ra ca sa va rva ; do minica -domains "${SERVICE}.boulder,${SERVICE}1.boulder,${SERVICE}2.boulder" done +minica -ip-addresses 10.77.77.77,10.88.88.88 + # minica sets restrictive directory permissions, but we don't want that chmod -R go+rX . diff --git a/test/startservers.py b/test/startservers.py index b5fc7343999..02c92cfba69 100644 --- a/test/startservers.py +++ b/test/startservers.py @@ -258,6 +258,9 @@ def startChallSrv(): '--defaultIPv4', os.environ.get("FAKE_DNS"), '-defaultIPv6', '', '--dns01', ':8053,:8054', + '--doh', '10.77.77.77:8443,10.88.88.88:8443', + '--doh-cert', 'test/grpc-creds/10.77.77.77/cert.pem', + '--doh-cert-key', 'test/grpc-creds/10.77.77.77/key.pem', '--management', ':8055', '--http01', '10.77.77.77:80', '-https01', '10.77.77.77:443', diff --git a/va/dns_test.go b/va/dns_test.go index ed714532366..704a6bc2c70 100644 --- a/va/dns_test.go +++ b/va/dns_test.go @@ -145,7 +145,8 @@ func TestDNSValidationNoServer(t *testing.T) { metrics.NoopRegisterer, clock.New(), 1, - log) + log, + nil) _, prob := va.validateChallenge(ctx, dnsi("localhost"), dnsChallenge())