[ANN] RubyDNS - asynchronous DNS client and server for Ruby

Hi,

I wanted to share a gem I made and I've got a fun demonstration.

I was always interested in DNS clients and servers and at one point I had a
very specific setup with servers behind an ADSL NAT connection, which meant
that locally resolved names pointed to servers inside the NAT while
externally resolved names should point at the ADSL modem which had
appropriate VHOST rules. Thus, was born RubyDNS.

RubyDNS is an infinitely flexible DNS server which includes an asynchronous
DNS client to ensure non-blocking behaviour when forwarding requests
upstream. It is built on EventMachine which theoretically should provide a
good asynchronous foundation for processing DNS requests and integration
with other asynchronous systems (e.g. em-http-request).

For fun, I made an example. WikipediaDNS allows you to query wikipedia via
DNS, e.g.:

:slight_smile: > dig +tcp +short @ayako.oriontransfer.org computer.wikipedia TXT
"A computer is a general purpose device that can be programmed to carry out
a finite set of arithmetic or logical operations. Since a sequence of
operations can be readily changed, the computer can solve more than one
kind of problem."

I'm running it on my VPS (temporarily for this demonstration, don't expect
this to be a permanent home) and you can also run it locally, the code is
available:
https://github.com/ioquatix/rubydns/blob/master/test/examples/wikipedia-dns.rb-
in this example, I've forced +tcp as udp seems to be blocked, at least

