DNS Tracking Tool: dnspeep
I recently created a little tool called dnspeep that allows you to understand what DNS requests your computer is sending and what responses it receives. In total, my code took 250 lines in Rust. In this article I will talk about the code, explain what it is for, why it was needed, and also talk about some of the problems that I encountered while writing it. And, of course, you can try the code yourself.
What you need to get started with code
To make it easier to work with the code, I have prepared several binaries.
Linux (x86) commands:
wget https://github.com/jvns/dnspeep/releases/download/v0.1.0/dnspeep-linux.tar.gz tar -xf dnspeep-linux.tar.gz sudo ./dnspeep
wget https://github.com/jvns/dnspeep/releases/download/v0.1.0/dnspeep-macos.tar.gz tar -xf dnspeep-macos.tar.gz sudo ./dnspeep
The code needs access to all DNS packets sent by the computer, so it needs to be run as root. For the same reason, tcpdump must also be run as root: the code uses libpcap, the same library as tcpdump. If for some reason you don’t want to download binaries and run them as root, you can use my original code and create your own based on it.
What is the result
Each line represents a DNS request and a corresponding response to the request.
$ sudo dnspeep query name server IP response A firefox.com 192.168.1.1 A: 18.104.22.168, A: 22.214.171.124, A: 126.96.36.199 AAAA firefox.com 192.168.1.1 NOERROR A bolt.dropbox.com 192.168.1.1 CNAME: bolt.v.dropbox.com, A: 188.8.131.52
These requests reflect my visits to neopets.com in a browser, and the bolt.dropbox.com request is because I have a Dropbox agent running and I guess from time to time it comes to my site to sync.
Why Create Another DNS Tool?
I believe that such a tool makes sense, as it can help you better understand how DNS works – without this tool it is rather difficult to understand how DNS behaves on a computer.
Your browser (and other computer programs) are constantly sending DNS requests. Knowing what requests the computer is sending and what responses it receives can give you a more realistic picture of the computer’s “life”.
I also use the code I wrote as a debugging tool. To questions like: “Is my problem related to DNS?” sometimes it is rather difficult to answer. Users, not knowing all the information, often use trial and error to find the problem, or just make guesses, although it would seem that it is worth just analyzing the responses to the DNS queries received by the computer, and the problem will be solved.
You can see what software “secretly” goes online
What I love about this tool is that it gives an idea of what programs on my computer are using the Internet! For example, I found that some utility on my computer from time to time, for some unknown reason, sends requests to ping.manjaro.org, probably to check if my computer is connected to the Internet.
A friend of mine used this tool to find that his computer had corporate monitoring software that he simply forgot to remove when he quit his last job.
If you have not worked with tcpdump before, it may not be clear at first what this utility does.
When I tell people about DNS requests sent from a computer, I almost always want to add: “All information can be obtained through tcpdump!” What does tcpdump do? It parses DNS packets! For example, this is what the incoming.telemetry.mozilla.org DNS request looks like:
11:36:38.973512 wlp3s0 Out IP 192.168.1.181.42281 > 192.168.1.1.53: 56271+ A? incoming.telemetry.mozilla.org. (48) 11:36:38.996060 wlp3s0 In IP 192.168.1.1.53 > 192.168.1.181.42281: 56271 3/0/0 CNAME telemetry-incoming.r53-2.services.mozilla.com., CNAME prod.data-ingestion.prod.dataops.mozgcp.net., A 184.108.40.206 (180)
At first, this information may seem like a “dark forest”, but with some skills you can learn to read it. Let’s analyze the following query as an example:
192.168.1.181.42281 > 192.168.1.1.53: 56271+ A? incoming.telemetry.mozilla.org. (48)
A? stands for DNS-inquiry type A;
incoming.telemetry.mozilla.org. – this is the name of the object to which the request is made;
56271 is the identifier for the DNS request;
192.168.1.181.42281 – source IP / port;
192.168.1.1.53 – destination IP / port;
(48) is the length of the DNS packet.
The answer looks like this:
56271 3/0/0 CNAME telemetry-incoming.r53-2.services.mozilla.com., CNAME prod.data-ingestion.prod.dataops.mozgcp.net., A 220.127.116.11 (180)
3/0/0 – the number of records in the response: 3 responses, 0 authority, 0 optional. From my experience, tcpdump only outputs the number of responses per request.
CNAME telemetry-incoming.r53-2.services.mozilla.com, CNAME prod.data-ingestion.prod.dataops.mozgcp.net. and A 18.104.22.168 are the same three answers
56271 is the response ID that matches the request ID. From this identifier, you can understand that this is a response to the request from the previous line.
It is, of course, quite difficult to work with such a format, because a person just needs to look at the DNS traffic, why all this jumble? And so he has to manually compare requests and responses, moreover, they are not always located on adjacent lines. This is where computing power comes in!
I decided to write a small program – dnspeep, which will perform such a comparison itself, as well as delete certain (in my opinion, unnecessary) information.
Problems I encountered while writing code
While writing the code, I ran into a number of problems.
I had to modify the pcap library somewhat to get it to work correctly with Tokio on Mac OS – behold these changes. It was one of those bugs that took many hours to find, and the whole fix was done on one line.
Different Linux distributions seem to use different versions of libpcap.so, so I was unable to directly use the binary that dynamically links libpcap (other users had the same problem, for example here). Therefore, I had to statically compile libpcap libraries into a tool on Linux. I still don’t understand how to organize this correctly in Rust, but I got what I wanted and it worked – I copied the libpcap.a file to the target / release / deps directory, and then just ran cargo build.
The dns_parser library I use does not support all types of DNS queries, but only some of the most common ones. Perhaps a different library could be used to parse DNS packets, but I did not find a suitable one.
Since the pcap library interface gives out a bunch of bare bytes (including for Ethernet data frames), I had to write the code, which determined how many bytes to strip from the beginning of the line to get the IP header of the packet. But I am sure that there are still “pitfalls” in my task.
By the way, you can’t even imagine what difficulties I had to choose a name for my utility – after all, there are great tools for working with DNS. lots of, and each has its own name (dnsspy! dnssnoop! dnssniff! dnswatch!) At first I wanted to include the word spy (spy) or its synonyms in the name, and then settled on a name that seemed funny to me, which – lo and behold! – no one else has borrowed for their own DNS tool.
My utility has one drawback: it does not tell you which process sent the DNS request, but there is a way out – use the tool dnssnoop… This tool works with eBPF data. From the description, it should work fine, but I haven’t tried it yet.
There are probably still many errors in my code.
I was able to test it only on Linux and Mac, and I already know of at least one error (due to the fact that not all DNS queries are supported). If you find a bug, please let me know!
Errors themselves are not dangerous – the libpcap interface is read-only, the worst thing that can happen is that it receives some incomprehensible data and throws an error or crashes.
I like to compose small study materials
Recently, I have been having a lot of fun writing small tutorials on DNS. Here are links to my previous articles:
Plain way composing DNS queries;
Describes what happens inside the computer when dispatch DNS queries;
Link to dnspeep…
Earlier in my posts, I simply explained how existing tools (such as dig or tcpdump) work, and if I wrote my own tools, it is quite rare. But now it is obvious to me that the output of these tools is rather vague, it is difficult to understand them, so I wanted to create more friendly options for viewing such information so that not only the tcpdump guru, but any other users could understand what DNS requests their computer is sending.
And if you want not only to understand what is happening with DNS requests and responses on your computer, but also to write your own protocols for your applications, pay attention to profession C ++ developer or Java developer, allowing you to master these languages from scratch or pump your knowledge of them. Come – experienced mentors and experts in their field will be happy to share their knowledge with you.
find outhow to level up in other specialties or master them from scratch:
Other professions and courses