nodejs / help

:sparkles: Need help with Node.js? File an Issue here. :rocket:
1.46k stars 279 forks source link

DNS: query for for authority section or additional section #634

Closed alexte closed 6 years ago

alexte commented 7 years ago

Is it possible to get the additional Authority Section and Additinal Section from an TLD or root name server using the dns module in nodejs?

dns=require("dns");
dns.setServers(["192.33.14.30"]);
dns.resolveNs("google.com",console.log);

Results in "ENODATA"

This is actually correct because the .com TLD name server "192.33.14.30" does not answer a direct query. But it would answer with an "authority section":

> host -v -t NS google.com 192.33.14.30
Trying "google.com"
Using domain server:
Name: 192.33.14.30
Address: 192.33.14.30#53
Aliases: 

;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 57942
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 4, ADDITIONAL: 4

;; QUESTION SECTION:
;google.com.                    IN      NS

;; AUTHORITY SECTION:
google.com.             172800  IN      NS      ns2.google.com.
google.com.             172800  IN      NS      ns1.google.com.
google.com.             172800  IN      NS      ns3.google.com.
google.com.             172800  IN      NS      ns4.google.com.

;; ADDITIONAL SECTION:
ns2.google.com.         172800  IN      A       216.239.34.10
ns1.google.com.         172800  IN      A       216.239.32.10
ns3.google.com.         172800  IN      A       216.239.36.10
ns4.google.com.         172800  IN      A       216.239.38.10

I am currently working on a service that is checking if domains are registered correctly. And for this I'm comparing my local NS list to the authorativ NS records in the TLD.

ipeychev commented 7 years ago

@alexte I'm also looking for a way to get the AUTHORITY SECTION via Node. Since you are ahead with this issue, were you able to find a solution?

alexte commented 7 years ago

The work arround to this issue was a library called "native-dns". https://www.npmjs.com/package/native-dns

But take care, it's a bit tricky! This library is not threaded save, so make only one query after the other.

ipeychev commented 7 years ago

Yeah, I looked at this library too but I felt using another library instead the built in dns module would be too much :) It seems however that's the right direction, thanks for the confirmation.

Fishrock123 commented 7 years ago

I feel like this should be a feature request to https://github.com/nodejs/node?

Fishrock123 commented 7 years ago

(Asking detailed and direct API questions like this on the main repo is certainly ok.)

ipeychev commented 7 years ago

Thanks @Fishrock123 for the heads up! @alexte Feeling like someone who would open such a feature request? :)

alexte commented 7 years ago

I would definitely support the request for this feature, but I think it's quite unlikely. The underlying c-ares DNS library doesn't support Authority queries I think (but I may be wrong).

Hence this feature would be a rather big rewrite of the dns.js module. I looked into it to provide a pull request myself, but it's to far from the current simple "dns.js" file which uses "cares-wrap.cc".

Perhaps a separate library is the correct place for this feature at the moment.

addaleax commented 7 years ago

The underlying c-ares DNS library doesn't support Authority queries I think (but I may be wrong).

It doesn’t look that way, yes. On the other hand DNS is a pretty simple protocol, it shouldn’t be hard to add support if we like, in Node or even upstream.

I looked into it to provide a pull request myself, but it's to far from the current simple "dns.js" file which uses "cares-wrap.cc".

If you want to do this, I’d be more than glad to provide any assistance I can offer :) I have a pretty good understanding of how the current dns implementation in Node works, I’d say.

alexte commented 7 years ago

OK great. I will give this project a second attempt, when I return from holiday.

Some thoughts:

You are right DNS is simple, but it is getting more complicated: The 512 byte limit as defined in RFC1035 is getting tight therefor IETF tries to push towards mandatory TCP if the server answers with TC bit set (RFC7766)

Would the nodejs community prefer to stay with c-ares or rather like a native implementation like native-dns?

addaleax commented 7 years ago

Would the nodejs community prefer to stay with c-ares or rather like a native implementation like native-dns?

@alexte I’m not sure. As long as c-ares is working, I guess we’re sticking to that, and with very few exceptions Node explicitly encourages the existence of alternative userland implementations when that makes sense.

tniessen commented 7 years ago

The underlying c-ares DNS library doesn't support Authority queries I think (but I may be wrong).

There is no such thing as "authority queries" as far as I know, instead, each DNS message can contain an arbitrary number of authority RRs.

c-ares partially supports authority RRs, the data is there, it's just that there is not really a lot of API around those RRs. If you don't feel like implementing something, I could give it a try @alexte, I already know some of the c-ares code.

alexte commented 7 years ago

@tniessen your are right there is no authority queries, but every dns answer includes a "question" section and my include an "answer", "authority" and "additional" section. The counters per section in the packet are called "QDCOUNT", "ANCOUNT", "NSCOUNT" and "ARCOUNT" in the RFC and the c-ares source.

