hsd icon indicating copy to clipboard operation
hsd copied to clipboard

rpc: add getnamedns method

Open tynes opened this issue 6 years ago • 6 comments

This PR adds a new Node rpc method called getnamedns. It accepts two arguments - the name (string) and a type (string). It will resolve the DNS query using the recursive resolver, and return the DNS response in JSON format.

I plan on using this RPC method to help people visualize what DNS messages look like. It is also a way for people to query against their local node without using something like dig. I do not recommend using this method in production, although a DoH proxy could be built on top of it.

tynes avatar Oct 08 '19 16:10 tynes

Codecov Report

Merging #266 into master will decrease coverage by 0.02%. The diff coverage is 25%.

Impacted file tree graph

@@            Coverage Diff            @@
##           master    #266      +/-   ##
=========================================
- Coverage   53.12%   53.1%   -0.03%     
=========================================
  Files         129     129              
  Lines       35751   35779      +28     
  Branches     6023    6027       +4     
=========================================
+ Hits        18993   18999       +6     
- Misses      16758   16780      +22
Impacted Files Coverage Δ
lib/dns/records.js 11.25% <100%> (+0.46%) :arrow_up:
lib/node/rpc.js 24.54% <12.5%> (-0.19%) :arrow_down:
lib/covenants/rules.js 73.04% <0%> (-0.15%) :arrow_down:

Continue to review full report at Codecov.

Legend - Click here to learn more Δ = absolute <relative> (impact), ø = not affected, ? = missing data Powered by Codecov. Last update 7c17227...90f3adf. Read the comment docs.

codecov-io avatar Oct 08 '19 16:10 codecov-io

How do you feel about a rpc like listnametypes which help the user get a list of currently supported types?

Would this accept a name and return a list of possible query types that are present for the name? Meaning the query types that will result in actual resource records being returned. Or would it be all the possible query types? Its a tradeoff, the client could just list them if you pass --help, but then all clients would need to implement something like that. It would be nice to solve it for everybody, but then we are sticking more dev tools into the RPC.

The motivation behind this PR is to allow a browser to directly query the DNS records. I am not sure if this is cache efficient, so that may be worth investigating before this is merged because we could potentially figure out a more cache efficient way of doing it.

If we add DNS over HTTPS, then this may not be necessary, as then it will be possible to resolve the DNS records from the browser. The header type application/dns+json (or something like that, the RFC defines it) could be used to return the DNS response in JSON, similar to the RPC

tynes avatar Oct 26 '19 18:10 tynes

Now that I've thought about it more, I'd rather make this an HTTP endpoint rather than an RPC. For people that already have a DNS over HTTPS setup, it would allow for hsd and a TLS terminating proxy to be a drop in replacement. I agree that DoH isn't ideal because it relies on the traditional CA system, but it seems like most of the traditional tech world is moving that direction and plugging into that network effect would only help with adoption.

tynes avatar Nov 18 '19 18:11 tynes

@pinheadmz I just rebased and cleaned up this PR, what do you think?

The RPC endpoint getnamedns does DNS resolution by hooking into the rs and then returns the DNS response in JSON format. I do not recommend using this RPC for applications that need to highly scale, but I see a couple of benefits:

  • Webapps can now use an RPC client to access the state tree/DNS and then use window.location to redirect, meaning they do not need to rely on the OS resolver to be configured in a particular way
  • More people will be able to better visualize what a DNS message looks like

tynes avatar May 11 '20 21:05 tynes

I'm not sure I see the use case for this when we already have rpc getnameresource along with the regular DNS API in the resolver?

pinheadmz avatar May 18 '20 12:05 pinheadmz

I think I'm coming around on this one, it allows for some interesting applications that connect to hsd (or even a browser-based spv node) without having to rely on DNS protocol. There's already been some browser extensions introduced for HNS, I think this function will be useful.

Do you think we need any more work on this PR? Any way to test it? You also mention moving it to HTTP instead of RPC. Any more thoughts on that?

Pretty cool, also includes RRSIG:

$ hsd-rpc getnamedns _tcp._443.proofofconcept tlsa
{
  "id": 0,
  "opcode": "QUERY",
  "code": "NOERROR",
  "qr": true,
  "aa": false,
  "tc": false,
  "rd": true,
  "ra": true,
  "z": false,
  "ad": true,
  "cd": false,
  "question": [
    {
      "name": "_tcp._443.proofofconcept.",
      "class": "IN",
      "type": "TLSA"
    }
  ],
  "answer": [
    {
      "name": "_tcp._443.proofofconcept.",
      "ttl": 3600,
      "class": "IN",
      "type": "TLSA",
      "data": {
        "usage": 3,
        "selector": 1,
        "matchingType": 1,
        "certificate": "22e3c95a736e370fa38e7d94239f49c7a9ef961af94e05ae8cc74fc3ca2ba5ce",
        "usageName": "DIC",
        "selectorName": "SPKI",
        "matchingTypeName": "SHA256"
      }
    },
    {
      "name": "_tcp._443.proofofconcept.",
      "ttl": 86400,
      "class": "IN",
      "type": "RRSIG",
      "data": {
        "typeCovered": "TLSA",
        "algorithm": 8,
        "labels": 3,
        "origTTL": 3600,
        "expiration": 1643305989,
        "inception": 1611683589,
        "keyTag": 58608,
        "signerName": "proofofconcept.",
        "signature": "tojaWY3E3bj6iBZSqkwgyz0QhaFMxIh/wt4qdT7QnMhLmd6Sq/cfXTTe1BrE8hYDwKjpIv+O7ZDTtPkWzfnswKx0Ffy1ZDyIBzF+YTQhWvs65ds7NmLaR/cGWqYSPY5PusaVXibAbhwf/I1kzu4M2ni9wq7BxIHHv39IDdoTsOw8EbQClSRMia6ebeUvDa1cfyC5EYXGoVb+T8TuL12OI5o6fYtQABZ1zKip95/S9xld2afejxGfxbFS/vwwVGIFr/ZlNwQE/7h14UPtPCFS5gTD3NUCstMIWxY9gksvqaxHWOpT3IltWadq2+VR7EAwkzLRZU2B1nIQqAEKWoCbYQ==",
        "algName": "RSASHA256"
      }
    }
  ],
  "authority": [],
  "additional": [],
  "edns": {
    "enabled": true,
    "size": 4096,
    "code": 0,
    "version": 0,
    "dnssec": true,
    "options": []
  },
  "size": 402
}

pinheadmz avatar Jan 27 '21 17:01 pinheadmz