RubyDNS has been used in a number of interesting systems, including
Murakumo, a distributed peer-to-peer DNS system, and along side vagrant to
provide dynamically registered DNS names for dynamically created virtual
hosts. Someone also contacted me recently about using it for full scale
network integration testing and also browser level testing of some sort. It
was used in f***PSN, a tool for bypassing the PSN network, and has been
also used in SiriProxy (I'm sure you can guess what it does).

I'd love to share RubyDNS with the hope that I see more interesting
projects developed on top of it. I get really excited thinking about all
the possibilities. For example it would be really interesting to make a
client-server architecture for sending data via DNS, perhaps some kind of
DNS port knocking security system, better integration of information
systems with DNS (e.g. mapping "document database" to DNS records).

Source code is available: https://github.com/ioquatix/rubydns

Project home page with introduction video and documentation:
http://www.codeotaku.com/projects/rubydns/index.en

Kind regards,
Samuel

···

from my current location.

Hi Samuel,
i was looking for hints/docs if it would be possible to create virtual
domains using rubydns. The dbs are stored in text (djbdns format) and db
(sqlite or postgres)..
thanks for rubydns gem.
kind regards -botp

···

On Tue, May 21, 2013 at 9:05 PM, Samuel Williams < space.ship.traveller@gmail.com> wrote:

Source code is available: GitHub - socketry/rubydns: A DSL for building fun, high-performance DNS servers.
Project home page with introduction video and documentation:
RubyDNS

I'm wondering if it's possible to use rubydns to diagnose an issue on my
local network. I'm having an issue with a particular server and I
believe that it's related to an extremely low TTL setting. I'd like to
try running my response time tests with custom TTL's for those domains.
I've gone through the video on your site and the documentation provided
and didn't see how I could pull this off.

I need to know how to:

1. Override the TTL only when a specific DNS query is made.
2. Ensure that the tests running from my local machine will use rubydns
to resolve the domain instead of my main system DNS (I'm running OSX
fwiw). Right now my only thought is to change my network settings to use
127.0.0.1 as my DNS.

Any insight you could provide would be welcome. Thanks and great tool!

···

--
Posted via http://www.ruby-forum.com/.

I answered my own question. The example on the github README and the
API docs illustrate how to do it. All I have to do to test anything else
example.

Returning the TTL was as easy as adding ttl: 30 to the
transaction.response. Great piece of code you have here.

···

from my local machine is set my local DNS to 127.0.0.1 with that

--
Posted via http://www.ruby-forum.com/.

Hi botp, you can create any configuration of DNS you like. RubyDNS doesn't
have a concept of zone files or anything like that, perhaps you can give me
more details about what you mean exactly by virtual domains?

···

On 22 May 2013 02:03, botp <botpena@gmail.com> wrote:

On Tue, May 21, 2013 at 9:05 PM, Samuel Williams < > space.ship.traveller@gmail.com> wrote:

Source code is available: GitHub - socketry/rubydns: A DSL for building fun, high-performance DNS servers.
Project home page with introduction video and documentation:
RubyDNS

Hi Samuel,
i was looking for hints/docs if it would be possible to create virtual
domains using rubydns. The dbs are stored in text (djbdns format) and db
(sqlite or postgres)..
thanks for rubydns gem.
kind regards -botp

Hi Samuel,
apologies in advance for any stupid question.
Maybe i should simplify my q:

say, I have a list of names w corresponding ip addresses in a text file.
now if a query comes in asking for an ip (among others) of a name, i'd look
inside the text file for that name, and output the ip if any...

problem is, i'd like to get more info about the query.. like what, where is
it coming fr, etc..

thanks again,
-botp

···

On Wed, May 22, 2013 at 7:02 AM, Samuel Williams < space.ship.traveller@gmail.com> wrote:

Hi botp, you can create any configuration of DNS you like. RubyDNS doesn't
have a concept of zone files or anything like that,...

Hi, you can use geo-ip for finding the location, geographically speaking.
There is an example of how to do this:
https://github.com/ioquatix/rubydns/blob/master/test/examples/geoip-dns.rb#L40-L41

You'll need to follow the instructions L40-41 to get a geo-ip database.
Does that answer your question?

···

On 22 May 2013 14:02, botp <botpena@gmail.com> wrote:

On Wed, May 22, 2013 at 7:02 AM, Samuel Williams < > space.ship.traveller@gmail.com> wrote:

Hi botp, you can create any configuration of DNS you like. RubyDNS
doesn't have a concept of zone files or anything like that,...

Hi Samuel,
apologies in advance for any stupid question.
Maybe i should simplify my q:

say, I have a list of names w corresponding ip addresses in a text file.
now if a query comes in asking for an ip (among others) of a name, i'd
look inside the text file for that name, and output the ip if any...

problem is, i'd like to get more info about the query.. like what, where
is it coming fr, etc..

thanks again,
-botp

sorry Samuel, i confused you again.
when i say IP, i just meant the ip address of the client querying my dns
server.

for now, i just want to get two things from the requesting client:
1 the ip of the client
2 the query object (and its attributes) issued by the client

···

On Wed, May 22, 2013 at 1:45 PM, Samuel Williams < space.ship.traveller@gmail.com> wrote:

Hi, you can use geo-ip for finding the location, geographically speaking.
There is an example of how to do this:
https://github.com/ioquatix/rubydns/blob/master/test/examples/geoip-dns.rb#L40-L41You’ll need to follow the instructions L40-41 to get a geo-ip database.
Does that answer your question?

1.
https://github.com/ioquatix/rubydns/blob/master/test/examples/geoip-dns.rb#L57
2.
https://github.com/ioquatix/rubydns/blob/master/lib/rubydns/transaction.rb#L43-L51

Does that help?

···

On 22 May 2013 22:02, botp <botpena@gmail.com> wrote:

On Wed, May 22, 2013 at 1:45 PM, Samuel Williams < > space.ship.traveller@gmail.com> wrote:

Hi, you can use geo-ip for finding the location, geographically speaking.
There is an example of how to do this:
https://github.com/ioquatix/rubydns/blob/master/test/examples/geoip-dns.rb#L40-L41You’ll need to follow the instructions L40-41 to get a geo-ip database.
Does that answer your question?

sorry Samuel, i confused you again.
when i say IP, i just meant the ip address of the client querying my dns
server.

for now, i just want to get two things from the requesting client:
1 the ip of the client
2 the query object (and its attributes) issued by the client

Hello,

Hi, you can use geo-ip for finding the location, geographically speaking. There is an example of how to do this: https://github.com/ioquatix/rubydns/blob/master/test/examples/geoip-dns.rb#L40-L41 You'll need to follow the instructions L40-41 to get a geo-ip database. Does that answer your question?

sorry Samuel, i confused you again.
when i say IP, i just meant the ip address of the client querying my dns server.

for now, i just want to get two things from the requesting client:
1 the ip of the client
2 the query object (and its attributes) issued by the client

I'm a bit offtopic really but, I think the 'correct' way to do this would be to monitor the DNS requests issued either by RubyDNS or any other DNS server/client at port UDP:53 with a firewall (pf, iptables, ipfw, etc) or tcpdump grab the values that are of interest from their logs and then run a ruby (or pythong, or whatever) script that collects the info you want.

Best Regards,

Panagiotis (atmosx) Atmatzidis

email: atma@convalesco.org
URL: http://www.convalesco.org
GnuPG ID: 0x1A7BFEC5
gpg --keyserver pgp.mit.edu --recv-keys 1A7BFEC5

···

On 22 Μαϊ 2013, at 12:02 , botp <botpena@gmail.com> wrote:

On Wed, May 22, 2013 at 1:45 PM, Samuel Williams <space.ship.traveller@gmail.com> wrote:

--
The wise man said: "Never argue with an idiot. They bring you down to their level and beat you with experience."

in a way, yes. But in this case i do it mainly for 2 reasons:
1 defense in-depth. protection at network level + protection at application
level
2 split dns

now, as to why rubydns interest me:
1 rubydns would shine on environments w heterogeneous dns setup, some have
bind, djbdns, etc... using ruby(dns), i wont have problems reading their
differing databases..
2 adhoc dns.. eg, i can just run a temp rubydns, while i fix their
problematic bind dns...
3 scale and economics. install ruby & deploy.
4 collaboration. my ruby/rails/sinatra apps can now communicate
seamlessly & natively with our dns servers...

kind regards
-botp

···

On Thu, May 23, 2013 at 4:08 AM, Panagiotis Atmatzidis <atma@convalesco.org>wrote:

I'm a bit offtopic really but, I think the 'correct' way to do this would
be to monitor the DNS requests issued either by RubyDNS or any other DNS
server/client at port UDP:53 with a firewall (pf, iptables, ipfw, etc) or
tcpdump grab the values that are of interest from their logs and then run a
ruby (or pythong, or whatever) script that collects the info you want.

ah, yes. funny i cannot seem to find those using ri. Got to fix my ruby
setup here.
guess i'll have to read the rubydns code then..

thanks again, Samuel
kind regards -botp

···

On Wed, May 22, 2013 at 10:40 PM, Samuel Williams < space.ship.traveller@gmail.com> wrote:

1.
https://github.com/ioquatix/rubydns/blob/master/test/examples/geoip-dns.rb#L57
2.
https://github.com/ioquatix/rubydns/blob/master/lib/rubydns/transaction.rb#L43-L51

Does that help?

Weird - if there is a bug with the documentation please submit a patch :smiley:
Thanks. Let me know if you have any further questions.

···

On 23 May 2013 15:44, botp <botpena@gmail.com> wrote:

On Wed, May 22, 2013 at 10:40 PM, Samuel Williams < > space.ship.traveller@gmail.com> wrote:

1.
https://github.com/ioquatix/rubydns/blob/master/test/examples/geoip-dns.rb#L57
2.
https://github.com/ioquatix/rubydns/blob/master/lib/rubydns/transaction.rb#L43-L51

Does that help?

ah, yes. funny i cannot seem to find those using ri. Got to fix my
ruby setup here.
guess i'll have to read the rubydns code then..

thanks again, Samuel
kind regards -botp

Now I'm kind of curious, what is your expertise and what are you doing with
DNS?

···

On 23 May 2013 15:42, botp <botpena@gmail.com> wrote:

On Thu, May 23, 2013 at 4:08 AM, Panagiotis Atmatzidis < > atma@convalesco.org> wrote:

I'm a bit offtopic really but, I think the 'correct' way to do this would
be to monitor the DNS requests issued either by RubyDNS or any other DNS
server/client at port UDP:53 with a firewall (pf, iptables, ipfw, etc) or
tcpdump grab the values that are of interest from their logs and then run a
ruby (or pythong, or whatever) script that collects the info you want.

in a way, yes. But in this case i do it mainly for 2 reasons:
1 defense in-depth. protection at network level + protection at
application level
2 split dns

now, as to why rubydns interest me:
1 rubydns would shine on environments w heterogeneous dns setup, some have
bind, djbdns, etc... using ruby(dns), i wont have problems reading their
differing databases..
2 adhoc dns.. eg, i can just run a temp rubydns, while i fix their
problematic bind dns...
3 scale and economics. install ruby & deploy.
4 collaboration. my ruby/rails/sinatra apps can now communicate
seamlessly & natively with our dns servers...

kind regards
-botp

nothing new really, just honing basic skills (besides programming) as
sharpest possible...
kind regards -botp

···

On Sat, May 25, 2013 at 8:53 PM, Samuel Williams < space.ship.traveller@gmail.com> wrote:

Now I'm kind of curious, what is your expertise and what are you doing
with DNS?