Tungsten aims to be a highly flexible and programmable DNS server. I am creating this to act as my internal DNS solution, resolving private or internal names. I am not sure if this will ever be suitable for public, high volume DNS resolution.
Warning
Use at your own risk
I cannot guarantee that this DNS server is fully stable. I use this in my homelab, where some downtime is okay.
- Easily add all sorts of records using structured, typesafe configuration instead of RFC 1035 syntax
- Autopopulate names from a Tailscale IPN/Tailnet
- Configuration hot-reloading
- Forward DNS queries to different places depending on what zone answers for them
- Fully recursive resolution with libunbound
- Serving from etcd
- Allow zones to individually bind to specific interfaces and addresses
- Shortcut syntax for certain DNS-SD services, as well as simpler SRV record syntax
Please note: this is not an exhaustive list, and will be updated in the future to reflect the current standing of this project.
Configuration is done via a combination of environment variables (for settings that are not likely to change) and the Pkl configuration file.
Environment variables are used for a few select things; mostly related to logging at the moment.
Variable | Default | Description |
---|---|---|
TUNGSTEN_LOG_FORMAT |
json |
Can be json or pretty ; determines what log output looks like. |
TUNGSTEN_LOG_LEVEL |
2 (warn) |
This value gets passed into zerolog.ParseLevel . See zerolog level docs here |
TUNGSTEN_DEV_MODE |
false |
Any truthy or falsy value (ie 0 , 1 , true , false , etc) |
You should check out the example.pkl
file for a general idea of how it's structured, but here's the general gist:
amends
tells Pkl what file to fetch for the type definitions (the url must return the text content of the template file)- It is highly recommended to have the Pkl language extension installed, as that will hint the type definitions and make it way easier to write your own config
Tungsten is set up with a CLI interface as shown:
❯ tungsten --help
A highly programmable DNS server, written in Go and configured with Pkl.
Usage:
tungsten [command]
Available Commands:
completion Generate the autocompletion script for the specified shell
help Help about any command
reload Reload the configuration without restarting the server
serve Run up the Tungsten DNS server
validate Check if the config is valid
version Print the version number of Tungsten
Flags:
-c, --config string Path to the configuration file (default "./example.pkl")
-h, --help help for tungsten
-s, --socket string Path to the socket for daemon communication (default "/run/tungsten/tungsten.sock")
Use "tungsten [command] --help" for more information about a command.
By default, binaries are not built with support for recursive resolution.
To build with libunbound, add the unbound
tag to the build command like so:
go build -tags unbound
The tungsten-full
package includes unbound, whereas the regular tungsten
or default package do not.
This project uses Pkl Codegen, and thus certain tools must be installed for this to work.
go install github.com/apple/pkl-go/cmd/[email protected] # This provides the `pkl-gen-go` command
In this case, generate
references the config files in config
to run pkl-gen-go
and create the corresponding go structs/interfaces.
go generate && go build
- SDNS (Go patterns for starting/stopping stuff, and DoH/DoQ things)
- damomurf/coredns-tailscale (Pulling information from tailscale for self-hosted MagicDNS)
- CoreDNS
bind
plugin (Translating iface names to bindable addresses)