Skip to content

Commit 5ffe139

Browse files
committed
feat(gateway)!: remove hardcoded defaultResolvers for .eth and .crypto
remove implicit DNS-over-HTTPS resolvers that were difficult to discover, override, or disable, improving user agency and configuration transparency - remove defaultResolvers map from gateway.NewDNSResolver - NewDNSResolver(nil) now uses system DNS only (no implicit DoH) - add autoconf.Client.ExpandDNSResolvers() convenience method for applications needing network-specific DNS resolver expansion - update test to use .foo instead of .eth TLD users needing DoH for non-ICANN TLDs should either pass explicit resolvers or use autoconf.ExpandDNSResolvers() to merge network defaults with custom resolvers Closes #771 Closes #772
1 parent 4c0aa3a commit 5ffe139

File tree

4 files changed

+49
-32
lines changed

4 files changed

+49
-32
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ The following emojis are used to highlight certain changes:
2525
- Added `Config.DiagnosticServiceURL` to configure a CID retrievability diagnostic service. When set, 504 Gateway Timeout errors show a "Check CID retrievability" button linking to the service with `?cid=<failed-cid>` [#1023](https://github.com/ipfs/boxo/pull/1023)
2626
- Improved 504 error pages with "Retry" button, diagnostic service integration, and clear indication when timeout occurs on sub-resource vs root CID [#1023](https://github.com/ipfs/boxo/pull/1023)
2727
- `gateway`: Added `Config.MaxRangeRequestFileSize` to protect against CDN issues with large file range requests. When set to a non-zero value, range requests for files larger than this limit return HTTP 501 Not Implemented with a suggestion to use verifiable block requests (`application/vnd.ipld.raw`) instead. This provides protection against Cloudflare's issue where range requests for files over 5GiB are silently ignored, causing excess bandwidth consumption and billing
28+
- `autoconf`: Added `Client.ExpandDNSResolvers()` convenience method for expanding DNS resolver maps with autoconf data ([#771](https://github.com/ipfs/boxo/issues/771), [#772](https://github.com/ipfs/boxo/issues/772))
2829

2930
### Changed
3031

@@ -45,6 +46,14 @@ The following emojis are used to highlight certain changes:
4546

4647
### Removed
4748

49+
- `gateway`: 🛠 Removed hardcoded `defaultResolvers` for `.eth` and `.crypto` TLDs from `gateway.NewDNSResolver` ([#771](https://github.com/ipfs/boxo/issues/771), [#772](https://github.com/ipfs/boxo/issues/772))
50+
- This change removes implicit defaults that were difficult to discover, override, or disable, improving user agency and configuration transparency
51+
- `NewDNSResolver(nil)` now uses system DNS only (no implicit DoH resolvers)
52+
- Users needing DNS-over-HTTPS for non-ICANN TLDs should either:
53+
- Pass explicit resolvers: `NewDNSResolver(map[string]string{"eth.": "https://dns.eth.limo/dns-query"})`
54+
- Use `autoconf.ExpandDNSResolvers()` to merge network defaults with custom resolvers
55+
- Use `autoconf.Client.ExpandDNSResolvers()` for convenience in long-running applications
56+
4857
### Fixed
4958

5059
- `routing/http/client`:

autoconf/fetch.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -603,3 +603,32 @@ func calculateEffectiveRefreshInterval(userInterval time.Duration, cacheTTLSecon
603603
serverTTL := time.Duration(cacheTTLSeconds) * time.Second
604604
return min(serverTTL, userInterval)
605605
}
606+
607+
// ExpandDNSResolvers expands DNS resolvers with "auto" placeholders using cached autoconf data.
608+
// This is a convenience method for applications that need to construct DNS resolvers.
609+
//
610+
// The customResolvers parameter is a map of domain patterns to DNS resolver URLs,
611+
// where values can be "auto" to use autoconf-provided resolvers. If nil or empty,
612+
// only autoconf resolvers will be returned.
613+
//
614+
// Returns a map ready to be passed to gateway.NewDNSResolver().
615+
//
616+
// Example:
617+
//
618+
// client, _ := autoconf.NewClient()
619+
//
620+
// // Apply all autoconf DNS resolvers
621+
// resolvers := client.ExpandDNSResolvers(map[string]string{
622+
// ".": "auto",
623+
// })
624+
//
625+
// // Mix autoconf with custom resolvers
626+
// resolvers = client.ExpandDNSResolvers(map[string]string{
627+
// "eth.": "auto",
628+
// "example.": "https://dns.example.com/dns-query",
629+
// })
630+
//
631+
// dnsResolver, _ := gateway.NewDNSResolver(resolvers)
632+
func (c *Client) ExpandDNSResolvers(customResolvers map[string]string) map[string]string {
633+
return ExpandDNSResolvers(customResolvers, c.GetCached())
634+
}

gateway/dns.go

Lines changed: 8 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,6 @@ import (
99
madns "github.com/multiformats/go-multiaddr-dns"
1010
)
1111

12-
var defaultResolvers = map[string]string{
13-
"eth.": "https://dns.eth.limo/dns-query",
14-
"crypto.": "https://resolver.unstoppable.io/dns-query",
15-
}
16-
1712
func newResolver(url string, opts ...doh.Option) (madns.BasicResolver, error) {
1813
if !strings.HasPrefix(url, "https://") && !strings.HasPrefix(url, "http://") {
1914
return nil, fmt.Errorf("invalid DoH resolver URL: %s", url)
@@ -22,13 +17,18 @@ func newResolver(url string, opts ...doh.Option) (madns.BasicResolver, error) {
2217
return doh.NewResolver(url, opts...)
2318
}
2419

25-
// NewDNSResolver creates a new DNS resolver based on the default resolvers and
26-
// the provided resolvers.
20+
// NewDNSResolver creates a new DNS resolver based on the provided resolvers.
2721
//
2822
// The argument 'resolvers' is a map of [FQDNs] to URLs for custom DNS resolution.
2923
// URLs starting with "https://" indicate [DoH] endpoints. Support for other resolver
3024
// types may be added in the future.
3125
//
26+
// If 'resolvers' is nil or empty, the default system DNS resolver will be used.
27+
//
28+
// To use network-specific DNS resolvers (e.g., for .eth or other non-ICANN TLDs),
29+
// use [boxo/autoconf.ExpandDNSResolvers] to merge autoconf-provided resolvers with
30+
// custom resolvers before calling this function.
31+
//
3232
// Example:
3333
// - Custom resolver for ENS: "eth." → "https://eth.link/dns-query"
3434
// - Override the default OS resolver: "." → "https://doh.applied-privacy.net/query"
@@ -39,17 +39,15 @@ func NewDNSResolver(resolvers map[string]string, dohOpts ...doh.Option) (*madns.
3939
var opts []madns.Option
4040
var err error
4141

42-
domains := make(map[string]struct{}) // to track overridden default resolvers
4342
rslvrs := make(map[string]madns.BasicResolver) // to reuse resolvers for the same URL
4443

4544
for domain, url := range resolvers {
4645
if domain != "." && !dns.IsFqdn(domain) {
4746
return nil, fmt.Errorf("invalid domain %s; must be FQDN", domain)
4847
}
4948

50-
domains[domain] = struct{}{}
5149
if url == "" {
52-
// allow overriding of implicit defaults with the default resolver
50+
// allow clearing resolver for a domain
5351
continue
5452
}
5553

@@ -69,24 +67,5 @@ func NewDNSResolver(resolvers map[string]string, dohOpts ...doh.Option) (*madns.
6967
}
7068
}
7169

72-
// fill in defaults if not overridden by the user
73-
for domain, url := range defaultResolvers {
74-
_, ok := domains[domain]
75-
if ok {
76-
continue
77-
}
78-
79-
rslv, ok := rslvrs[url]
80-
if !ok {
81-
rslv, err = newResolver(url)
82-
if err != nil {
83-
return nil, fmt.Errorf("bad resolver for %s: %w", domain, err)
84-
}
85-
rslvrs[url] = rslv
86-
}
87-
88-
opts = append(opts, madns.WithDomainResolver(domain, rslv))
89-
}
90-
9170
return madns.NewResolver(opts...)
9271
}

gateway/dns_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ func TestAddNewDNSResolver(t *testing.T) {
4141
require.Equal(t, dnslinkValue, res[0])
4242
}
4343

44-
func TestOverrideDNSDefaults(t *testing.T) {
44+
func TestCustomDNSResolver(t *testing.T) {
4545
ctx := context.Background()
4646
ctx, cancel := context.WithCancel(ctx)
4747
defer cancel()
@@ -50,7 +50,7 @@ func TestOverrideDNSDefaults(t *testing.T) {
5050
require.NoError(t, err)
5151
defer l.Close()
5252

53-
dnslinkName := "dnslink-test.eth"
53+
dnslinkName := "dnslink-test.foo"
5454
dnslinkValue := "dnslink=/ipfs/bafkqaaa"
5555

5656
go func() {
@@ -59,7 +59,7 @@ func TestOverrideDNSDefaults(t *testing.T) {
5959

6060
listenAddr := l.Addr().(*net.TCPAddr)
6161
r, err := NewDNSResolver(map[string]string{
62-
"eth.": fmt.Sprintf("http://%s:%d", listenAddr.IP, listenAddr.Port),
62+
"foo.": fmt.Sprintf("http://%s:%d", listenAddr.IP, listenAddr.Port),
6363
})
6464
require.NoError(t, err)
6565

0 commit comments

Comments
 (0)