You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Erik Hollensbe 309a80104b ugh 8 months ago
cmd move to as a part of release 1 year ago
config Fix configuration validation 11 months ago
dnsdb Some additional tests and validations 1 year ago
proto ugh 8 months ago
service Fix configuration validation 11 months ago
version add golangci-lint, fix some things it nailed 1 year ago
.gitignore add golangci-lint, fix some things it nailed 1 year ago
.golangci.yml add golangci-lint, fix some things it nailed 1 year ago
Makefile Several fixes related to the existing release tooling. No changes otherwise. 8 months ago Docker image! 1 year ago
VERSION ldnsd 0.1.1 11 months ago
box-release.rb Add protoc to the release build 8 months ago
box.rb Upgraded deps and better release tooling 11 months ago export CAROOT lol 11 months ago mroe crap 11 months ago
example.conf Breaking out the service so we can test it soon 1 year ago
go.mod Upgraded deps and better release tooling 11 months ago
go.sum Upgraded deps and better release tooling 11 months ago
ldnsd_test.go move to as a part of release 1 year ago Docker image! 1 year ago
task.yml trying again 11 months ago
tinyci.yml Add CI 11 months ago

ldnsd: Light DNSd: a small, 0 ttl A record store that is remotely programmable.

Light DNSd is largely designed for testing & small environments, providing an easy to manage DNS service that serves the minimum necessary to deliver name services centrally. Compare with a remotely programmable /etc/hosts file that lives in a central location. ldnsd comes with ldnsctl which can handle the programming, or use/generate GRPC-compliant clients from our protobuf definitions to program it inside of your tools directly.

Light DNSd is backed by sqlite3 and provides very few features:

  • No recursion
  • No caching (although this may be added soon, see Potential Issues)
  • No forwarding
  • All records are 0 TTL

Since not all clients are very happy with how ldnsd sees the world (simply), it is strongly advised that you front it with a caching, recursive, standards-compliant nameserver like coredns, bind, dqcache/dnscache, etc, especially for the purposes of servicing client resolvers. Think of ldnsd more as a companion to your DNS stack instead of replacing it.


Installing a release is your best choice. Otherwise, you can still go get and get the desired result in your $GOBIN or $GOPATH/bin.

Docker Image

If you wish to use Docker to power ldnsd, you can use our erikh/ldnsd version-tagged images. Running with --net=host is advisable to avoid the UDP proxy docker provides as it tends to drop packets under high load.

Example usage:

# start the service
$ docker run -it -d --name ldnsd --net=host erikh/ldnsd:0.1.0
# configure some hosts
$ docker exec -it ldnsd ldnsctl set myhost
$ dig myhost.internal. @

Manual Installation

If you'd like to build in a container or build the release version, just make sure to have docker installed; box will be installed as root as a part of the process during the first run while creating the shell image.

To create a release tarball:

$ make shell
# <inside the container>
$ make release # out comes the tarball in the CWD

Make a CA

You'll need a CA. I strongly recommend installing mkcert and trying this script to generate the CA, one server cert, and one client cert in /etc/ldnsd (you may need to be root to write to this directory):

This will only make the service available on localhost/ through this cert. All other attempts will be rejected.

Note if you change the directories, you will need to adjust the configuration file, which is discussed below.

export CAROOT="/etc/ldnsd"
mkcert -install
mkcert -ecdsa -cert-file /etc/ldnsd/server.pem -key-file /etc/ldnsd/server.key localhost
mkcert -ecdsa -client -cert-file /etc/ldnsd/client.pem -key-file /etc/ldnsd/client.key localhost


ldnsd takes one argument, the configuration filename. It is a basic YAML document that covers certificate management and network listening information.

Here is an example. If in doubt, all options have defaults:

# vim: ft=yaml
  ca: "/etc/ldnsd/rootCA.pem"
  cert: "/etc/ldnsd/server.pem"
  key: "/etc/ldnsd/server.key"
# grpc listening port
grpc: "localhost:7847"
# dns listening port (udp only!)
listen: "localhost:53"
# TLD for domains.
domain: "internal"

Launching and Utilization

ldnsd my.conf to launch the service, it does not daemonize so be sure to run it in the background if you need to. Also, since :53 is privileged port, you will need to run this process as root.

ldnsctl can be used to query and manipulate the service. To resolve hosts, use DNS:

dig bar.internal. @

"Set", "List" and "Delete" operations go through ldnsctl. To review how to use those operations, please review the ldnsctl help command's output.

Potential Issues

sqlite3 (and the way we use it) under a lot of contention could cause slow responses, which could lead to dropped queries. There are benchmarks at the root of the repository, if you are able to produce this behavior with them please let us know.

On a 12 thread / 6 core intel 9xxx processor, the erikh/dnsserver package delivers 7000ns/op for a similar test that ldnsd delivers in 30000ns/op, suggesting that (understandably) sqlite3 is slower than map access. That said, extended "burn-in" benchmarks have shown no delivery issues so far.

For most other bugs, please see the Issues pages.


Erik Hollensbe