Is there a good way to correlate DNS requests/responses with subsequent TCP/UDP connections using Bro (in realtime)? With how my tap is configured I can see the client’s DNS request/response and all their traffic. I want to be able to combine their DNS request (if there is one) with the corresponding TCP/UDP following it. For my use case I need this to be done in realtime (not later by simply doing a JOIN). So, I am interested in a single log entry with DNS request/response AND connection info.
It seems like this should be possible by basically doing the following:
dns_response.dst_ip == conn.src_ip AND
conn.dst_ip == dns_response.answer_ip AND
(conn.timestamp - dns_response.timestamp) < THRESHOLD
Has anyone done this? Any guidance would be greatly appreciated.
Thanks,
–Jason
Are you running a cluster? This type of problem is one of the hardest to solve on distributed analysis.
Otherwise if you are running a single node then it should be fairly easy. I *think* you would essentially want to create a 2-tuple set with a short timeout.
global watch_for_connections: set[addr, addr] = {} &create_timeout=2secs;
You would fill out that set in one or more DNS event handlers and then check to see if any connections are being made in a connection_established handler.
Again though, if you are running a cluster this is a really hard problem.
.Seth
I think Seth meant &create_expire. But yeah, this is totally possible if you’re running a single node/standalone mode. You could also use something like
type DNSqr record {
query: string;
asking_host: addr;
};
dns_query_cache: table[addr] of DNSqr &create_expire=2secs;
where the dns_query_cache is indexed by answer addresses (the a value in dns_A_reply events).
-AK