Handshake SPV name resolver
SPV resolver daemon for the Handshake network. Written in C for speed/size/embedability.
hnsd exists as a 4-layer architecture:
.as a stub zone
A standard stub resolver can hit the recursive server with a request. The flow looks something like this.
stub resolver -> +rd request -> recursive server -> libunbound -> +nord request -> authoritative server -> spv node -> proof request -> peer
Coming back, a response will look like:
peer -> proof response -> spv node -> authoritative server -> translated dns response -> libunbound -> recursive server -> dns response -> stub resolver
This daemon currently stores no data, and uses about 12mb of memory when operating with a full DNS cache.
This architecture works well, given that there's two layers of caching between the final resolution and the p2p layer (which entails the production of slightly expensive-to-compute proofs).
The recursive resolver leverages libunbound's built-in cache: there is, however, also a cache for the authoritative server. This is atypical when compared to a standard RFC 1035 nameserver which simply holds a zonefile in memory and serves it. All current ICANN-based root zone servers are RFC 1035 nameservers. We differ in that our root zonefile is a blockchain. With caching for the root server, new proofs only need to be requested every 6 hours (the duration of name tree update interval at the consensus layer). This substantially reduces load for full nodes who are willing to serve proofs as a public service.
hnsd will recursively build and statically link to
uv, which is included in the source repo.
$ brew install git automake autoconf libtool unbound
You're a Linux user so you probably already know what to do. Make sure you have git, autotools, libtool, and unbound installed via whatever package manager your OS uses.
Windows builds are made natively with MSYS2 / MinGW. This uses the MinGW libunbound and OpenSSL packages provided by MSYS2.
pacman -S base-devel mingw-w64-i686-toolchain mingw-w64-i686-unbound mingw-w64-i686-crt-git
pacman -S git
The Windows build will dynamically link to the MinGW libunbound and OpenSSL DLLs. You can run it from the MSYS2 shell, which sets PATH appropriately, copy those DLLs to the hnsd directory, etc.
$ git clone git://github.com/handshake-org/hnsd.git $ cd hnsd
$ ./autogen.sh && ./configure && make
$ sudo make install
Currently, hnsd will setup a recursive name server listening locally. If you want to resolve names through the handshake network, this requires you to change your resolv.conf to 127.0.0.1, as well as configure the daemon to listen on port 53 -- this requires root access on OSX, and some hackery on Linux.
$ sudo ./hnsd -p 4 -r 127.0.0.1:53.
First we need to alter our resolv.conf:
echo 'nameserver 127.0.0.1' | sudo tee /etc/resolv.conf > /dev/null
Secondly, we need to allow our daemon to listen on low ports, without root access (much safer than running as root directly).
$ sudo setcap 'cap_net_bind_service=+ep' /path/to/hnsd
Now run with:
$ ./hnsd -p 4 -r 127.0.0.1:53
On Linux, there are a few services which may try to automatically overwrite your
resolv.conf. resolvconf, dhcpcd, and NetworkManager are usually the culprits here.
If you're using resolvconf,
/etc/resolvconf.confmust be modified:
$ sudo vi /etc/resolvconf.conf
name_serversfield must be altered in order to truly alter your resolv.conf:
dhcpcd may try to overwrite your resolv.conf with whatever nameservers are advertised by your router (usually your ISP's nameservers). To prevent this,
/etc/dhcpcd.confmust be modified:
$ sudo vi /etc/dhcpcd.conf
In the default config, you may see a line which looks like:
option domain_name_servers, domain_name, domain_search, host_name
We want to remove
Likewise, NetworkManager has similar behavior to dhcpcd. To prevent it from tainting your resolv.conf,
/etc/NetworkManager/NetworkManager.confmust be altered:
$ sudo vi /etc/NetworkManager/NetworkManager.conf
NetworkManager.confis usually empty, but we need to add a
dnsoption under the
[main]section, resulting in a configuration like:
Windows users: your system may alter the "end of line" characters in certain files that will break the build inside docker. To prevent this, add this option to your git global configuraiton before cloning this repo:
$ git config --global core.autocrlf input
To build a Docker image with the name
$ docker build -t hnsd .
To create and run a container named
$ docker create \ --name=hnsd \ --publish=127.0.0.1:53:53/udp \ --restart=unless-stopped \ hnsd -r 0.0.0.0:53
$ docker start hnsd
To check the
hnsdcontainer if it runs correctly
$ docker ps -a
To stop a container named
$ docker stop hnsd
To build hnsd as an OpenWRT package you'll need to rename
Makefileand put it in
your_openwrt_dir/package/net/hnsdbefore building. Then you can use your
menuconfigand select it.
$ make package/net/hnsd/compile V=s
Please keep in mind that
libunboundand all of its dependencies such as
libsodium, libmnl, libevent2(all packs), libpthread, libnghttp2, python3-base,libprotobuf-cand some of them are reqired to be installed manually.
$ hnsd [options]
-c, --config Path to config file.
-n, --ns-host IP address and port for root nameserver, e.g. 127.0.0.1:5369.
-r, --rs-host IP address and port for recursive nameserver, e.g. 127.0.0.1:53.
-i, --ns-ip Public IP for NS records in the root zone.
-u, --rs-config Path to unbound config file.
-p, --pool-size Size of peer pool.
-k, --identity-key Identity key for signing DNS responses as well as P2P messages.
-s, --seeds Extra seeds to connect to on P2P network. Example: -s [email protected]
-l, --log-file Redirect output to a log file.
-d, --daemon Fork and background the process.
-h, --help Help message.
makecommand will output two binaries into the root directory:
test_hnsd, which is compiled from unit tests in the
test/directory. Run the tests with
See LICENSE for more info.