Code Monkey home page Code Monkey logo

sdns's Introduction

SDNS ๐Ÿš€

A high-performance, recursive DNS resolver server with DNSSEC support, focused on preserving privacy.


Installation

Use the go get command to install sdns:

go get github.com/semihalev/sdns

Pre-build Binaries

You can download the latest release from the Github Repo.

Docker

$ docker run -d --name sdns -p 53:53 -p 53:53/udp sdns

Docker Compose

Install docker-compose and run from the root directory:

$ sudo apt install docker-compose
$ docker-compose up -d

Homebrew for macOS

Install and run as a service:

$ brew install sdns
$ brew install semihalev/tap/sdns (updated every release)
$ brew services start sdns

Snapcraft

$ snap install sdns

AUR for ArchLinux

$ yay -S sdns-git

Note: Pre-built binaries, Docker packages, brew taps, and snaps are automatically created by Github workflows.

Building from Source

$ go build

Testing

$ make test

Flags

Flag Desc
-c, --config PATH Location of the config file. If it doesn't exist, a new one will be generated.
-v, --version Show the version of the sdns.
-h, --help Show this help and exit.

Debugging Environment

To debug your environment, execute the following command:

$ export SDNS_DEBUGNS=true && export SDNS_PPROF=true && ./sdns

The SDNS_DEBUGNS environment variable is beneficial for verifying the RTT (Round Trip Time) of authoritative servers. To use it, send an HINFO query for zones with chaos class.

Here's an example of the output you might receive:

$ dig chaos hinfo example.com

; <<>> DiG 9.17.1 <<>> chaos hinfo example.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 29636
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 4, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: f27dbb995df5ac79e4fa37c07d131b5bd03aa1c5f802047a7c02fb228a886cb281ecc319323dea81 (good)
;; QUESTION SECTION:
;example.com.			CH	HINFO

;; AUTHORITY SECTION:
example.com.		0	CH	HINFO	"Host" "IPv4:199.43.135.53:53 rtt:142ms health:[GOOD]"
example.com.		0	CH	HINFO	"Host" "IPv4:199.43.133.53:53 rtt:145ms health:[GOOD]"
example.com.		0	CH	HINFO	"Host" "IPv6:[2001:500:8f::53]:53 rtt:147ms health:[GOOD]"
example.com.		0	CH	HINFO	"Host" "IPv6:[2001:500:8d::53]:53 rtt:148ms health:[GOOD]"

Configuration (v1.3.7)

Key Description
version Configuration version
directory sdns working directory (must grant write access to sdns user)
bind DNS server binding address Default: :53
bindtls DNS-over-TLS server binding address Default: :853
binddoh DNS-over-HTTPS server binding address Default: :8053
binddoq DNS-over-QUIC server binding address Default: :853
tlscertificate Path to the TLS certificate file
tlsprivatekey Path to the TLS private key file
outboundips Outbound IPv4 addresses (randomly chosen if multiple entries provided)
outboundip6s Outbound IPv6 addresses (randomly chosen if multiple entries provided)
rootservers DNS Root IPv4 servers
root6servers DNS Root IPv6 servers
dnssec DNSSEC validation on signed zones, off for disabled.
rootkeys Trusted DNSSEC anchors
fallbackservers Failover resolver IPv4 or IPv6 addresses with port (leave blank to disable) Example: "8.8.8.8:53"
forwarderservers Forwarder resolver IPv4 or IPv6 addresses with port (leave blank to disable) Example: "8.8.8.8:53"
api HTTP API server binding address (leave blank to disable)
bearertoken API bearer token for authorization. If the token set, Authorization header should be send on API requests
blocklists Remote blocklist address list (downloaded to the blocklist folder)
blocklistdir [DEPRECATED] Directory creation is automated in the working directory
loglevel Log verbosity level (crit, error, warn, info, debug)
accesslog Location of the access log file (leave blank to disable) Default: Common Log Format
nullroute IPv4 address for forwarding blocked queries
nullroutev6 IPv6 address for forwarding blocked queries
accesslist Client whitelist for query permissions
querytimeout Maximum wait duration for DNS query response Default: 10s
timeout Network timeout duration for each DNS lookup Default: 2s
hostsfile Enable serving zone data from a hosts file (leave blank to disable)
expire Default error cache TTL (in seconds) Default: 600
cachesize Cache size (total records in cache) Default: 256000
prefetch Cache prefetch before expiry (threshold: 10%-90%, 0 to disable)
maxdepth Maximum iteration depth per query Default: 30
ratelimit Query-based rate limit per second (0 to disable) Default: 0
clientratelimit Client IP address-based rate limit per minute (no limit if client supports EDNS cookie) Default: 0
blocklist Manual blocklist entries
whitelist Manual whitelist entries
cookiesecret DNS cookie secret (RFC 7873) - auto-generated if not set
nsid DNS server identifier (RFC 5001) - useful for operating multiple sdns instances (leave blank to disable)
chaos Enable responses to version.server, version.bind, hostname.bind and id.server chaos txt queries
qname_min_level Qname minimize level (0 to disable - higher values increase complexity and impact response performance)
emptyzones Enable response to RFC 1918 zone queries. For details, see http://as112.net/

