Skip to content

Build Unbound from source

trinib edited this page Apr 19, 2023 · 17 revisions

by NLnet Labs

Unbound is a validating, recursive, caching DNS resolver. It is designed to be fast and lean and incorporates modern features based on open standard


1. Create unbound user account:

sudo useradd -M unbound && sudo usermod -L unbound && sudo usermod -a -G unbound unbound

2. Download needed library components:

sudo apt install -y libunbound-dev && sudo apt install -y libevent-dev && sudo apt install -y build-essential && sudo apt install -y libssl-dev && sudo apt install -y libexpat1-dev && sudo apt install -y bison && sudo apt install -y flex && sudo apt install -y libmnl-dev && sudo apt install -y libhiredis-dev && sudo apt install -y libsystemd-dev

For DietPi pkg-config package (apt install -y install pkg-config) might be needed.

3. Download the tarball of the latest version and untar it:

wget https://nlnetlabs.nl/downloads/unbound/unbound-latest.tar.gz && tar xzf unbound-latest.tar.gz

Or can also get latest package from repo: https://github.com/NLnetLabs/unbound/tags

4. Enter package directory:

cd unbound-{version#}

(use ls command to see package directory version)

5. Configure:

./configure --prefix=/usr --sysconfdir=/etc --with-conf-file=/etc/unbound/unbound.conf.d/unbound.conf --with-run-dir=/var/lib/unbound --with-rootkey-file=/var/lib/unbound/root.key --enable-subnet --enable-ipset --enable-cachedb --enable-checking --with-libhiredis --with-libevent --enable-systemd
List of configurables

Configuration:
  -h, --help              display this help and exit
      --help=short        display options specific to this package
      --help=recursive    display the short help of all the included packages
  -V, --version           display version information and exit
  -q, --quiet, --silent   do not print `checking ...' messages
      --cache-file=FILE   cache test results in FILE [disabled]
  -C, --config-cache      alias for `--cache-file=config.cache'
  -n, --no-create         do not create output files
      --srcdir=DIR        find the sources in DIR [configure dir or `..']

Installation directories:
  --prefix=PREFIX         install architecture-independent files in PREFIX
                          [/usr/local]
  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
                          [PREFIX]

By default, `make install' will install all the files in
`/usr/local/bin', `/usr/local/lib' etc.  You can specify
an installation prefix other than `/usr/local' using `--prefix',
for instance `--prefix=$HOME'.

For better control, use the options below.

Fine tuning of the installation directories:
  --bindir=DIR            user executables [EPREFIX/bin]
  --sbindir=DIR           system admin executables [EPREFIX/sbin]
  --libexecdir=DIR        program executables [EPREFIX/libexec]
  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
  --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
  --runstatedir=DIR       modifiable per-process data [LOCALSTATEDIR/run]
  --libdir=DIR            object code libraries [EPREFIX/lib]
  --includedir=DIR        C header files [PREFIX/include]
  --oldincludedir=DIR     C header files for non-gcc [/usr/include]
  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]
  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]
  --infodir=DIR           info documentation [DATAROOTDIR/info]
  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]
  --mandir=DIR            man documentation [DATAROOTDIR/man]
  --docdir=DIR            documentation root [DATAROOTDIR/doc/unbound]
  --htmldir=DIR           html documentation [DOCDIR]
  --dvidir=DIR            dvi documentation [DOCDIR]
  --pdfdir=DIR            pdf documentation [DOCDIR]
  --psdir=DIR             ps documentation [DOCDIR]

System types:
  --build=BUILD     configure for building on BUILD [guessed]
  --host=HOST       cross-compile to build programs to run on HOST [BUILD]

Optional Features:
  --disable-option-checking  ignore unrecognized --enable/--with options
  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
  --enable-checking       Enable warnings, asserts, makefile-dependencies
  --enable-debug          same as enable-checking
  --disable-flto          Disable link-time optimization (gcc specific option)
  --enable-pie            Enable Position-Independent Executable (eg. to fully
                          benefit from ASLR, small performance penalty)
  --enable-relro-now      Enable full relocation binding at load-time (RELRO
                          NOW, to protect GOT and .dtor areas)
  --enable-shared[=PKGS]  build shared libraries [default=yes]
  --enable-static[=PKGS]  build static libraries [default=yes]
  --enable-fast-install[=PKGS]
                          optimize for fast installation [default=yes]
  --disable-libtool-lock  avoid locking (might break parallel builds)
  --disable-rpath         disable hardcoded rpath (default=enabled)
  --disable-largefile     omit support for large files
  --enable-systemd        compile with systemd support
  --enable-alloc-checks   enable to memory allocation statistics, for debug
                          purposes
  --enable-alloc-lite     enable for lightweight alloc assertions, for debug
                          purposes
  --enable-alloc-nonregional
                          enable nonregional allocs, slow but exposes regional
                          allocations to other memory purifiers, for debug
                          purposes
  --disable-swig-version-check
                          Disable swig version check to build python modules
                          with older swig even though that is unreliable
  --disable-sha1          Disable SHA1 RRSIG support, does not disable nsec3
                          support
  --disable-sha2          Disable SHA256 and SHA512 RRSIG support
  --enable-subnet         Enable client subnet
  --disable-gost          Disable GOST support
  --disable-ecdsa         Disable ECDSA support
  --disable-dsa           Disable DSA support
  --disable-ed25519       Disable ED25519 support
  --disable-ed448         Disable ED448 support
  --enable-event-api      Enable (experimental) pluggable event base
                          libunbound API installed to unbound-event.h
  --enable-tfo-client     Enable TCP Fast Open for client mode
  --enable-tfo-server     Enable TCP Fast Open for server mode
  --enable-static-exe     enable to compile executables statically against
                          (event) uninstalled libs, for debug purposes
  --enable-fully-static   enable to compile fully static
  --enable-lock-checks    enable to check lock and unlock calls, for debug
                          purposes
  --enable-allsymbols     export all symbols from libunbound and link binaries
                          to it, smaller install size but libunbound export
                          table is polluted by internal symbols
  --enable-dnstap         Enable dnstap support (requires protobuf-c)
  --enable-dnscrypt       Enable dnscrypt support (requires libsodium)
  --enable-cachedb        enable cachedb module that can use external cache
                          storage
  --enable-ipsecmod       Enable ipsecmod module that facilitates
                          opportunistic IPsec
  --enable-ipset          enable ipset module
  --disable-explicit-port-randomisation
                          disable explicit source port randomisation and rely
                          on the kernel to provide random source ports
  --enable-linux-ip-local-port-range
                          Define this to enable use of
                          /proc/sys/net/ipv4/ip_local_port_range as a default
                          outgoing port range. This is only for the libunbound
                          on Linux and does not affect unbound resolving
                          daemon itself. This may severely limit the number of
                          available outgoing ports and thus decrease
                          randomness. Define this only when the target system
                          restricts (e.g. some of SELinux enabled
                          distributions) the use of non-ephemeral ports.

Optional Packages:
  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
  --with-conf-file=path   Pathname to the Unbound configuration file
  --with-run-dir=path     set default directory to chdir to (by default dir
                          part of cfg file)
  --with-chroot-dir=path  set default directory to chroot to (by default same
                          as run-dir)
  --with-share-dir=path   set default directory with shared data (by default
                          same as share/unbound)
  --with-pidfile=filename set default pathname to unbound pidfile (default
                          run-dir/unbound.pid)
  --with-rootkey-file=filename
                          set default pathname to root key file (default
                          run-dir/root.key). This file is read and written.
  --with-rootcert-file=filename
                          set default pathname to root update certificate file
                          (default run-dir/icannbundle.pem). This file need
                          not exist if you are content with the builtin.
  --with-username=user    set default user that unbound changes to (default
                          user is unbound)
  --with-pic[=PKGS]       try to use only PIC/non-PIC objects [default=use
                          both]
  --with-aix-soname=aix|svr4|both
                          shared library versioning (aka "SONAME") variant to
                          provide on AIX, [default=aix].
  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
  --with-sysroot[=DIR]    Search for dependent libraries within DIR (or the
                          compiler's sysroot if not specified).
  --with-pthreads         use pthreads library, or --without-pthreads to
                          disable threading support.
  --with-solaris-threads  use solaris native thread library.
  --with-syslog-facility=LOCAL0 - LOCAL7
                          set SYSLOG_FACILITY, default DAEMON
  --with-dynlibmodule     build dynamic library module, or
                          --without-dynlibmodule to disable it. (default=no)
  --with-pyunbound        build PyUnbound, or --without-pyunbound to skip it.
                          (default=no)
  --with-pythonmodule     build Python module, or --without-pythonmodule to
                          disable script engine. (default=no)
  --with-nss=path         use libnss instead of openssl, installed at path.
  --with-nettle=path      use libnettle as crypto library, installed at path.
  --with-ssl=pathname     enable SSL (will check /usr/local/ssl /usr/lib/ssl
                          /usr/ssl /usr/pkg /usr/local /opt/local /usr/sfw
                          /usr or specify like /usr/include/openssl11)
  --with-libbsd           Use portable libbsd functions
  --with-deprecate-rsa-1024
                          Deprecate RSA 1024 bit length, makes that an
                          unsupported key, for use when OpenSSL FIPS refuses
                          1024 bit verification
  --with-libevent=pathname
                          use libevent (will check /usr/local /opt/local
                          /usr/lib /usr/pkg /usr/sfw /usr or you can specify
                          an explicit path). Slower, but allows use of large
                          outgoing port ranges.
  --with-libexpat=path    specify explicit path for libexpat.
  --with-libhiredis=path  specify explicit path for libhiredis.
  --with-libnghttp2=path  specify explicit path for libnghttp2.
  --with-dnstap-socket-path=pathname
                          set default dnstap socket path
  --with-protobuf-c=path  Path where protobuf-c is installed, for dnstap
  --with-libsodium=path   Path where libsodium is installed, for dnscrypt
  --with-libmnl=path      specify explicit path for libmnl.
  --with-libunbound-only  do not build daemon and tool programs

Some influential environment variables:
  CC          C compiler command
  CFLAGS      C compiler flags
  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
              nonstandard directory <lib dir>
  LIBS        libraries to pass to the linker, e.g. -l<library>
  CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
              you have headers in a nonstandard directory <include dir>
  CPP         C preprocessor
  YACC        The `Yet Another Compiler Compiler' implementation to use.
              Defaults to the first program found out of = `bison -y', `byacc',
              `yacc'.
  YFLAGS      The list of arguments that will be passed by default to $YACC.
              This script will default YFLAGS to the empty string to avoid a
              default value of `-d' given by some make applications.
  LT_SYS_LIBRARY_PATH
              User-defined run-time library search path.
  PKG_CONFIG  path to pkg-config utility
  PKG_CONFIG_PATH
              directories to add to pkg-config's search path
  PKG_CONFIG_LIBDIR
              path overriding pkg-config's built-in search path
  SYSTEMD_CFLAGS
              C compiler flags for SYSTEMD, overriding pkg-config
  SYSTEMD_LIBS
              linker flags for SYSTEMD, overriding pkg-config
  SYSTEMD_DAEMON_CFLAGS
              C compiler flags for SYSTEMD_DAEMON, overriding pkg-config
  SYSTEMD_DAEMON_LIBS
              linker flags for SYSTEMD_DAEMON, overriding pkg-config
  PYTHON_VERSION
              The installed Python version to use, for example '2.3'. This
              string will be appended to the Python interpreter canonical
              name.

Use these variables to override the choices made by `configure' or to help
it to find libraries and programs with nonstandard names/locations.

Report bugs to <unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues>.

6. Make and install:

make && sudo make install

Create unbound directory and set permission:

sudo mkdir /var/lib/unbound && sudo chown unbound:unbound /var/lib/unbound/

7. Download trust anchor root key:

sudo unbound-anchor && sudo mv root.key /var/lib/unbound/

8. Download root hints:

sudo wget -O root.hints https://www.internic.net/domain/named.root && sudo mv root.hints /var/lib/unbound/

IMPORTANT: This needs to update every 6 months using cron job.
Enter in command line crontab -e, it will ask select an editor(choose 1), paste these lines at the bottom of crontab and save (control+x then y then enter):

1 0 1 */6 * wget -O root.hints https://www.internic.net/domain/named.root
2 0 1 */6 * sudo mv root.hints /var/lib/unbound/

9. Create log file and set permission:

sudo touch /var/lib/unbound/unbound.logs && sudo chown unbound:unbound /var/lib/unbound/unbound.logs

10. Download unbound configuration file with DNS over TLS settings and replace in unbound folder:

wget https://raw.githubusercontent.com/trinib/AdGuard-WireGuard-Unbound-Cloudflare/main/unbound.conf && sudo mv unbound.conf /etc/unbound/unbound.conf.d/

11. Some path need to be changed in unbound.confand from the one set by the built-in package manager. You can change it manually or automatically from command line:

awk '{sub(/[#]auto-trust-anchor-file/,"auto-trust-anchor-file") || sub(/[#]chroot/,"chroot") || sub(/dev/,"var") && sub(/null/,"lib/unbound/unbound.logs")}1' /etc/unbound/unbound.conf.d/unbound.conf > unbound.conf && sudo mv unbound.conf /etc/unbound/unbound.conf.d/
  • Manually:

Un-comment auto-trust-anchor-file(line 43) to enable DNSSEC

    # enable DNSSEC
    auto-trust-anchor-file: "/var/lib/unbound/root.key"

Un-comment chroot(line 46) to access permission for systemd

    # Can be uncommented if you do not need file access protection
    chroot: ""

Change log file location(line 148) to /var/lib/unbound/

    # Do not print log lines that say why queries return SERVFAIL to clients
    logfile: /var/lib/unbound/unbound.logs

Save

Create service to boot at startup:

sudo nano /lib/systemd/system/unbound.service

Copy and save:

[Unit]
Description=Unbound DNS server
Documentation=man:unbound(8)
After=network.target
Before=nss-lookup.target
Wants=nss-lookup.target

[Service]
Type=notify
Restart=on-failure
ExecStart=/usr/sbin/unbound -d -p $DAEMON_OPTS
ExecReload=+/bin/kill -HUP $MAINPID

[Install]
WantedBy=multi-user.target

Enable and start unbound service:

sudo systemctl enable unbound && sudo systemctl start unbound

Check version and status:

unbound -V && sudo systemctl status unbound

image

Optional

Configure locally on the hosting machine : https://unbound.docs.nlnetlabs.nl/en/latest/use-cases/local-stub.html#configuring-the-local-stub-resolver