After reading the source of c-ares it looks to me that the api helper functions like in "ares_parse_ns_reply.c", just use the QDCOUNT and ANCOUNT. NSCOUNT and ARCOUNT are actually ignored. But parts of the c-ares source like adig.c implement a parser for this.

I think it would be a very useful addition to c-ares, if you could implement that, but I don't know if the maintainers would include that ?

tniessen commented 7 years ago

@alexte Thanks, I know the structure of DNS messages :) However, I am not too sure about the constraints which the last two sections are subject to, so I tried to get in touch with the c-ares maintainers. We should probably await their response before taking any further action.

Upate: Here is my inquiry to the team behind c-ares. (They should really enable UTF8 on their mail archives.)

refack commented 7 years ago

Will the new resolveAny API be of any help? (Or does it need extending?)

> dns.resolveAny('github.com', console.log)
QueryReqWrap {
...
}
> null [ { address: '192.30.253.113', ttl: 59, type: 'A' },
  { address: '192.30.253.112', ttl: 59, type: 'A' },
  { exchange: 'ALT1.ASPMX.L.GOOGLE.com', priority: 5, type: 'MX' },
  { exchange: 'ALT4.ASPMX.L.GOOGLE.com', priority: 10, type: 'MX' },
  { exchange: 'ASPMX.L.GOOGLE.com', priority: 1, type: 'MX' },
  { exchange: 'ALT2.ASPMX.L.GOOGLE.com', priority: 5, type: 'MX' },
  { exchange: 'ALT3.ASPMX.L.GOOGLE.com', priority: 10, type: 'MX' },
  { value: 'ns4.p16.dynect.net', type: 'NS' },
  { value: 'ns2.p16.dynect.net', type: 'NS' },
  { value: 'ns-421.awsdns-52.com', type: 'NS' },
  { value: 'ns-1283.awsdns-32.org', type: 'NS' },
  { value: 'ns1.p16.dynect.net', type: 'NS' },
  { value: 'ns-1707.awsdns-21.co.uk', type: 'NS' },
  { value: 'ns3.p16.dynect.net', type: 'NS' },
  { value: 'ns-520.awsdns-01.net', type: 'NS' },
  { entries: [ 'docusign=087098e3-3d46-47b7-9b4e-8a23028154cd' ],
    type: 'TXT' },
  { entries: [ 'v=spf1 ip4:192.30.252.0/22 include:_spf.google.com include:esp.github.com include:_spf.createsend.com include:mail.zendesk.com include:servers.mcsv.net ~all' ],
    type: 'TXT' },
  { nsname: 'ns1.p16.dynect.net',
    hostmaster: 'hostmaster.github.com',
    serial: 1501060715,
    refresh: 3600,
    retry: 600,
    expire: 604800,
    minttl: 60,
    type: 'SOA' } ]
tniessen commented 7 years ago

@refack Not really, it is not the same. resolveAny just gives you all resource records associated with the given name. A nameserver might not have any resource records about a given name, but he might still be able to point to the authority which keeps those records:

$ host -t ANY -v google.com 192.33.14.30
Trying "google.com"
Using domain server:
Name: 192.33.14.30
Address: 192.33.14.30#53
Aliases:

;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 54097
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 4, ADDITIONAL: 4

;; QUESTION SECTION:
;google.com.                    IN      ANY

;; AUTHORITY SECTION:
google.com.             172800  IN      NS      ns2.google.com.
google.com.             172800  IN      NS      ns1.google.com.
google.com.             172800  IN      NS      ns3.google.com.
google.com.             172800  IN      NS      ns4.google.com.

;; ADDITIONAL SECTION:
ns2.google.com.         172800  IN      A       216.239.34.10
ns1.google.com.         172800  IN      A       216.239.32.10
ns3.google.com.         172800  IN      A       216.239.36.10
ns4.google.com.         172800  IN      A       216.239.38.10

Received 164 bytes from 192.33.14.30#53 in 11 ms
alexte commented 7 years ago

@refack : as @tniessen says resolveAny just gives you the answer section and not the authority section.

BTW: the QTYPE=ANY will propably fail sooner or later, because it leads to DDoS amplification due to big responses, and IEFT discourages answering to QTYPE=ANY queries with long answers. Read on https://datatracker.ietf.org/doc/draft-ietf-dnsop-refuse-any/ I have already seen big nameservers not answering ANY queries at all.

refack commented 7 years ago

Should we then have a "NODE_ANY" that queries all "interesting" types? Or is that an edge case? (just apropo, I had to do just that today while migrating a few domains to new DNS servers...)

gireeshpunathil commented 6 years ago

We already have a tracking issue for this, so closing in favor of https://github.com/nodejs/node/issues/14713