This is the multi-page printable view of this section.
Click here to print.
Return to the regular view of this page.
Getting Started
Getting Started with dnsmonster
Passive DNS monitoring framework built on Golang.
dnsmonster
implements a packet sniffer for DNS traffic. It Ability to accept traffic from a pcap
file, a live interface or a dnstap
socket,
and Ability to be used to index and store hundreds of thousands of DNS queries per second as it has shown to be capable of indexing 200k+ DNS queries per second on a commodity computer. It aims to be scalable, simple and easy to use, and help
security teams to understand the details about an enterprise’s DNS traffic. dnsmonster
doesn’t look to follow DNS conversations, rather it aims to index DNS packets as soon as they come in. It also doesn’t aim to breach
the privacy of the end-users, with the ability to mask Layer 3 IPs (IPv4 and IPv6), enabling teams to perform trend analysis on aggregated data without being able to trace back the queries to an individual. Blogpost
Warning
The code before version 1.x is considered beta quality and is subject to breaking changes. Please check the release notes for each tag to see the list of breaking scenarios between each release, and how to mitigate potential data loss.
Main features
- Ability to use Linux’s
afpacket
and zero-copy packet capture.
- Supports BPF
- Ability to mask IP address to enhance privacy
- Ability to have a pre-processing sampling ratio
- Ability to have a list of “skip”
fqdn
s to avoid writing some domains/suffix/prefix to storage
- Ability to have a list of “allow” domains, used to log access to certain domains
- Hot-reload of skip and allow domain files/urls
- Modular output with configurable logic per output stream.
- Automatic data retention policy using ClickHouse’s TTL attribute
- Built-in Grafana dashboard for ClickHouse output.
- Ability to be shipped as a single, statically linked binary
- Ability to be configured using environment variables, command line options or configuration file
- Ability to sample outputs using ClickHouse’s SAMPLE capability
- Ability to send metrics using
prometheus
and statstd
- High compression ratio thanks to ClickHouse’s built-in LZ4 storage
- Supports DNS Over TCP, Fragmented DNS (udp/tcp) and IPv6
- Supports dnstrap over Unix socket or TCP
- built-in SIEM integration with Splunk and Microsoft Sentinel
1 - installation
Learn how to install dnsmonster on your platform using Docker, prebuilt binaries, or compiling it from the source on any platform Go supports
dnsmonster
has been built with minimum dependencies. In runtime, the only optional dependency for dnsmonster
is libpcap
. By building dnsmonster
without libpcap, you will lose the ability to set bpf
filters on your live packet captures.
installation methods
Prebuilt binaries
Each relase of dnsmonster
will ship with two binaries. One for Linux amd64, built statically against an Alpine based image, and one for Windows amd64, which depends on a capture library to be installed on the OS. I’ve tested thw Windows binary with the latest version of Wireshark installed on the system and there was no issues to run the executable.
Prebuilt packages
Per each release, the statically-linked binary mentioned above is also wrapped into deb
and rpm
packages with no dependencies, making it easy to deploy it in Debian and RHEL based distributions. Note that the packages don’t generate any service files or configuration templates at installation time.
Run as a container
The container build process only generates a Linux amd64 output. Since dnsmonster
uses raw packet capture funcationality, Docker/Podman daemon must grant the capability to the container
sudo docker run --rm -it --net=host --cap-add NET_RAW --cap-add NET_ADMIN --name dnsmonster ghcr.io/mosajjal/dnsmonster:latest --devName lo --stdoutOutputType=1
Check out the configuration section to understand the provided command line arguments.
Build from the source
- with
libpcap
:
Make sure you have go
, libpcap-devel
and linux-headers
packages installed. The name of the packages might differ based on your distribution. After this, simply clone the repository and run go build .
git clone https://github.com/mosajjal/dnsmonster --depth 1 /tmp/dnsmonster
cd /tmp/dnsmonster
go get
go build -o dnsmonster ./cmd/dnsmonster
- without
libpcap
:
dnsmonster
only uses one function from libpcap
, and that’s converting the tcpdump
-style filters into BPF bytecode. If you can live with no BPF support, you can build dnsmonster
without libpcap
. Note that for any other platform, the packet capture falls back to libpcap
so it becomes a hard dependency (*BSD, Windows, Darwin)
git clone https://github.com/mosajjal/dnsmonster --depth 1 /tmp/dnsmonster
cd /tmp/dnsmonster
go get
go build -o dnsmonster -tags nolibpcap ./cmd/dnsmonster
The above build also works on ARMv7 (RPi4) and AArch64.
Build Statically
If you have a copy of libpcap.a
, you can build the statically link it to dnsmonster
and build it fully statically. In the code below, please change /root/libpcap-1.9.1/libpcap.a
to the location of your copy.
git clone https://github.com/mosajjal/dnsmonster --depth 1 /tmp/dnsmonster
cd /tmp/dnsmonster/
go get
go build --ldflags "-L /root/libpcap-1.9.1/libpcap.a -linkmode external -extldflags \"-I/usr/include/libnl3 -lnl-genl-3 -lnl-3 -static\"" -a -o dnsmonster ./cmd/dnsmonster
For more information on how the statically linked binary is created, take a look at Dockerfiles in the root of the repository responsible for generating the published binaries.
2 - post-installation
Set up services and shell completions for dnsmonster
Post-install
After you install dnsmonster, you might need to take a few extra steps to build services so dnsmonster
runs automatically on system startup. These steps aren’t included in the installation process by default.
Systemd service
If you’re using a modern and popular distro like Debian, Ubuntu, Fedora, Arch, RHEL, you’re probably using systemd
as your init system. To have dnsmonster
as a service, created a file in /etc/systemd/system/
named dnsmonster.service
, and define your systemd unit there. The name dnsmonster
as a service name is totally optional.
cat > /etc/systemd/system/dnsmonster.service << EOF
[Unit]
Description=Dnsmonster Service
Wants=network-online.target
After=network-online.target
[Service]
Type=simple
Restart=always
RestartSec=3
ExecStart=/sbin/dnsmonster --config /etc/dnsmonster.ini
[Install]
WantedBy=multi-user.target
EOF
The above systemd service looks at /etc/dnsmonster.ini
as a configuration file. Checkout the configuration section to see how that configuration file is generated.
to start the service and ebable it at boot time, run the following
sudo systemctl enable --now dnsmonster.service
You can also build a systemd service that takes the interface name dynamically and runs the dnsmonster
instance per interface. To do so, create a service unit like this:
cat > /etc/systemd/system/[email protected] << EOF
[Unit]
Description=Dnsmonster Service
Wants=network-online.target
After=network-online.target
[Service]
Type=simple
Restart=always
RestartSec=3
ExecStart=/sbin/dnsmonste --devName=%i --config /etc/dnsmonster.ini
[Install]
WantedBy=multi-user.target
EOF
The above unit creates a dynamic systemd service that can be enabled for multiple Interfaces. For example, to run the service for the loopback interface in linux (lo
), run the following:
Note that the above example only works if you’re not specifying a dnstap
or a local pcap
file as an input inside the configuration file.
init.d service
bash and fish completion