On 05/03/2012 12:25 PM, Terry Shepherd wrote:
For a project at work, I need to have my development machine here at
my house reachable via a name.

I don't have static IP from my ISP (they offer it, but it's an
expensive add-on).

I have the router configured so that if you go to
http://205.178.x../mypage you get to my server, but I need to have it
reachable via http://somehost.mydomain.com/

How can I do this with PERL?  I looked up "Dynamic DNS" on
search.cpan.org and did not find anything that seemed appropriate.

Thanks!


Welcome, Terry.

Did you work for KIXE-TV in the 80s? I knew a Terry Shephard ... or Shepperd .. or I can't remember how he spelled his name.

Anyway -- first things first: Perl or perl, *never* PERL :) (Perl is a programming language, perl is the program that implements Perl, and PERL is a brand of ant-poison.)

Yes -- what you want is easily doable. There's a lot of work to getting it to work, so I'll break it into pieces.

First: I'm going to assume you're running Bind9 on your name server - I'm sure there are other DNS implementations that will do it, but bind is the one I know. If this is wrong - let me know and I'll see what I can do to adjust my advice.

On your name server, for the zone "example.com" you need to allow updates.

It will look something like this:

  zone "example.com" IN {
   type master;
    allow-update { dyn-dns; };
    journal "/var/cache/bind/example.com.jnl";
   file "/etc/bind/pri/example.com";
  };

"dyn-dns" in the config file is the name of an ACL (Access Control List) which defines "who is allowed to update this record"

You create the Access Control List by adding something like:

  acl dyn-dns {
      key dyn-dns-key;
  };


Which says "Any Update transaction signed with dyn-dns-key meets the requirements of this access list". You may wish to add more constraints to the Access List ( IP mask etc) depending on your needs.

Next:  You need to CREATE the key dyn-dns-key with a "key" directive.

key "dyn-dns-key" {
    algorithm hmac-md5;
    secret "base-64-string";
};

It's a base-64 string on my server, but I honestly can't remember if it MUST be or if we just made a choice to do that. It might work just as well if the shared secret is "fredddy-kreuger-is-not-a-nice-man"

Okay -- now -- restart bind and check the logs (/var/log/daemon on my box - your mileage may vary)

NOW - We get to the Perl side.

Install Net::DNS from CPAN

The bits you will need are

Net::DNS::Resolver - This is the object that encapsulate the DNS server.

Net::DNS::Update - The object that encapsulates the changes.

Read the doco for each of these,but they're pretty dense and difficult to read if you don't have the DNS RFC(s) memorized. If you're like me, you'll get lost in a sea of Resource Record Sets and Resource Records and ... swoon.

What you're going to do is create an "update" DNS request that says "Delete all of the A records for somehost.mydomain.com. Add an A record for somehost.mydomain.com. that points to 205.178.x.x. Sign that request with my secret key."

Then you're going to SEND that request to the Resolver (name server) and (one hopes) check the return status.

First - creating the Update request record.

  my $update = Net::DNS::Update->new('mydomain.com.');
  $update->push(update => rr_del('somehost.mydomain.com. A'));
$update->push(update => rr_add('somehost.mydomain.com A 205.178.123.123 '));
  $update->sign_tsig(q(dyn-dns-key) => 'some-shared-secret');

Some "gotchas" to watch out for:

* the constructor to Update wants the name of the domain the change is going to happen in.

* All of the records being added MUST use the fully-qualified-domain-name.

* the NAME of the key (dyn-dns-key) MUST match the NAME of the key in the ACL ... if you call it "my-secret-key" you must call it that in both places.

Now - sending that record off to the server

  my $res = Net::DNS::Resolver->new;
  $res->nameservers('fqdn.for.your.authoritative.name.server.net');

  my $reply = $res->send($update);



Finally - look at the reply status.

If $reply is undef, you sent nothing, and you can find the reason in $res->errorstring

If $reply is defined, it you can get $reply->header->rcode

If the change was accepted, it will be the string 'NOERROR'

If there was something wrong, it ($reply->header->rcode) will be a (barely) useful error message.

Hope this gets you started down the path of writing some code.

--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/


Reply via email to