Skip to content

Commit

Permalink
change(doh): hardcoded DoH host to ip resolution
Browse files Browse the repository at this point in the history
- Define IPv4 and/or IPv6 addresses for each DoH server
- No "self DNS" anymore (no DoT or plaintext DNS to resolve DoH host)
- Add `DOH_IP_VERSION` variable
- Warner field removed from ResolverSettings
- SelfDNS struct field removed from ResolverSettings
- IPv6 bool pointer field added to ResolverSettings
  • Loading branch information
qdm12 committed Nov 24, 2023
1 parent 546e124 commit dbdfdb6
Show file tree
Hide file tree
Showing 35 changed files with 448 additions and 200 deletions.
2 changes: 1 addition & 1 deletion .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ issues:
source: "^//go:generate "
- linters:
- lll
source: "^\\t+(defaultDNSIPv6AddrPort|defaultDoTIPv6AddrPort)\\(.+\\),$"
source: "^\\t+(defaultDNSIPv6AddrPort|defaultDoTIPv6AddrPort|netip.AddrFrom16)\\(.+\\),$"
- linters:
- ireturn
text: ".+returns interface \\(github\\.com\\/prometheus\\/client_golang\\/prometheus\\.[a-zA-Z]+\\)$"
Expand Down
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ ENV \
CACHE_TYPE=lru \
CACHE_LRU_MAX_ENTRIES=10000 \
DOT_CONNECT_IPV6=off \
DOH_IP_VERSION=ipv4 \
BLOCK_MALICIOUS=on \
BLOCK_SURVEILLANCE=off \
BLOCK_ADS=off \
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ If you're running Kubernetes, there is a separate article on [how to set up K8s]
| `REBINDING_PROTECTION` | `on` | `on` or `off`. Enabling will prevent the server from returning any private IP address to the client. |
| `CHECK_DNS` | `on` | `on` or `off`. Check resolving github.com using `127.0.0.1:53` at start |
| `DOT_CONNECT_IPV6` | `off` | `on` or `off`. Connects to the DNS resolvers over IPv6 instead of IPv4 |
| `DOH_IP_VERSION` | `ipv4` | `ipv4` or `ipv6`. Connects to the DNS upstream servers only over IPv4 addresses or only over IPv6 addresses |
| `UPDATE_PERIOD` | `24h` | Period to update block lists and restart Unbound. Set to `0` to disable. |

## Migrate
Expand Down
35 changes: 12 additions & 23 deletions internal/config/doh.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,23 @@ import (
"github.com/qdm12/dns/v2/pkg/provider"
"github.com/qdm12/gosettings"
"github.com/qdm12/gosettings/reader"
"github.com/qdm12/gosettings/validate"
"github.com/qdm12/gotree"
)

type DoH struct {
DoHProviders []string
IPVersion string
Timeout time.Duration
Self DoT
}

func (d *DoH) setDefaults() {
d.DoHProviders = gosettings.DefaultSlice(d.DoHProviders, []string{
provider.Cloudflare().Name,
provider.Google().Name,
})
d.IPVersion = gosettings.DefaultComparable(d.IPVersion, "ipv4")
d.Timeout = gosettings.DefaultComparable(d.Timeout, time.Second)
d.Self.setDefaults()
}

func (d *DoH) validate() (err error) {
Expand All @@ -31,17 +32,17 @@ func (d *DoH) validate() (err error) {
return fmt.Errorf("DoH provider: %w", err)
}

err = validate.IsOneOf(d.IPVersion, "ipv4", "ipv6")
if err != nil {
return fmt.Errorf("IP version: %w", err)
}

const minTimeout = time.Millisecond
if d.Timeout < minTimeout {
return fmt.Errorf("%w: %s must be at least %s",
ErrTimeoutTooSmall, d.Timeout, minTimeout)
}

err = d.Self.validate()
if err != nil {
return fmt.Errorf("self dns: %w", err)
}

return nil
}

Expand All @@ -53,29 +54,17 @@ func (d *DoH) ToLinesNode() (node *gotree.Node) {
node = gotree.New("DNS over HTTPs:")

node.Appendf("DNS over HTTPs providers: %s", andStrings(d.DoHProviders))

node.Appendf("Request timeout: %s", d.Timeout)

node.AppendNode(d.Self.ToLinesNode())
node.Appendf("Connecting over %s", d.IPVersion)
node.Appendf("Query timeout: %s", d.Timeout)

return node
}

