zmap/zdns

zdns does not follow cnames during iterative mode ptr lookups

herrin opened this issue · 6 comments

echo 199.33.224.123 | /opt/rdns6/zdns PTR --iterative

{"data":{"answers":[{"answer":"cnameptrtest.dirtside.com.","class":"IN","name":"123.224.33.199.in-addr.arpa","ttl":86400,"type":"CNAME"}],"protocol":"udp","resolver":"45.63.13.121:53"},"name":"199.33.224.123","status":"NOERROR","timestamp":"2023-12-04T16:33:42Z"}

Asked it for a PTR but it only gave me the intermediate CNAME. When not using iterative mode, I see the expected behavior:

echo 199.33.224.123 | /opt/rdns6/zdns PTR --name-servers 8.8.8.8

{"data":{"additionals":[{"flags":"","type":"EDNS0","udpsize":512,"version":0}],"answers":[{"answer":"cnameptrtest.dirtside.com.","class":"IN","name":"123.224.33.199.in-addr.arpa","ttl":21600,"type":"CNAME"},{"answer":"acnamename.dirtside.com.","class":"IN","name":"cnameptrtest.dirtside.com","ttl":600,"type":"PTR"}],"protocol":"udp","resolver":"8.8.8.8:53"},"name":"199.33.224.123","status":"NOERROR","timestamp":"2023-12-04T16:35:50Z"}

This is "expected" behavior for that particular module. The raw protocol modules return back to you the exact output received from the server (recursive or authoritative server, depending on the mode). We aren't doing anything different in the recursive case here, 8.8.8.8 is just happening to helpfully also hand back the second record.

That said, obviously, most of the time you want to follow the CNAME, which is why we have the secondary lookup modules. I believe that the right course of action here is to create a ptr-lookup module that matches what we have for A and MX records, but for PTR lookups. [Updated Below]

That's actually really weird. The only times you -don't- want to follow a CNAME are if the user requested a CNAME type or requested ANY records for the name. For every other record type, a CNAME return means: follow me.

While that use case is often useful for lookups (and hence why we do have the lookup modules), the raw result is often quite useful for research. In the end, I think that both have their own uses.

Well, yes. And no. And that's not really the point.

I'm trying to use zdns for some data collection at CAIDA. Discarding the information about the CNAME would be bad. If there's a CNAME in the middle, I want to know. But failing to follow it is also bad. That means I have to deal with a bunch of extra logic in what is supposed to be a simple shell script to go and resolve those CNAMES.

I don't just want to follow CNAMES to A and PTR records. I want it for -every- record type. SOA records, MX records, NS records, whatever. Because that's what a CNAME is. It means that other name over there holds the data I'm looking for.

So implementing a special module to follow CNAMES in A records and a special module to follow CNAMES in PTR records is weird. It makes more sense to me for it to be a flag to any lookup type. Follow them and give me the complete chain. Or don't follow them.

That makes sense to me. CNAME/DNAME are pretty consistent across record types. The "special case" ones are MX record (as you said) and "IP address" where both A and AAAA records are wanted. The latter one could probably be generalized by accepting more than one record type at a time. "echo www.google.com | zdns A AAAA" instead of just "zdns A".