Denis Machard

My technical gists

Infrastructure background, developer mindset. I build things for pleasure.
    @github @mastodon @rss

    Enabling DNStap logging on most popular DNS servers

    This post details how to enable the dnstap feature in main open source dns servers.

    dnstap is a flexible, structured binary log format for DNS servers. It uses Protocol Buffers to encode DNS packets in events.

    dnstap can encode any DNS messages with network informations like ip and port. It includes client queries and responses.

    Introduction

    This dnstap feature has been tested with success with the following dns servers:

    RQ/RSCQ/CRAQ/ARFQ/FRUnix SocketTCP StreamTLS supportExtra Field
    Bindxxxxx
    PowerDNS recursorxxx
    PowerDNS dnsdistxxxx
    NSDxx
    Unboundxxxxxx
    CoreDNSxxxxxx
    Knot Resolverxx
    Knot DNSXx

    ISC bind

    bind 9.11.22 bind 9.16.10

    Dnstap messages supported:

    • RESOLVER_QUERY
    • RESOLVER_RESPONSE
    • CLIENT_QUERY
    • CLIENT_RESPONSE
    • AUTH_QUERY
    • AUTH_RESPONSE

    Build with dnstap support

    Since 9.16 version, the dnstap feature is enabled before that you need to download latest source and build-it with dnstap support:

    ./configure --enable-dnstap
    make && make install
    

    Unix socket

    Update the configuration file /etc/named.conf to activate the dnstap feature:

    options {
        dnstap { client; auth; resolver; forwarder; };
        dnstap-output unix "/var/run/named/dnstap.sock";
        dnstap-identity "dns-bind";
        dnstap-version "bind";
    }
    

    Execute the dnstap receiver with named user:

    su - named -s /bin/bash -c "dnstap_receiver -u "/var/run/named/dnstap.sock""
    

    If you have some troubles take a look to selinux

    TCP stream

    Not supported on Bind! You can apply the following workaround with the socat or stunnel command.

    while true; do socat unix-listen:/var/run/dnsdist/dnstap.sock tcp4-connect:<ip_dnstap_receiver>:<port_dnstap_receiver>,forever,interval=10, fork; sleep 1; done
    

    PowerDNS - pdns-recursor

    pdns-recursor 4.3.4 pdns-recursor 4.4.0

    Dnstap messages supported:

    • RESOLVER_QUERY
    • RESOLVER_RESPONSE

    Unix socket

    Update the configuration file to activate the dnstap feature:

    vim /etc/pdns-recursor/recursor.conf
    lua-config-file=/etc/pdns-recursor/recursor.lua
    
    vim /etc/pdns-recursor/recursor.lua
    dnstapFrameStreamServer("/var/run/pdns-recursor/dnstap.sock")
    

    Execute the dnstap receiver with pdns-recursor user:

    su - pdns-recursor -s /bin/bash -c "dnstap_receiver -u "/var/run/pdns-recursor/dnstap.sock""
    

    TCP stream

    Update the configuration file to activate the dnstap feature with tcp mode and execute the dnstap receiver in listening tcp socket mode:

    vim /etc/pdns-recursor/recursor.conf
    lua-config-file=/etc/pdns-recursor/recursor.lua
    
    vim /etc/pdns-recursor/recursor.lua
    dnstapFrameStreamServer("10.0.0.100:6000")
    

    Note: TCP stream are only supported with a recent version of libfstrm.

    PowerDNS - dnsdist

    dnsdist 1.8 dnsdist 1.7 dnsdist 1.6 dnsdist 1.5 dnsdist 1.4

    Dnstap messages supported:

    • CLIENT_QUERY
    • CLIENT_RESPONSE

    Unix socket

    Create the dnsdist folder where the unix socket will be created:

    mkdir -p /var/run/dnsdist/
    chown dnsdist.dnsdist /var/run/dnsdist/
    

    Update the configuration file /etc/dnsdist/dnsdist.conf to activate the dnstap feature:

    fsul = newFrameStreamUnixLogger("/var/run/dnsdist/dnstap.sock")
    addAction(AllRule(), DnstapLogAction("dnsdist", fsul))
    addResponseAction(AllRule(), DnstapLogResponseAction("dnsdist", fsul))
    -- Cache Hits
    addCacheHitResponseAction(AllRule(), DnstapLogResponseAction("dnsdist", fsul))
    

    Execute the dnstap receiver with dnsdist user:

    su - dnsdist -s /bin/bash -c "dnstap_receiver -u "/var/run/dnsdist/dnstap.sock""
    

    TCP stream

    Update the configuration file /etc/dnsdist/dnsdist.conf to activate the dnstap feature with tcp stream and execute the dnstap receiver in listening tcp socket mode:

    fsul = newFrameStreamTcpLogger("127.0.0.1:8888")
    addAction(AllRule(), DnstapLogAction("dnsdist", fsul))
    addResponseAction(AllRule(), DnstapLogResponseAction("dnsdist", fsul))
    -- Cache Hits
    addCacheHitResponseAction(AllRule(), DnstapLogResponseAction("dnsdist", fsul))
    

    NLnetLabs - nsd

    nsd 4.3.2

    Dnstap messages supported:

    • AUTH_QUERY
    • AUTH_RESPONSE

    Build with dnstap support

    Download latest source and build-it with dnstap support:

    ./configure --enable-dnstap
    make && make install
    

    Unix socket

    Update the configuration file /etc/nsd/nsd.conf to activate the dnstap feature:

    dnstap:
        dnstap-enable: yes
        dnstap-socket-path: "/var/run/nsd/dnstap.sock"
        dnstap-send-identity: yes
        dnstap-send-version: yes
        dnstap-log-auth-query-messages: yes
        dnstap-log-auth-response-messages: yes
    

    Execute the dnstap receiver with nsd user:

    su - nsd -s /bin/bash -c "dnstap_receiver -u "/var/run/nsd/dnstap.sock""
    

    NLnetLabs - unbound

    unbound 1.11.0 unbound 1.12.0 unbound 1.13.0

    Dnstap messages supported:

    • CLIENT_QUERY
    • CLIENT_RESPONSE
    • RESOLVER_QUERY
    • RESOLVER_RESPONSE

    Build with dnstap support

    Download latest source and build-it with dnstap support:

    ./configure --enable-dnstap
    make && make install
    

    Unix socket

    Update the configuration file /etc/unbound/unbound.conf to activate the dnstap feature:

    dnstap:
        dnstap-enable: yes
        dnstap-socket-path: "dnstap.sock"
        dnstap-send-identity: yes
        dnstap-send-version: yes
        dnstap-log-resolver-query-messages: yes
        dnstap-log-resolver-response-messages: yes
        dnstap-log-client-query-messages: yes
        dnstap-log-client-response-messages: yes
        dnstap-log-forwarder-query-messages: yes
        dnstap-log-forwarder-response-messages: yes
    

    Execute the dnstap receiver with unbound user:

    su - unbound -s /bin/bash -c "dnstap_receiver -u "/usr/local/etc/unbound/dnstap.sock""
    

    TCP stream

    Update the configuration file /etc/unbound/unbound.conf to activate the dnstap feature with tcp mode and execute the dnstap receiver in listening tcp socket mode:

    dnstap:
        dnstap-enable: yes
        dnstap-socket-path: ""
        dnstap-ip: "10.0.0.100@6000"
        dnstap-tls: no
        dnstap-send-identity: yes
        dnstap-send-version: yes
        dnstap-log-client-query-messages: yes
        dnstap-log-client-response-messages: yes
    

    TLS stream

    Update the configuration file /etc/unbound/unbound.conf to activate the dnstap feature with tls mode and execute the dnstap receiver in listening tcp/tls socket mode:

    dnstap:
        dnstap-enable: yes
        dnstap-socket-path: ""
        dnstap-ip: "10.0.0.100@6000"
        dnstap-tls: yes
        dnstap-send-identity: yes
        dnstap-send-version: yes
        dnstap-log-client-query-messages: yes
        dnstap-log-client-response-messages: yes
    

    CoreDNS

    coredns 1.11.1 coredns 1.8.4 coredns 1.8.0

    Dnstap messages supported:

    • CLIENT_QUERY
    • CLIENT_RESPONSE
    • FORWARDER_QUERY
    • FORWARDER_RESPONSE

    Unix socket

    corefile example

    .:53 {
        dnstap /tmp/dnstap.sock full
        forward . 8.8.8.8:53
    }
    

    Then execute CoreDNS with your corefile

     ./coredns -conf corefile
    

    TCP stream

    corefile example

    .:53 {
            dnstap tcp://10.0.0.51:6000 full
            forward . 8.8.8.8:53
    }
    

    Then execute CoreDNS with your corefile

     ./coredns -conf corefile
    

    TLS stream

    corefile example

    .:53 {
            dnstap tls://10.0.0.51:6000 full {
              skip-verify
            }
            forward . 8.8.8.8:53
    }
    

    Then execute CoreDNS with your corefile

     ./coredns -conf corefile
    

    CZ-NIC - Knot Resolver

    Unix socket

    corefile example

    net.listen("0.0.0.0", 5553)
    
    modules.load('nsid')
    nsid.name('instance1')
    
    modules = {
        dnstap = {
            socket_path = "/tmp/dnstap.sock",
            identity =  nsid.name() or "",
            version = "knot-resolver" .. package_version(),
            client = {
                log_queries = true,
                log_responses = true,
            },
        }
    }
    

    Then execute the Knot Resolver, example with docker

    sudo docker run -d -v $PWD/kresd.conf:/etc/knot-resolver/kresd.conf --name=knot --network=host cznic/knot-resolver -n -c /etc/knot-resolver/kresd.conf
    
    propulsed by hugo and hugo-theme-gists