Skip to content

Commit

Permalink
feat(bootstrap): support IP only encrypted DNS
Browse files Browse the repository at this point in the history
Also make `tcp+udp` upstreams use any IPs provided.
  • Loading branch information
ThinkChaos committed Jan 18, 2023
1 parent a794599 commit e47a8b7
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 31 deletions.
4 changes: 1 addition & 3 deletions docs/config.yml
Expand Up @@ -216,9 +216,7 @@ minTlsServeVersion: 1.3
# optional: use these DNS servers to resolve blacklist urls and upstream DNS servers. It is useful if no system DNS resolver is configured, and/or to encrypt the bootstrap queries.
bootstrapDns:
- tcp+udp:1.1.1.1
- usptream: https://1.1.1.1/dns-query
ips:
- 1.1.1.1
- https://1.1.1.1/dns-query
- upstream: https://dns.digitale-gesellschaft.ch/dns-query
ips:
- 185.95.218.42
Expand Down
6 changes: 2 additions & 4 deletions docs/configuration.md
Expand Up @@ -155,7 +155,7 @@ It is useful if no system DNS resolver is configured, and/or to encrypt the boot
| upstream | Upstream (see above) | no | | |
| ips | List of IPs | yes, if upstream is DoT/DoH | | Only valid if upstream is DoH or DoT |

If you only need to specify upstream, you can use the short form: `bootstrapDns: <upstream>`.
When using an upstream specified by IP, and not by hostname, you can write only the upstream and skip `ips`.

!!! note

Expand All @@ -168,9 +168,7 @@ If you only need to specify upstream, you can use the short form: `bootstrapDns:
- upstream: tcp-tls:dns.example.com
ips:
- 123.123.123.123
- upstream: https://dns2.example.com/dns-query
ips:
- 234.234.234.234
- upstream: https://234.234.234.234/dns-query
```

## Filtering
Expand Down
43 changes: 21 additions & 22 deletions resolver/bootstrap.go
Expand Up @@ -235,35 +235,34 @@ func newBootstrapedResolvers(b *Bootstrap, cfg config.BootstrapDNSConfig) (boots

upstream := upstreamCfg.Upstream

var ips []net.IP

switch {
case upstream.IsDefault():
if upstream.IsDefault() {
multiErr = multierror.Append(
multiErr,
fmt.Errorf("item %d: upstream not configured (ips=%v)", i, upstreamCfg.IPs),
)

continue
case upstream.Net == config.NetProtocolTcpUdp:
ip := net.ParseIP(upstream.Host)
if ip == nil {
multiErr = multierror.Append(
multiErr,
fmt.Errorf("item %d: '%s': protocol %s must use IP instead of hostname", i, upstream, upstream.Net),
)
continue
}
}

var ips []net.IP

if ip := net.ParseIP(upstream.Host); ip != nil {
ips = append(ips, ip)
default:
ips = upstreamCfg.IPs
if len(ips) == 0 {
multiErr = multierror.Append(
multiErr,
fmt.Errorf("item %d: '%s': protocol %s requires IPs to be set", i, upstream, upstream.Net),
)
continue
}
} else if upstream.Net == config.NetProtocolTcpUdp {
multiErr = multierror.Append(
multiErr,
fmt.Errorf("item %d: '%s': protocol %s must use IP instead of hostname", i, upstream, upstream.Net),
)

continue
}

ips = append(ips, upstreamCfg.IPs...)

if len(ips) == 0 {
multiErr = multierror.Append(multiErr, fmt.Errorf("item %d: '%s': no IPs configured", i, upstream))

continue
}

resolver := newUpstreamResolverUnchecked(upstream, b)
Expand Down
45 changes: 43 additions & 2 deletions resolver/bootstrap_test.go
Expand Up @@ -128,7 +128,7 @@ var _ = Describe("Bootstrap", Label("bootstrap"), func() {
})
})

When("IP is invalid", func() {
When("using non IP hostname", func() {
It("errors", func() {
cfg := config.Config{
BootstrapDNS: []config.BootstrappedUpstreamConfig{
Expand All @@ -146,6 +146,29 @@ var _ = Describe("Bootstrap", Label("bootstrap"), func() {
Expect(err.Error()).Should(ContainSubstring("must use IP instead of hostname"))
})
})

When("extra IPs are configured", func() {
BeforeEach(func() {
sutConfig = &config.Config{
BootstrapDNS: []config.BootstrappedUpstreamConfig{
{
Upstream: config.Upstream{
Net: config.NetProtocolTcpUdp,
Host: "0.0.0.0",
},
IPs: []net.IP{net.IPv4allrouter},
},
},
}
})
It("uses them", func() {
Expect(sut).ShouldNot(BeNil())

for _, ips := range sut.bootstraped {
Expect(ips).Should(ContainElements(net.IPv4zero, net.IPv4allrouter))
}
})
})
})

Context("using encrypted DNS", func() {
Expand All @@ -164,7 +187,25 @@ var _ = Describe("Bootstrap", Label("bootstrap"), func() {

_, err := NewBootstrap(&cfg)
Expect(err).ShouldNot(Succeed())
Expect(err.Error()).Should(ContainSubstring("requires IPs to be set"))
Expect(err.Error()).Should(ContainSubstring("no IPs configured"))
})
})

When("hostname is IP", func() {
It("doesn't require extra IPs", func() {
cfg := config.Config{
BootstrapDNS: []config.BootstrappedUpstreamConfig{
{
Upstream: config.Upstream{
Net: config.NetProtocolTcpTls,
Host: "0.0.0.0",
},
},
},
}

_, err := NewBootstrap(&cfg)
Expect(err).Should(Succeed())
})
})
})
Expand Down

0 comments on commit e47a8b7

Please sign in to comment.