func (d *DoH) read(reader *reader.Reader) (err error) {
d.DoHProviders = reader.CSV("DOH_RESOLVERS")
d.Timeout, err = reader.Duration("DOH_TIMEOUT")
if err != nil {
return err
}

d.Self.DoTProviders = reader.CSV("DOT_RESOLVERS")
d.Self.DNSProviders = reader.CSV("DNS_FALLBACK_PLAINTEXT_RESOLVERS")
d.Self.IPv6, err = reader.BoolPtr("DOT_CONNECT_IPV6")
if err != nil {
return err
}
d.IPVersion = reader.String("DOH_IP_VERSION")

d.Self.Timeout, err = reader.Duration("DOT_TIMEOUT")
d.Timeout, err = reader.Duration("DOH_TIMEOUT")
if err != nil {
return err
}
Expand Down
4 changes: 2 additions & 2 deletions internal/config/outdated.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ func checkOutdatedEnv(reader *reader.Reader) (warnings []string) {
"PROVIDERS": {"DOT_RESOLVERS", "DOH_RESOLVERS", "DNS_FALLBACK_PLAINTEXT_RESOLVERS"},
"PROVIDER": {"DOT_RESOLVERS", "DOH_RESOLVERS", "DNS_FALLBACK_PLAINTEXT_RESOLVERS"},
"CACHING": {"CACHE_TYPE"},
"IPV4": {"DOT_CONNECT_IPV6"},
"IPV6": {"DOT_CONNECT_IPV6"},
"IPV4": {"DOT_CONNECT_IPV6", "DOH_IP_VERSION"},
"IPV6": {"DOT_CONNECT_IPV6", "DOH_IP_VERSION"},
"UNBLOCK": {"ALLOWED_HOSTNAMES"},
"PRIVATE_ADDRESS": {"REBINDING_PROTECTION"},
"CHECK_UNBOUND": {"CHECK_DNS"},
Expand Down
20 changes: 2 additions & 18 deletions internal/setup/doh.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,26 +22,10 @@ func dohServer(userSettings config.Settings,
return nil, fmt.Errorf("DNS over HTTPS providers: %w", err)
}

selfDoTProviders, err := stringsToProviders(providers, userSettings.DoT.DoTProviders)
if err != nil {
return nil, fmt.Errorf("DNS over TLS providers: %w", err)
}

selfDNSProviders, err := stringsToProviders(providers, userSettings.DoT.DNSProviders)
if err != nil {
return nil, fmt.Errorf("plaintext DNS providers: %w", err)
}

resolverSettings := doh.ResolverSettings{
DoHProviders: DoHProviders,
SelfDNS: doh.SelfDNS{
DoTProviders: selfDoTProviders,
DNSProviders: selfDNSProviders,
Timeout: userSettings.DoH.Self.Timeout,
IPv6: *userSettings.DoH.Self.IPv6,
},
Warner: logger,
Metrics: metrics,
IPv6: ptrTo(userSettings.DoH.IPVersion == "ipv6"),
Metrics: metrics,
}

settings := doh.ServerSettings{
Expand Down
5 changes: 5 additions & 0 deletions internal/setup/helpers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package setup

func ptrTo[T any](value T) *T {
return &value
}
23 changes: 4 additions & 19 deletions pkg/doh/dial.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,14 @@ package doh
import (
"bytes"
"context"
"fmt"
"net"
"sync"

"github.com/qdm12/dns/v2/internal/server"
"github.com/qdm12/dns/v2/pkg/dot"
"github.com/qdm12/dns/v2/pkg/provider"
)

func newDoHDial(settings ResolverSettings) (
dial server.Dial, err error) {
func newDoHDial(settings ResolverSettings) (dial server.Dial) {
// note: settings are already defaulted
metrics := settings.Metrics

Expand All @@ -22,19 +19,7 @@ func newDoHDial(settings ResolverSettings) (
dohServers[i] = provider.DoH
}

// DoT HTTP client to resolve the DoH URL hostname
DoTSettings := dot.ResolverSettings{
DoTProviders: settings.SelfDNS.DoTProviders,
DNSProviders: settings.SelfDNS.DNSProviders,
Timeout: settings.Timeout, // http client timeout really
IPv6: settings.SelfDNS.IPv6,
Warner: settings.Warner,
Metrics: metrics,
}
dotClient, err := newDoTClient(DoTSettings)
if err != nil {
return nil, fmt.Errorf("creating DoT client: %w", err)
}
httpClient := newHTTPClient(dohServers, *settings.IPv6)

// HTTP bodies buffer pool
bufferPool := &sync.Pool{
Expand All @@ -52,7 +37,7 @@ func newDoHDial(settings ResolverSettings) (
metrics.DoHDialInc(DoHServer.URL)

// Create connection object (no actual IO yet)
conn = newDoHConn(ctx, dotClient, bufferPool, DoHServer.URL)
conn = newDoHConn(ctx, httpClient, bufferPool, DoHServer.URL)
return conn, nil
}, nil
}
}
10 changes: 3 additions & 7 deletions pkg/doh/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,15 @@ package doh

import (
"context"
"fmt"

"github.com/qdm12/dns/v2/internal/server"
)

func newDNSHandler(ctx context.Context, settings ServerSettings) (
handler *server.Handler, err error) {
dial, err := newDoHDial(settings.Resolver)
if err != nil {
return nil, fmt.Errorf("creating DoH dial: %w", err)
}
handler *server.Handler) {
dial := newDoHDial(settings.Resolver)

exchange := server.NewExchange("DoH", dial, settings.Logger)

return server.New(ctx, exchange, settings.Logger), nil
return server.New(ctx, exchange, settings.Logger)
}
Loading

0 comments on commit dbdfdb6

Please sign in to comment.