Skip to content

Conversation

@ShogunPanda
Copy link

Currently the server respond only to a rule explicitilly configured for ANY RR requests.
Instead, in case of ANY requests, it should completely skip resource class matching.

@ioquatix
Copy link
Member

This looks good, but can you explain to me a bit more about the typical use-case?

@ShogunPanda
Copy link
Author

That's pretty simple... :)

Let's say you just try to run the example at test/example1.rb.
Then, on another terminal, just issue this query: dig @127.0.0.1 any test1.mydomain.org.

As you can see, you won't get any reply from the server. This because it's trying to match the resource class ANY against the rule class. But, instead, you should skip the resource class at all.

The only problem I saw is in Transaction#respond!. With a ANY query you don't have a good default for @resource_class and you can't instantiate the resource. We should set a default value: is A record a good candidate?

Hope my explanation is useful.
Best regards!
Shogun

@ioquatix
Copy link
Member

Right, so you'd like to include a special treatment of Resolv::DNS::Resource::IN::ANY, rather than just writing a rule to match against it?

Semantically, I'm assuming that Resolv::DNS::Resource::IN::ANY is support to return all records that match?, e.g. CNAME, A, etc?

@ShogunPanda
Copy link
Author

Yes, a ANY record should return any record that matchs (A, CNAME etc) (as stated here).

So we shouldn't require the user to write a specific rule for that.

@ioquatix
Copy link
Member

Do you think this is a good default behaviour, maybe we should make it an option that can be switched on or off, it sounds like the type of record that could be exploited easily. Already, one can specify multiple RR types for a given block that will match, if the user intends for this behaviour wouldn't it be better to specify it explicitly?

If it was on by default, how about if the user didn't want that behaviour by default, how would they switch it off?

Finally, the default behaviour for all existing RubyDNS scripts would be changed by the above patch. Do you think this is a problem?

@ShogunPanda
Copy link
Author

Probably you're right... this could lead to exploits and to user confusion.
I ended up on including an option called :match_resource_class (with a default of true) that will skip resource class matching.

Additionally, when it is a ANY request or a ANY response, I also set Transaction#answer_resource_class to give a good default for the answer. The class will be the first non ANY class specified by the user or IN::A by default.
How do you see this modfications?

@ShogunPanda
Copy link
Author

Some modification are still pending. Please wait for a next commit.

@ioquatix
Copy link
Member

Keep in mind that in the patch you are referring to IN::ANY, yet there are a variety of resource classes other than IN, it seems like a more generic approach would be better? Not that classes other than IN are very practical these days..

Just wondering if there is some way to keep the main pattern matching simple and with some extra option to handle the ANY case. Keep in mind that the more complex the pattern matching code, the harder it is to maintain and use.

@ShogunPanda
Copy link
Author

Ok, all commit are there now. The request is ready.

What do you mean by "other classes than IN"? ANY is the only class which acts as wildcard, AFAIK.
The approach I wrote is quite general I think... can you show me a case for which doesn't act well?

@ioquatix
Copy link
Member

While it is highly unlikely, there are more than one kind of address class. IN::A is an internet address, but there are other address class e.g. CHAOS for chaos network names.

http://www.miek.nl/s/2f9a7850f8/

In this case, the patch includes a hard-coded reference IN::ANY, yet DNS has lots of different resource classes. It isn't impossible to imagine that someone would use RubyDNS for a real mashup - that is kind of the point, it isn't your average DNS server - you can do all sorts of whacky things with it.

I will review the patch when I have a moment.

@ShogunPanda
Copy link
Author

Ok, I'll take a look to all address classes

@ioquatix
Copy link
Member

I think what you've done so far looks really good.

Here is the crux of the issue as I see it. What you want to do is basically have all handlers match against IN::ANY or even ANY, in addition to the original resource record type.

Essentially what this looks like is:

match("80.0.0.10.in-addr.arpa", [IN::PTR, IN::ANY]) do |transaction| transaction.respond!(Name.create("dev.mydomain.org.")) end 

So for each rule you simply allow it to match IN::ANY. However, as you've correctly asserted, there is no way to know exactly what kind of rule to return. This is even more subtle in the sense that there are few, if any, records that you'd want to have the same kind of response.

The main case for matching multiple resource record types is if you are passing the request upstream. For example, you might want to pass all requests to *.google.com to a specific handler, or you might want to only pass A and AAAA requests.

In order to process IN::ANY, you may want to serve local records but avoid passing this upstream to other DNS servers. This customisation is completely arbitrary.

When responding to ANY, in the case that you match [IN::A, IN::PTR, IN::AAAA], should we respond with a record for each type? Its almost like IN::ANY needs to enumerate all possible types and then send all records.

Perhaps we need to write:

match("80.0.0.10.in-addr.arpa", [IN::A, IN::AAAA], :any => :all) do ... match("80.0.0.10.in-addr.arpa", [IN::A, IN::AAAA], :any => [IN::AAAA]) do ... 

I think I need to think about this problem a bit more.

@ShogunPanda
Copy link
Author

Ok, but for your last concern I suggest you to leave it to the user. He should make the decision of which class return to the user.

@ioquatix
Copy link
Member

There is one other option, to have an explicit clause to match ANY requests, and then fire requests back through the rules for specific cases, e.g. A, AAAA and so on. This way, we preserve existing behaviour and make the handling of ANY explicit, but without imposing a per-rule burden/cost. I may explore this option as a counter proposal so we have something to compare with.

@ShogunPanda
Copy link
Author

Good idea... I'll take a look to a possible implementation...

@ShogunPanda
Copy link
Author

Ok, I followed your suggestion and simply make the server process a rule for every type in case of ANY requests.
The patch is much more cleaner and the behavior of the software is still the same :)
Hope this helps!

@ioquatix ioquatix closed this Jul 15, 2012
@ioquatix
Copy link
Member

Hi ShogunPanda - thanks for all the effort you put into this. In the end I think it is best that the RubyDNS transaction resolver is kept as simple as possible.

To clarify, the goal of RubyDNS is to be a programmable DNS domain specific language, without making any assumptions about what you might want to do with that.

I've released RubyDNS 0.4.1 which shows how to implement ANY requests with a minimum of changes and a large degree of flexibility, I believe this should meet your requirements efficiently.

I hope this is sufficient for your needs - please let me know how you get on.

Again, thanks for all your effort and do let me know if you have any more ideas.

Kind regards,
Samuel

@ioquatix
Copy link
Member

Please checkout the example1.rb file which shows the code required =)

@ShogunPanda
Copy link
Author

Ok, I implemented it following your suggestion.
Thanks for your help!

If you'd like to check the results, they are here: http://github.com/ShogunPanda/devdnsd.

@ioquatix
Copy link
Member

Looks good - that project looks interesting, thanks for sharing it with me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants