Using ruby-pdns for reverse DNS

37 views
Skip to first unread message

renchap

unread,
Nov 6, 2009, 9:25:09 AM11/6/09
to ruby-pdns-users
Hi,

I want to use rub-pdns to handle reverse dns records.

I have a database with (ip,reverse). Some examples of the behavior,
with the 11.22.33.0/24 range handled by the module, with domain
reverse.bar.com
- Request : 44.33.22.11.in-addr.arpa, in the list, answer : PTR
foo.reverse.bar.com
- Request : A foo.bar.com, in the list, answer : 11.22.33.44
- Request 43.33.22.11, not in the list, answer : PTR
11-22-33-43.reverse.bar.com
- Request 11-22-33-43.reverse.bar.com, answer : 11.22.33.43

It seems that I cant do this using ruby-pdns at the moment. I suggest
allowing a regexp in newrecord, which can allow me to add newrecord(/
[0-9]+\.33\.22\.11\.in.addr\.arpa) and newrecord(/.*\.reverse\.bar
\.com/), and this would match all records i need.

Do you have a prefered way to do this ? I will try to add this to this
project, I think reverse dns management is a great use for pipebackend
and your module.

renchap

R.I.Pienaar

unread,
Nov 6, 2009, 9:28:44 AM11/6/09
to ruby-pd...@googlegroups.com
hello,

----- "renchap" <ren...@gmail.com> wrote:

> Hi,
>
> I want to use rub-pdns to handle reverse dns records.
>
> I have a database with (ip,reverse). Some examples of the behavior,
> with the 11.22.33.0/24 range handled by the module, with domain
> reverse.bar.com
> - Request : 44.33.22.11.in-addr.arpa, in the list, answer : PTR
> foo.reverse.bar.com
> - Request : A foo.bar.com, in the list, answer : 11.22.33.44
> - Request 43.33.22.11, not in the list, answer : PTR
> 11-22-33-43.reverse.bar.com
> - Request 11-22-33-43.reverse.bar.com, answer : 11.22.33.43

I too want to be able to do something similar, but for RBLs in my case.

> It seems that I cant do this using ruby-pdns at the moment. I suggest
> allowing a regexp in newrecord, which can allow me to add newrecord(/
> [0-9]+\.33\.22\.11\.in.addr\.arpa) and newrecord(/.*\.reverse\.bar
> \.com/), and this would match all records i need.

Not thought of regex but I guess it could work and would solve both problems in one go, would gladly accept your patches after review.

Don't hesitate to ask if you have questions about the code.

--
R.I.Pienaar

Renaud Chaput

unread,
Nov 6, 2009, 10:12:50 AM11/6/09
to ruby-pd...@googlegroups.com
I think this can be done by changing Pdns::Resolvers::get_resolver
with something like this :

@@resolvers.each do |key, resolver|
if key.class == String
return resolver if key == request
elsif key.class == Regexp
return resolver if request.match(key)
else
# raise some exception about bad class
end
raise(Pdns::UnknownRecord, "Can't answer queries for #{request[:qname]}")

What do you think about this ?
Maybe we can optimize this by adding a check on the @@resolvers hash
at startup, and if it does not contains any Regexp, we revert to the
precedent behaviour which should be faster (one key lookup on a hash).

Maybe we can also try first the lookup, and then check for the
regexps. To do this, we should create 2 hashs to replace @@resolvers,
one with the strings and one with the regexps. This would be more
modular, and maybe we can also add the ability to give a method name
to newrecord, to add even more flexibility.

Which way seems better for you (regarding performance and modularity) ?

--
Renaud Chaput
renaud...@gmail.com
+ 33 6 65 17 20 87

R.I.Pienaar

unread,
Nov 6, 2009, 10:19:13 AM11/6/09
to ruby-pd...@googlegroups.com
hello,

----- "Renaud Chaput" <ren...@gmail.com> wrote:

> I think this can be done by changing Pdns::Resolvers::get_resolver
> with something like this :
>
> @@resolvers.each do |key, resolver|
> if key.class == String
> return resolver if key == request
> elsif key.class == Regexp
> return resolver if request.match(key)
> else
> # raise some exception about bad class
> end
> raise(Pdns::UnknownRecord, "Can't answer queries for
> #{request[:qname]}")

This looks good, though we'd need to test it works :)

> What do you think about this ?
> Maybe we can optimize this by adding a check on the @@resolvers hash
> at startup, and if it does not contains any Regexp, we revert to the
> precedent behaviour which should be faster (one key lookup on a
> hash).
>
> Maybe we can also try first the lookup, and then check for the
> regexps. To do this, we should create 2 hashs to replace @@resolvers,
> one with the strings and one with the regexps. This would be more
> modular, and maybe we can also add the ability to give a method name
> to newrecord, to add even more flexibility.
>
> Which way seems better for you (regarding performance and modularity)

I'm in favor of starting simple, and optimize later, lets get the regex matching working, tested etc with as minimal code changes as possible then later we can optimise it.

Please also if you intend to send in code see if there's any sane unit tests you can write to cover your code and the new features.


--
R.I.Pienaar

Renaud Chaput

unread,
Nov 8, 2009, 1:35:09 PM11/8/09
to ruby-pd...@googlegroups.com
Is it something special to do to run the test suite ? I got some errors :

renchap@thrall ~/dev/ruby-pdns/ruby-pdns/tests $ ruby -r rubygems
tc_resolvers.rb
Loaded suite tc_resolvers
Started
EEEE
Finished in 0.000853 seconds.

1) Error:
test_if_empty_clears_records(TC_ResolversTests):
NoMethodError: undefined method `datadir' for nil:NilClass
/home/renchap/.gem/ruby/1.8/gems/ruby-pdns-0.4.1/lib/pdns/extdata.rb:19:in
`loaddata'
/home/renchap/.gem/ruby/1.8/gems/ruby-pdns-0.4.1/lib/pdns/extdata.rb:7:in
`initialize'
/home/renchap/.gem/ruby/1.8/gems/ruby-pdns-0.4.1/lib/pdns/resolvers.rb:17:in
`new'
/home/renchap/.gem/ruby/1.8/gems/ruby-pdns-0.4.1/lib/pdns/resolvers.rb:17:in
`initialize'
tc_resolvers.rb:15:in `new'
tc_resolvers.rb:15:in `test_if_empty_clears_records'

2) Error:
test_if_handles_mixed_case_as_lower(TC_ResolversTests):
NoMethodError: undefined method `datadir' for nil:NilClass
/home/renchap/.gem/ruby/1.8/gems/ruby-pdns-0.4.1/lib/pdns/extdata.rb:19:in
`loaddata'
/home/renchap/.gem/ruby/1.8/gems/ruby-pdns-0.4.1/lib/pdns/extdata.rb:7:in
`initialize'
/home/renchap/.gem/ruby/1.8/gems/ruby-pdns-0.4.1/lib/pdns/resolvers.rb:17:in
`new'
/home/renchap/.gem/ruby/1.8/gems/ruby-pdns-0.4.1/lib/pdns/resolvers.rb:17:in
`initialize'
tc_resolvers.rb:23:in `new'
tc_resolvers.rb:23:in `test_if_handles_mixed_case_as_lower'

3) Error:
test_if_record_load(TC_ResolversTests):
NoMethodError: undefined method `datadir' for nil:NilClass
/home/renchap/.gem/ruby/1.8/gems/ruby-pdns-0.4.1/lib/pdns/extdata.rb:19:in
`loaddata'
/home/renchap/.gem/ruby/1.8/gems/ruby-pdns-0.4.1/lib/pdns/extdata.rb:7:in
`initialize'
/home/renchap/.gem/ruby/1.8/gems/ruby-pdns-0.4.1/lib/pdns/resolvers.rb:17:in
`new'
/home/renchap/.gem/ruby/1.8/gems/ruby-pdns-0.4.1/lib/pdns/resolvers.rb:17:in
`initialize'
tc_resolvers.rb:6:in `new'
tc_resolvers.rb:6:in `test_if_record_load'

4) Error:
test_if_stats_increment(TC_ResolversTests):
NoMethodError: undefined method `datadir' for nil:NilClass
/home/renchap/.gem/ruby/1.8/gems/ruby-pdns-0.4.1/lib/pdns/extdata.rb:19:in
`loaddata'
/home/renchap/.gem/ruby/1.8/gems/ruby-pdns-0.4.1/lib/pdns/extdata.rb:7:in
`initialize'
/home/renchap/.gem/ruby/1.8/gems/ruby-pdns-0.4.1/lib/pdns/resolvers.rb:17:in
`new'
/home/renchap/.gem/ruby/1.8/gems/ruby-pdns-0.4.1/lib/pdns/resolvers.rb:17:in
`initialize'
tc_resolvers.rb:32:in `new'
tc_resolvers.rb:32:in `test_if_stats_increment'

4 tests, 0 assertions, 0 failures, 4 errors

$ ruby --version
ruby 1.8.7 (2009-06-12 patchlevel 174) [x86_64-linux]


I will need to run the test suite smoothly before trying to add the feature.

--

R.I.Pienaar

unread,
Nov 8, 2009, 2:49:43 PM11/8/09
to ruby-pd...@googlegroups.com
hello,

Not much, you might need to set your libdir, something like

cd tests
export RUBYLIB=.:../lib

and that should get it going

--
R.I.Pienaar

Renaud Chaput

unread,
Nov 8, 2009, 3:01:59 PM11/8/09
to ruby-pd...@googlegroups.com
Hi,

I got the same errors.
Should it work with ruby 1.8.7 (2009-06-12 patchlevel 174) [x86_64-linux] ?

I test this on Gentoo Linux.

R.I.Pienaar

unread,
Nov 8, 2009, 3:06:20 PM11/8/09
to ruby-pd...@googlegroups.com
hello,

Ah I see now these are related to the extdata stuff that code is a bit new and fresh if you're patching it might be best for you to do so against the ruby-pdns-0.5 branch so you can be 100% sure you're working with code I am done writing and that should work, trunk is in a the mids of a big refactor/reshuffle now.

--
R.I.Pienaar

Renaud Chaput

unread,
Nov 8, 2009, 3:59:51 PM11/8/09
to ruby-pd...@googlegroups.com
With 0.5 branch :

renchap@thrall ~/dev/ruby-pdns/tests $ ruby tc_resolvers.rb


Loaded suite tc_resolvers
Started
EEEE

Finished in 0.002105 seconds.

1) Error:
test_if_empty_clears_records(TC_ResolversTests):
NoMethodError: undefined method `logfile' for nil:NilClass
../lib/pdns/log.rb:10:in `initialize'
../lib/pdns.rb:74:in `new'
../lib/pdns.rb:74:in `debug'
../lib/pdns/resolvers.rb:24:in `add_resolver'
../lib/pdns.rb:38:in `newrecord'
./records/test_if_record_load.prb:2
tc_resolvers.rb:16:in `load'
tc_resolvers.rb:16:in `test_if_empty_clears_records'

2) Error:
test_if_handles_mixed_case_as_lower(TC_ResolversTests):
NoMethodError: undefined method `logfile' for nil:NilClass
../lib/pdns/log.rb:10:in `initialize'
../lib/pdns.rb:74:in `new'
../lib/pdns.rb:74:in `debug'
../lib/pdns/resolvers.rb:24:in `add_resolver'
../lib/pdns.rb:38:in `newrecord'
./records/test_if_handles_mixed_case_as_lower.prb:2
tc_resolvers.rb:26:in `load'
tc_resolvers.rb:26:in `test_if_handles_mixed_case_as_lower'

3) Error:
test_if_record_load(TC_ResolversTests):
NoMethodError: undefined method `logfile' for nil:NilClass
../lib/pdns/log.rb:10:in `initialize'
../lib/pdns.rb:74:in `new'
../lib/pdns.rb:74:in `debug'
../lib/pdns/resolvers.rb:24:in `add_resolver'
../lib/pdns.rb:38:in `newrecord'
./records/test_if_record_load.prb:2
tc_resolvers.rb:9:in `load'
tc_resolvers.rb:9:in `test_if_record_load'

4) Error:
test_if_stats_increment(TC_ResolversTests):
NoMethodError: undefined method `logfile' for nil:NilClass
../lib/pdns/log.rb:10:in `initialize'
../lib/pdns.rb:74:in `new'
../lib/pdns.rb:74:in `debug'
../lib/pdns/resolvers.rb:24:in `add_resolver'
../lib/pdns.rb:38:in `newrecord'
./records/test_if_stats_increment.prb:2
tc_resolvers.rb:35:in `load'
tc_resolvers.rb:35:in `test_if_stats_increment'

4 tests, 0 assertions, 0 failures, 4 errors

All other tests works fine.

R.I.Pienaar

unread,
Nov 8, 2009, 5:32:35 PM11/8/09
to ruby-pd...@googlegroups.com
hey,

Try running:

ruby ts_pdns.rb

There seem to be some inter dependencies between tests, the ts_* files are the entire test suite which will run the rest in order

--
R.I.Pienaar

Renaud Chaput

unread,
Nov 9, 2009, 2:59:50 AM11/9/09
to ruby-pd...@googlegroups.com
Ok, this works fine.

Here is my patch. I changed can_answer? and type to use the net
get_resolver, and get_resolver handles String and Regexp. It is easy
to add new types.
The patch contains a test with a regexp that matches, and one that
does not matches.

I think this code can be optimized by using 2 @@resolvers hash, one
with only strings and the other one with the other types. This would
allow to perform as the current 0.5 code when you don't use regexp.

I will try implementing my reverse-dns module using this, and will
post here the result.

regexp.patch

R.I.Pienaar

unread,
Nov 9, 2009, 3:02:12 AM11/9/09
to ruby-pd...@googlegroups.com
Awesome, I'll checkout your patch a bit later.

thanks for persisting, sorry I didnt point out the right branch to use earlier!

--
R.I.Pienaar

R.I.Pienaar

unread,
Nov 9, 2009, 3:52:55 AM11/9/09
to ruby-pd...@googlegroups.com
hello,

I've created a ticket for this with your patch:

http://code.google.com/p/ruby-pdns/issues/detail?id=31

you can join onto the ticket to track its progress,

--
R.I.Pienaar

Renaud Chaput

unread,
Dec 1, 2009, 6:09:29 PM12/1/09
to ruby-pd...@googlegroups.com
Hi,

Using this patch, I made my reverse DNS module. You can find it here :
http://github.com/renchap/ruby-pdns-reverse
The patch works fine for me, but there can be an issue with stats
(havent checked this).

During the development of my module, i ran into some errors (related
to chomp when the backend starts, and another one in module syntax
error handling). I will open tickets for these errors as soon as I
have time.

Do you know if you can include this patch in the 0.5 release ? It
would avoid me to use a custom-made gem.

R.I.Pienaar

unread,
Dec 1, 2009, 6:12:39 PM12/1/09
to ruby-pd...@googlegroups.com
hello,

----- "Renaud Chaput" <ren...@gmail.com> wrote:

> Hi,
>
> Using this patch, I made my reverse DNS module. You can find it here
> : http://github.com/renchap/ruby-pdns-reverse
> The patch works fine for me, but there can be an issue with stats
> (havent checked this).

Thanks for this, I'll take a look soon, another project had me side tracked but its cooling down so will spend some time on this soon.

>
> During the development of my module, i ran into some errors (related
> to chomp when the backend starts, and another one in module syntax
> error handling). I will open tickets for these errors as soon as I
> have time.

Thanks,

> Do you know if you can include this patch in the 0.5 release ? It
> would avoid me to use a custom-made gem.


I'll do a 0.5 release soon with your patches etc, I was going to hold off on a release till I got all the extenral API stuff going but thats still some way off, so will do a interim release.

thanks again.
--
R.I.Pienaar
Reply all
Reply to author
Forward
0 new messages