Plugin Configuration

In sdns, you have the ability to add custom plugins. The sequence of the plugins and the middlewares has a mutual impact on their execution. Config keys must be strings, and values can be of any type. Plugins are loaded before the cache middleware in the specified order.

The plugin interface is straightforward. For additional information, please refer to the example plugin.

Example Configuration

[plugins]
     [plugins.example]
     path = "/path/to/exampleplugin.so"
     config = {key_1 = "value_1", intkey = 2, boolkey = true, keyN = "nnn"}
     [plugins.another]
     path = "/path/to/anotherplugin.so"

Server Configuration Checklist

  • Increase the file descriptor limit on your server

Features

  • Linux/BSD/Darwin/Windows supported
  • DNS RFC compatibility
  • DNS lookups within listed ipv4 and ipv6 auth servers
  • DNS caching with prefetch support
  • DNSSEC validation
  • DNS over TLS support (DoT)
  • DNS over HTTPS support (DoH) with HTTP/3 support
  • DNS over QUIC support (DoQ)
  • Outbound IP selection
  • Middleware Support, you can add, your own middleware
  • RTT priority within listed servers
  • Failover forwarders while returning failured responses
  • Forwarder support
  • EDNS Cookie Support (client<->server)
  • EDNS NSID Support
  • Full IPv6 support (client<->server, server<->server)
  • Query based ratelimit
  • IP based ratelimit
  • Access list
  • Access log
  • Prometheus basic query metrics
  • Black-hole for malware responses
  • HTTP API support
  • Cache Purge API and query support
  • Answer chaos txt queries for version.bind and hostname.bind
  • Empty zones support described at RFC 1918
  • External plugins supported

TODO

  • More tests
  • Try lookup NS address better way
  • DNS over TLS support
  • DNS over HTTPS support
  • Full DNSSEC support
  • RTT optimization
  • Access list
  • Periodic priming queries described at RFC 8109
  • Full IPv6 support (server<->server communication)
  • Query name minimization to improve privacy described at RFC 7816
  • DNAME Redirection in the DNS described at RFC 6672
  • Automated Updates DNSSEC Trust Anchors described at RFC 5011
  • DNS64 DNS Extensions for NAT from IPv6 Clients to IPv4 Servers described at RFC 6147
  • DNS over QUIC support described at RFC 9250

Performance

Benchmark Environment

  • Server Specifications:
    • Processor: Intel Xeon E5-2609 v4 CPU
    • Memory: 32GB

Benchmarking Tool

  • Tool Name: DNS-OARC dnsperf
  • Benchmark Configuration:
    • Query Data Volume: 50,000 sample queries

Benchmark Comparisons

Benchmarks were performed on the following DNS resolvers: sdns-1.3.3, pdns-recursor-4.8.4, bind-9.19.12, unbound-1.17.1.

Benchmark Results

Resolver RESPONSE LOST NOERROR SERVFAIL NXDOMAIN Run Time QPS
SDNS 100% 1 35,164 866 13,969 87s47ms 571/s
PowerDNS 99.99% 6 35,140 893 13,961 88s83ms 563/s
Bind 99.74% 132 35,024 885 13,959 127s64ms 390/s
Unbound 99.49% 253 35,152 624 13,971 174s64ms 284/s

Contributing

We welcome pull requests. If you're considering significant changes, please start a discussion by opening an issue first.

Before submitting patches, please review our CONTRIBUTING guidelines.

โ™ฅ๏ธ Made With

  • miekg/dns - Alternative (more granular) approach to a DNS library

Inspired by

License

MIT

sdns's People

Contributors

benleb avatar c1982 avatar dependabot[bot] avatar gordonbondon avatar hstern avatar m3ok avatar peterdavehello avatar rahulpowar avatar semihalev avatar spikecodes avatar thebigbone avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sdns's Issues

Fallback to Google DNS is not desirable

Please do not fallback on Google resolvers for privacy reasons, more importantly, this can not be overriden in the configuration file like the Root IPs/keys. I'd use either the local ones or a mix of 1.1.1.1/9.9.9.9/ instead. At the very least, make it a config entry.

v1.1.8 tarball checksum changed?

We're attempting to update Homebrew's version of Go at Homebrew/homebrew-core#83413.

While testing the new version, CI produced the following error:

==> brew install --build-from-source sdns
==> FAILED
==> Downloading https://github.com/semihalev/sdns/archive/v1.1.8.tar.gz
==> Downloading from https://codeload.github.com/semihalev/sdns/tar.gz/v1.1.8
Error: SHA256 mismatch
Expected: 9b5ca516e711764ba1e840e97b679ef3d299c60945920b84baed155fb8df8711
  Actual: 5ffc8a72be67c3f9ce7200fd638ade6435ae177b09eda5eb149daadc66955ba6

I can update the sha256 associated with sdns, but CI will come back to me with the following error:

sdns:
  * stable sha256 changed without the url/version also changing; please create an issue upstream to rule out malicious circumstances and to find out why the file changed.

Can I confirm that the change in checksum was intentional and that nothing is amiss here? Thanks.

Wildcard domains

Does it block wildcard domains too?

*.domain.com

I couldn't find anything in code

[BUG] - errInvalidSignaturePeriod when first create trust-anchor

Description

ๅ›พ็‰‡
In function ValidityPeriod(), the rr.Expiration is smaller than utc, so the validation failed.
ๅ›พ็‰‡
This is the error displayed

Reproduction steps

delete db directory, run the application

sdns version

sdns v1.3.5 rev bb819c1
built by go1.20.6 (windows amd64)

Logs

INFO[10-28|17:15:39] Starting sdns...                         version=1.3.5
INFO[10-28|17:15:39] Loading config file...                   path=sdns.conf
INFO[10-28|17:15:39] Working directory                        path=db
INFO[10-28|17:15:39] Empty zones loaded                       zones=99
INFO[10-28|17:15:39] DNS server listening...                  net=udp addr=:53
INFO[10-28|17:15:39] DNS server listening...                  net=tcp addr=:53
INFO[10-28|17:15:39] API server listening...                  addr=127.0.0.1:8080
WARN[10-28|17:15:39] No trust anchor state file found or the state corrupted! New one will be generate. path=db\\trust-anchor.db
CRIT[10-28|17:15:39] Root zone keys not verified

OS

No response

Additional context

No response

Privacy

Does sdns use random resolvers or minimum ping or something else?

For example I have set 3 forwarders but if the first one is not working then it doesn't use the other two. and if it is working then only that single one is used all the time the other two are never used.

checkGLUE is odd

