Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

Re: My own dynamic DNS setup

by Theodore (Scribe)
on Apr 11, 2014 at 13:01 UTC ( #1081958=note: print w/ replies, xml ) Need Help??


in reply to My own dynamic DNS setup

And here is my own perverted pair of scripts, with IPv6/AAAA support :-)

Client script:

#!/usr/bin/perl use strict; if (($ARGV[0] ne "v4") and ($ARGV[0] ne "v6")) { print "Usage: $0 v4|v6\n"; exit 1; }; # Check for IPV6 requ. my $ipver = "v4"; if ($ARGV[0] eq "v6") { require Net::INET6Glue::INET_is_INET6; $ipver = "v6"; }; my $previp = ''; # DNS record types: my %drts = ( 'v4' => 'A', 'v6' => 'AAAA', ); # Checkip url my $checkurl = 'http://www.example.com.gr/myip'; # Updateip url my $updateurl = 'http://www.example.com/ddnsset.pl?'; # FQDN to set: my $fqdn = 'myhost'; # History filenames: my %iphist = ( 'v4' => '/tmp/dynipsethistv4.txt', 'v6' => '/tmp/dynipsethistv6.txt', ); # Load history: if (-e $iphist{$ipver}) { open (HI, "<", $iphist{$ipver}) or die "Failed to open " . $iphist +{$ipver} . " for reading: $!.\n"; $previp = <HI>; close HI; }; # Create a user agent object use LWP::UserAgent; my $ua = LWP::UserAgent->new; $ua->agent("dynipset/0.1 "); # Create a request my $req = HTTP::Request->new(GET => $checkurl); # Pass request to the user agent and get a response back my $res = $ua->request($req); # Check the outcome of the response if ($res->is_success) { my $newip = $res->content; #print "DEBUG: My new IP is $newip ($ipver) \n"; if ($previp eq $newip) { # Do nothing. #print "DEBUG: IP not changed.\n"; exit 0; } else { # Set ip: my $dbrec = "$fqdn|" . $drts{$ipver} . "|$newip"; my $rc = &setDNS($dbrec); if ($rc) { print "SET: $fqdn " . $drts{$ipver} . " $newip\n"; } else { print "ERROR: setDNS failed ($fqdn|$newip)!\n"; exit 1; }; # Save new ip to history: open (HI, ">", $iphist{$ipver}) or die "Failed to open " . $ip +hist{$ipver} . " for writing: $!.\n"; print HI $newip; close HI; exit 0; }; } else { print "ERROR: checkip request failed: " . $res->status_line, "\n"; exit 1; }; exit 0; sub setDNS { my ($dbrec, $rest) = @_; use Crypt::CBC; use MIME::Base64 qw(encode_base64url decode_base64url); my $cipher = Crypt::CBC->new( -key => 'a pass phrase', -cipher => 'Blowfish', -keysize => 56 ); my $ciphertext = $cipher->encrypt($dbrec); my $encoded = encode_base64url($ciphertext); #print "DEBUG: $encoded\n"; my $url = "$updateurl$encoded"; my $ua = LWP::UserAgent->new; $ua->agent("dynipset/0.1 "); # Create a request my $req = HTTP::Request->new(GET => $url); # Pass request to the user agent and get a response back my $res = $ua->request($req); if ($res->is_success) { return 1; } else { print "ERROR: updateip request failed: " . $res->status_line, +"\n"; return 0; }; };

Server script:

#!/usr/bin/perl use strict; use Net::DNS; use Paranoid::Network::IPv4 qw(:all); use Paranoid::Network::IPv6 qw(:all); use Data::Dumper; use CGI; my $zone = 'dyn.example.com'; # A zone reserved for this script +. my $dnsserver = '127.0.0.1'; # Assuming 'allow-updates {127.0.0 +.1;}' in localhost BIND. my @validnames = ('myhost', 'myhost2'); # Only these are allowed. my @validtypes = ('A', 'AAAA'); # Only these are allowed. my $query = CGI->new; my @params = $query->url_param('keywords'); my $qref = &qdecode($params[0]); my ($name, $type, $ip, $rest) = @{ $qref }; if (not grep($name, @validnames)) { print STDERR "ERROR: Invalid name: $name\n"; print $query->header('text/html','500 Internal Server Error'); print $query->start_html(-title=>''); print $query->end_html(); exit 1; }; if (not grep($type, @validtypes)) { print STDERR "ERROR: Invalid type: $type\n"; print $query->header('text/html','500 Internal Server Error'); print $query->start_html(-title=>''); print $query->end_html(); exit 1; }; if ( (($type eq 'A') and (not (($ip =~ /^@{[ IPV4REGEX ]}$/)))) or (($type eq 'AAAA') and (not (($ip =~ /^@{[ IPV6REGEX ]}$/)))) ) { print STDERR "ERROR: Invalid IP: $ip\n"; print $query->header('text/html','500 Internal Server Error'); print $query->start_html(-title=>''); print $query->end_html(); exit 1; }; my $fqn = $name . "." . $zone; my $fqdn = $name . "." . $zone . "."; my $resolver = new Net::DNS::Resolver; $resolver->nameservers($dnsserver); # Delete old record. my $update = new Net::DNS::Update($zone); $update->push( prereq => yxrrset("$fqn $type") ); $update->push( update => rr_del("$fqn $type") ); my $reply = $resolver->send($update); if ($reply) { if ( $reply->header->rcode eq 'NOERROR' ) { print STDERR "Delete old records succeeded\n"; } else { print STDERR 'Delete old records failed: ', $reply->he +ader->rcode, "\n"; } } else { print STDERR 'Delete old records failed: ', $resolver->errorst +ring, "\n"; print $query->header('text/html','500 Internal Server Error'); print $query->start_html(-title=>''); print $query->end_html(); exit 1; }; undef $reply, $update; # Add new record. $update = new Net::DNS::Update($zone); $update->push( prereq => yxdomain($zone) ); $update->push( update => rr_add("$fqdn 300 $type $ip") ); $reply = $resolver->send($update); if ($reply) { if ( $reply->header->rcode eq 'NOERROR' ) { print STDERR "Update succeeded\n"; print $query->header('text/html','204 No response'); } else { print STDERR 'Update failed: ', $reply->header->rcode, + "\n"; print $query->header('text/html','500 Internal Server Error'); print $query->start_html(-title=>''); print $query->end_html(); exit 1; } } else { print STDERR 'Update failed: ', $resolver->errorstring, "\n"; print $query->header('text/html','500 Internal Server Error'); print $query->start_html(-title=>''); print $query->end_html(); exit 1; } exit 0; sub qdecode { my ($dbrec, $rest) = @_; use Crypt::CBC; use MIME::Base64 qw(encode_base64url decode_base64url); my $cipher = Crypt::CBC->new( -key => 'a pass phrase', -cipher => 'Blowfish', -keysize => 56 ); my $decoded = decode_base64url($dbrec); my $decrypted = $cipher->decrypt($decoded); my @result = split(/\|/, $decrypted, 3); return \@result; };


Comment on Re: My own dynamic DNS setup
Select or Download Code

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1081958]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (3)
As of 2014-09-22 05:42 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (180 votes), past polls