📜 ⬆️ ⬇️

Making a dDNS client for DNS Yandex

For some reason, I climbed into the mail help for the Yandex domain and noticed Him there - the long-awaited DNS API .
And I wanted to make a more native dDNS client than just a 2-month-old solution through user emulation.


Since it would take me a long time to do C, and I don’t know Python or Perl, we’ll do it on pearl.

Total given:

I want to change them all.
')
First, let's define the IP with which we will replace the entry:
sub getip {
( my $ interface , my $ ipconf ) = @_ ;
$ ipconf = defined ( $ ipconf ) ? $ ipconf : '/ sbin / ip' ;
my $ res = `ip a s $ interface | grep "inet" ` or die ( " Can't get info from ip: " . $! ) ;
if ( $ res = ~ / ( ( \\\ ) on a1.3,3 . {
return $ 1 ;
}
die ( "Can't find ip" ) ;
}

We take the first available IP of the specified interface.

And we throw into the function the execution of the request to the API and the general response checks:
sub yapi {
my $ url = $ _ [ 0 ] ;
die 'Not URL in params yapi func'
unless defined ( $ url ) ;
my $ cont = $ ua -> get ( $ url ) ;
die 'HTTP Error:' , $ cont -> status_line
unless $ cont -> is_success ;
die 'Not XML, given' , $ cont -> content_type
unless $ cont -> content_type eq 'text / xml' ;
my $ resp = XML :: Simple
-> new ( )
-> XMLin ( $ cont -> content ) ;
die 'API error:' , $ resp -> { domains } -> { error }
unless $ resp -> { domains } -> { error } eq 'ok' ;
return ( $ resp -> { domains } -> { domain } ) ;
}

In particular, make sure there is a server response, parse the XML and check if Yandex has returned an error to the API.

Now the main part:
#! / usr / bin / perl
# Domain name
my $ domain = 'example.org' ;
# token authorization
my $ token = '1bdf72e04d6b50c82a48c7e4dd38cc6920116dfd6774a9e7b32eddfe' ;
# new IP, determined by the interface name passed by the first argument
# i.e., for example ./yaddns.pl ppp0
my $ currentip = getip ( $ ARGV [ 0 ] ) ;

use strict ;
use LWP :: UserAgent ;
use XML :: Simple ;
#use Data :: Dumper; #for debug!
my $ ua = LWP :: UserAgent -> new ;
$ ua -> agent ( "dDNS client for pdd.yandex.ru." ) ;


my $ domainlist = yapi ( 'https://pddimp.yandex.ru/nsapi/get_domain_records.xml?token=' . $ token . '& domain =' . $ domain ) -> { response } -> { record } ;
while ( my ( $ record_id , $ record ) = each ( % $ domainlist ) ) {
#print Dumper ($ record);
if ( $ record -> { type } eq 'A' && $ currentip ne $ record -> { content } ) {
my $ update = 'https://pddimp.yandex.ru/nsapi/edit_a_record.xml?token=' . $ token
. '& domain =' . $ domain . '& subdomain =' . $ record -> { subdomain }
. '& record_id =' . $ record_id . '& content =' . $ currentip ;
print 'Record Update' . $ record_id . '(host' . $ record -> { subdomain } . ") \ n " ;
yapi ( $ update ) ;
}
}

Sim get a list of records of this domain and update all A-records whose IP is not what we want.

That's all, in general. Now it remains to register the launch of the script when you raise the interface and you can safely live on.

PS: under debian you need to deliver, if not, libcrypt-ssleay-perl, libxml-simple-perl and libwww-perl packages.

Please note that the API is outdated in December 2014.

Source: https://habr.com/ru/post/129600/


All Articles