The checkGLUE func is odd:

 func (h *DNSHandler) checkGLUE(proto string, req, mesg *dns.Msg) *dns.Msg {
	//check cname response

is this following a CNAME? Then a better name would be "additional processing".

Failure to resolve SOA record for www.bbc.com

Using SDNS attempts to resolve www.bbc.com IN soa returns only www.bbc.com. 300 IN CNAME www-bbc-com.bbc.net.uk.. The cname portion is not resolved.

dig @195.244.44.44 www.bbc.com SOA
; <<>> DiG 9.16.4 <<>> @195.244.44.44 www.bbc.com SOA
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 50031
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: e522e60e7ea0e5a6d7e75a1d63375c960aa359e277106e12e8345836627d3d5dc6efedd95fff65c9 (good)
;; QUESTION SECTION:
;www.bbc.com.                   IN      SOA

;; ANSWER SECTION:
www.bbc.com.            300     IN      CNAME   www-bbc-com.bbc.net.uk.

;; Query time: 286 msec
;; SERVER: 195.244.44.44#53(195.244.44.44)
;; WHEN: Tue Aug 11 07:23:20 PDT 2020
;; MSG SIZE  rcvd: 120

Google does return results for this same query

dig @8.8.8.8 www.bbc.com soa

; <<>> DiG 9.16.4 <<>> @8.8.8.8 www.bbc.com soa
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 56105
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 1, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;www.bbc.com.                   IN      SOA

;; ANSWER SECTION:
www.bbc.com.            160     IN      CNAME   www-bbc-com.bbc.net.uk.
www-bbc-com.bbc.net.uk. 98      IN      CNAME   bbc.map.fastly.net.

;; AUTHORITY SECTION:
fastly.net.             29      IN      SOA     ns1.fastly.net. hostmaster.fastly.com. 2017052201 3600 600 604800 30

;; Query time: 26 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Tue Aug 11 07:24:05 PDT 2020
;; MSG SIZE  rcvd: 166

It appears in the logs that there is an attempt to forward the SOA request to www-bbc-com.bbc.net.uk which gets cancelled, im guessing that is because another server successfully responds.

DBUG[08-11|07:15:59] Dial failed to upstream server           query="www-bbc-com.bbc.net.uk. IN SOA" upstream=212.58.224.6:53 upstream server=ns0.tcams.bbc.co.uk. net=udp rtt=10s error="dial udp 212.58.224.6:53: operation was canceled" retried=0   

Cloudflare has the same results as SDNS, so Im unsure which is the correct operation, can you help clarify?

dig @1.1.1.1 www.bbc.com soa +dnssec

; <<>> DiG 9.16.4 <<>> @1.1.1.1 www.bbc.com soa +dnssec
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 62365
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 1232
;; QUESTION SECTION:
;www.bbc.com.                   IN      SOA

;; ANSWER SECTION:
www.bbc.com.            300     IN      CNAME   www-bbc-com.bbc.net.uk.

;; Query time: 333 msec
;; SERVER: 1.1.1.1#53(1.1.1.1)
;; WHEN: Tue Aug 11 07:29:20 PDT 2020
;; MSG SIZE  rcvd: 87

version mismatch

I downloaded 0.2.2 from the releases page. Started it up. wrote a config file with this at the top:

version = "0.2.1"

I should add that the first time I run it, it doesn't work. I have to quit/restart and then it starts working.

nice project

As said I'm just spot checking things, but it's good code and comprehensive from a DNS standpoint.

Invalid DNSSEC answer returned from cache

If I start sdns and then query:

dig +cd dnssec.fail @localhost -p 1053 
dig  dnssec.fail @localhost -p 1053    

The latter returns a response while the answer is actually invalid, but has been put in the cache because of +cd (checking disabled).

Feature: Programmic way to change DNS servers sdns is using for lookup

When I turn on my VPN, I would like sdns to use their DNS to lookup external sources. But, all I can find to do it is to have two configs, kill the server, and rerun it with a different config file. I would rather send a command to a TCP/IP port on sdns and change the server address. The sdns program already has an API server. Does that allow for it? Where is documentation for the API server?

no DNSKEY records found

I downloaded release v0.25 and started it up on linux, this error message appears:

WARN[01-23|15:54:35] DNSSEC verify failed (answer)            query=". IN NS" error="no DNSKEY records found"
EROR[01-23|15:54:35] root servers update failed               error="no DNSKEY records found"

I try to query it and get:
WARN[01-23|15:56:29] DNSSEC verify failed (delegation)        query="com. IN NS" signer=. signed=com. error="no DNSKEY records found"
WARN[01-23|15:56:29] Resolve query failed                     query="example.com. IN A" error="no DNSKEY records found"

any ideas?

forwarder support for dns over https tls?

currently forwarders are only using port 53 on systems where it might be blocked or privacy is an issue can you add support for doing lookups over dns over https or tls?

alos a basic doh listner without tls so that this app could be used with local porxy like nginx or cloudflared. currently its only tls so it doesn't work if the use case scenario is to used this as a local dns.
also instead of manual whitelist can whitelists be loaded from urls?

[BUG] - build example plugin not possible

Description

It is not possible to build the example plugin, so it would work.
If I checkout both repos, and try to build it as the readme told me, I cant load the plugin.

Once I build the sdns with CGO_ENABLED=1 I can load the plugin, but not it will not accept the function assert in line 111 in middelware.go (newFn, ok := newFuncSym.(func(cfg *config.Config) Handler))

Reproduction steps

# this is from github release
Apr 09 13:04:40 homeprinter sdns[3382185]: t=2024-04-09T13:04:40+0200 lvl=eror msg="Plugin open failed" plugin=wildcardhostsfile error="plugin: not implemented" 

or

# this is selfbuild from source with CGO_ENABLED=1
Apr 09 13:25:22 homeprinter sdns[3399475]: t=2024-04-09T13:25:22+0200 lvl=eror msg="Plugin new function assert failed" plugin=wildcardhostsfile

sdns version

1.3.6 from releases (without CGO_ENABLED=1)
also 1.3.6 self build with CGO_ENDABLED=1

Logs

No response

OS

Linux

Additional context

No response

panic: root zone DS not verified

t=2019-04-10T10:01:06+0000 lvl=info msg="Starting sdns..." version=0.2.2-rc1
panic: root zone DS not verified

goroutine 1 [running]:
main.(*Resolver).verifyRootKeys(0xc000264990, 0xc000272090, 0x1)
/go/src/github.com/semihalev/sdns/resolver.go:705 +0x3c5
main.(*Resolver).verifyDNSSEC(0xc000264990, 0xbdbbcc, 0x3, 0x114706e, 0x1, 0x114706e, 0x1, 0xc000272090, 0xc000204440, 0x2, ...)
/go/src/github.com/semihalev/sdns/resolver.go:744 +0x9a5
main.(*Resolver).Resolve(0xc000264990, 0xbdbbcc, 0x3, 0xc000214d80, 0xc00007e6c0, 0xcb5001, 0x1e, 0x0, 0xc00027e000, 0x0, ...)
/go/src/github.com/semihalev/sdns/resolver.go:171 +0x65f
main.(*Resolver).verifyDNSSEC(0xc000264990, 0xbdbbcc, 0x3, 0x114706e, 0x1, 0xbdb4f4, 0x1, 0xc000272000, 0xc0002042e0, 0x2, ...)
/go/src/github.com/semihalev/sdns/resolver.go:728 +0xb19
main.(*Resolver).Resolve(0xc000264990, 0xbdbbcc, 0x3, 0xc000215ac8, 0xc00007e6c0, 0xc000245001, 0x5, 0x0, 0x0, 0x0, ...)
/go/src/github.com/semihalev/sdns/resolver.go:171 +0x65f
main.(*Resolver).checkPriming(0xc000264990, 0xc000082840, 0xc0000c6400)
/go/src/github.com/semihalev/sdns/resolver.go:833 +0x1c9
main.NewResolver(0x10)
/go/src/github.com/semihalev/sdns/resolver.go:55 +0x124
main.NewHandler(0x4)
/go/src/github.com/semihalev/sdns/handler.go:33 +0x22
main.(*Server).Run(0xc0000827e0)
/go/src/github.com/semihalev/sdns/server.go:31 +0x37
main.start()
/go/src/github.com/semihalev/sdns/main.go:171 +0x2e3
main.main()
/go/src/github.com/semihalev/sdns/main.go:184 +0xb7

log client ips

Is it possible to log client ips that are querying? I currently have loglevel at debug but don't see them.

resolver.go: use of reflection

		if err == nil {
			if reflect.DeepEqual(nsCache.Servers, servers) {
				return nil, errLoopDetection
			}

probably nicer and fast to not use reflect here - although most latency will come from the network anyway.

HTTP API usage

I'm experimenting with the HTTP API and all requests get 404 errors.

Here is an example I found in test cases.
GET http://127.0.0.1:8080/dns-query?name=www.google.com&type=a&do=true&cd=true&edns_client_subnet=127.0.0.1/32

Is there any user guide on HTTP API?

[BUG] - Test_ClientTimeout failed

Description

=== RUN Test_ClientTimeout
client_test.go:29:
Error Trace: /root/sdns/middleware/resolver/client_test.go:29
Error: An error is expected but got nil.
Test: Test_ClientTimeout
--- FAIL: Test_ClientTimeout (0.01s)

Reproduction steps

build from source and use makefile:

make

on tests it failing

sdns version

current source

Logs

No response

OS

Linux

Additional context

No response

No such file or directory on listen

Log

INFO[03-17|14:59:17] Starting sdns...                         version=0.3.0-rc1
INFO[03-17|14:59:17] DNS server listening...                  net=udp addr=:53
INFO[03-17|14:59:17] API server listening...                  addr=127.0.0.1:8080
INFO[03-17|14:59:17] DNS server listening...                  net=https addr=:8053
INFO[03-17|14:59:17] DNS server listening...                  net=tcp-tls addr=:853
EROR[03-17|14:59:17] DNS listener failed                      net=tcp-tls addr=:853 error="open : no such file or directory"
INFO[03-17|14:59:17] DNS server listening...                  net=tcp addr=:53
EROR[03-17|14:59:17] DNSs listener failed                     net=https addr=:8053 error="open : no such file or directory"

Config:


# config version, config and build versions can be different.
version = "0.3.0"

# address to bind to for the DNS server
bind = ":53"

# address to bind to for the DNS-over-TLS server
bindtls = ":853"

# address to bind to for the DNS-over-HTTPS server
binddoh = ":8053"

# tls certificate file
# tlscertificate = "server.crt"

# tls private key file
# tlsprivatekey = "server.key"

# outbound ip addresses, if you set multiple, sdns can use random outbound ip address
outboundips = []

# root servers
rootservers = [
"192.5.5.241:53",
"198.41.0.4:53",
"192.228.79.201:53",
"192.33.4.12:53",
"199.7.91.13:53",
"192.203.230.10:53",
"192.112.36.4:53",
"128.63.2.53:53",
"192.36.148.17:53",
"192.58.128.30:53",
"193.0.14.129:53",
"199.7.83.42:53",
"202.12.27.33:53"
]

# root ipv6 servers
root6servers = [
"[2001:500:2f::f]:53",
"[2001:503:ba3e::2:30]:53",
"[2001:500:200::b]:53",
"[2001:500:2::c]:53",
"[2001:500:2d::d]:53",
"[2001:500:a8::e]:53",
"[2001:500:12::d0d]:53",
"[2001:500:1::53]:53",
"[2001:7fe::53]:53",
"[2001:503:c27::2:30]:53",
"[2001:7fd::1]:53",
"[2001:500:9f::42]:53",
"[2001:dc3::35]:53"
]

# root keys for dnssec
rootkeys = [
".                      172800  IN      DNSKEY  256 3 8 AwEAAdp440E6Mz7c+Vl4sPd0lTv2Qnc85dTW64j0RDD7sS/zwxWDJ3QRES2VKDO0OXLMqVJSs2YCCSDKuZXpDPuf++YfAu0j7lzYYdWTGwyNZhEaXtMQJIKYB96pW6cRkiG2Dn8S2vvo/PxW9PKQsyLbtd8PcwWglHgReBVp 7kEv/Dd+3b3YMukt4jnWgDUddAySg558Zld+c9eGWkgWoOiuhg4rQRkF stMX1pRyOSHcZuH38o1WcsT4y3eT0U/SR6TOSLIB/8Ftirux/h297oS7tCcwSPt0wwry5OFNTlfMo8v7WGurogfk8hPipf7TTKHIi20LWen5RCsvYsQBkYGpF78=",
".                      172800  IN      DNSKEY  256 3 8 AwEAAcH+axCdUOsTc9o+jmyVq5rsGTh1EcatSumPqEfsPBT+whyj0/UhD7cWeixV9Wqzj/cnqs8iWELqhdzGX41ZtaNQUfWNfOriASnWmX2D9m/EunplHu8nMSlDnDcT7+llE9tjk5HI1Sr7d9N16ZTIrbVALf65VB2ABbBG39dyAb7tz21PICJbSp2cd77UF7NFqEVkqohl/LkDw+7Apalmp0qAQT1Mgwi2cVxZMKUiciA6EqS+KNajf0A6olO2oEhZnGGY6b1LTg34/YfHdiIIZQqAfqbieruCGHRiSscC2ZE7iNreL/76f4JyIEUNkt6bQA29JsegxorLzQkpF7NKqZc=",
".                      172800  IN      DNSKEY  257 3 8 AwEAAagAIKlVZrpC6Ia7gEzahOR+9W29euxhJhVVLOyQbSEW0O8gcCjFFVQUTf6v58fLjwBd0YI0EzrAcQqBGCzh/RStIoO8g0NfnfL2MTJRkxoXbfDaUeVPQuYEhg37NZWAJQ9VnMVDxP/VHL496M/QZxkjf5/Efucp2gaD X6RS6CXpoY68LsvPVjR0ZSwzz1apAzvN9dlzEheX7ICJBBtuA6G3LQpzW5hOA2hzCTMjJPJ8LbqF6dsV6DoBQzgul0sGIcGOYl7OyQdXfZ57relSQageu+ipAdTTJ25AsRTAoub8ONGcLmqrAmRLKBP1dfwhYB4N7knNnulqQxA+Uk1ihz0=",
".                      172800  IN      DNSKEY  257 3 8 AwEAAaz/tAm8yTn4Mfeh5eyI96WSVexTBAvkMgJzkKTOiW1vkIbzxeF3+/4RgWOq7HrxRixHlFlExOLAJr5emLvN7SWXgnLh4+B5xQlNVz8Og8kvArMtNROxVQuCaSnIDdD5LKyWbRd2n9WGe2R8PzgCmr3EgVLrjyBxWezF0jLHwVN8efS3rCj/EWgvIWgb9tarpVUDK/b58Da+sqqls3eNbuv7pr+eoZG+SrDK6nWeL3c6H5Apxz7LjVc1uTIdsIXxuOLYA4/ilBmSVIzuDWfdRUfhHdY6+cn8HFRm+2hM8AnXGXws9555KrUB5qihylGa8subX2Nn6UwNR1AkUTV74bU="
]

# fallback servers
fallbackservers = [
"8.8.8.8:53",
"8.8.4.4:53"
]

# address to bind to for the http API server, leave blank to disable
api = "127.0.0.1:8080"

# what kind of information should be logged, Log verbosity level [crit,error,warn,info,debug]
loglevel = "info"

# list of remote blocklists
blocklists = [
"http://mirror1.malwaredomains.com/files/justdomains",
"https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts",
"http://sysctl.org/cameleon/hosts",
"https://zeustracker.abuse.ch/blocklist.php?download=domainblocklist",
"https://s3.amazonaws.com/lists.disconnect.me/simple_tracking.txt",
"https://s3.amazonaws.com/lists.disconnect.me/simple_ad.txt",
"http://hosts-file.net/ad_servers.txt",
"https://raw.githubusercontent.com/quidsup/notrack/master/trackers.txt"
]

# list of locations to recursively read blocklists from (warning, every file found is assumed to be a hosts-file or domain list)
blocklistdir = "bl"

# ipv4 address to forward blocked queries to
nullroute = "0.0.0.0"

# ipv6 address to forward blocked queries to
nullroutev6 = "::0"

# which clients allowed to make queries
accesslist = [
"0.0.0.0/0",
"::0/0"
]

# enables serving zone data from a hosts file, leave blank to disable
# the form of the entries in the /etc/hosts file are based on IETF RFC 952 which was updated by IETF RFC 1123.
hostsfile = ""

# query timeout for dns lookups in duration
timeout = "5s"

# connect timeout for dns lookups in duration
connecttimeout = "2s"

# default cache TTL in seconds
expire = 600

# cache size (total records in cache)
cachesize = 256000

# maximum recursion depth for nameservers
maxdepth = 30

# query based ratelimit per second, 0 for disable
ratelimit = 0

# client ip address based ratelimit per minute, 0 for disable
clientratelimit = 0

# manual blocklist entries
blocklist = []

# manual whitelist entries
whitelist = []

[BUG] - Root servers update failed

Description

I'm happily running sdns on top of OpenWRT as the DNS upstream for AdGuardHome. From time to time, I'm seeing the following message in the log:

Wed Dec 6 03:46:26 2023 daemon.info sdns[17660]: t=2023-12-06T02:46:26+0000 lvl=eror msg="Root servers update failed" error="A record count mismatch"

I've been taking a look at the code, but I'm not really familiar with Go, so I'm not sure what the purpose of the snippet where appears this comparison: ipv4Count != nsCount

Is this something really expected ?

Thanks !

Reproduction steps

I guess this `checkPriming` thing is scheduled, so it happens from time to time.

sdns version

1.3.5

Logs

Wed Dec  6 03:46:26 2023 daemon.info sdns[17660]: t=2023-12-06T02:46:26+0000 lvl=eror msg="Root servers update failed" error="A record count mismatch"

OS

Linux

Additional context

I'm using the default configuration for the root servers. Please note that my ISP hasn't enabled IPv6 yet, so currently using just IPv4 (I left the IPv6 addresses for the root servers though). sdns is listening just on localhost

# Address to bind to for the DNS server.
bind = "127.0.0.1:5354"

"go test" segfault when you have no IPv6

Not sure how to fix or workaround this but go test without IPv6 connectivity segfault because the reply is nil.

=== RUN   Test_handler
--- FAIL: Test_handler (15.01s)
    handler_test.go:84: 
        	Error Trace:	handler_test.go:84
        	Error:      	Received unexpected error:
        	            	read udp [::1]:53289->[::1]:53288: i/o timeout
        	Test:       	Test_handler
    handler_test.go:85: 
        	Error Trace:	handler_test.go:85
        	Error:      	Expected value not to be nil.
        	Test:       	Test_handler
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
	panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x48 pc=0x1677715]

goroutine 14 [running]:
testing.tRunner.func1(0xc000265100)
	/usr/local/go/src/testing/testing.go:792 +0x387
panic(0x172dc20, 0x1da3150)
	/usr/local/go/src/runtime/panic.go:513 +0x1b9
github.com/semihalev/sdns.Test_handler(0xc000265100)
	/Users/roberto/Src/Go/src/github.com/semihalev/sdns/handler_test.go:86 +0x405
testing.tRunner(0xc000265100, 0x1835f50)
	/usr/local/go/src/testing/testing.go:827 +0xbf
created by testing.(*T).Run
	/usr/local/go/src/testing/testing.go:878 +0x353

Process finished with exit code 1

I added a assert.NotNil(t, r) in line 85 so now it is line 86 in handler_test.go which segfaults.

Request to add forwarding dns function

Currently the sdns program does not support the forwarding of dns query functions. For example, I can forward all dns domain name queries to 1.1.1.1 and 8.8.8.8 for resolution.

Multitenant

Is there a way to associate whitelists and blacklists only to specific client ips?

parallel queries

The resolver does parallel lookup:

	// Start lookup on each nameserver top-down, in interval
	for index, server := range servers {
		go L(server, len(servers)-1 == index)
 ....

This is nice for latency, but it breaks things at larger scales. For one you get an awful lot of queries which means you can get blocked (common in cloud providers).
The config.Interval mitigates against this which is good - how did you determine that interval?

Different zones queries route to different DNS upstream servers

Hi,

Is there any chance to handle different lookups route to different upstrem DNS servers?

For example (meta config structure, not valid):

server {
label="main_dns";
ip=8.8.8.8, 8.8.4.4, 1.1.1.1;
exclude=".office.lan, .private";
}

server {
label="private_dns";
ip=192.168.45.1, 10.34.216.1;
include=".office.lan, .private";
}

Thank you!

code review: question/comment

I'm opening issue as I go through your code (hope you don't mind).

In resolver. go the rootserver and root6server are both hardcoded. Usually these things live in a root.hints file. I.e. would be good to factor that out.

Further more there is a thing called priming; i.e. you go to the root and you validate (and update) the hints file with the data you get from (some) root servers. Is something like this currently implemented?

Local Name assignments

Hi,

I was wanting to be able to assign local network names for the ten computers in my house. I have them setup in the hosts file, but sdns doesn't look at it. Is there a way to get it to? Or, can we assign local names in the config file?

RFC 5011 support

RFC 5011: Automated Updates of DNS Security (DNSSEC) Trust Anchors

is an RFC that tells you how to detect a root (KSK) key rollover happens and how to update your currently configured root-anchor.

I haven't implemented this myself, but it would be a nice addition.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.