121 |
- |
1 |
#!/usr/bin/perl -w
|
|
|
2 |
####################################################
|
|
|
3 |
##
|
|
|
4 |
## DnsExit.Com Dynamic IP update setup script
|
|
|
5 |
## v1.70
|
|
|
6 |
##
|
|
|
7 |
## Purpose to further automate setup for use by
|
|
|
8 |
## Arch Linux and allow use of systemd for startup.
|
|
|
9 |
##
|
|
|
10 |
####################################################
|
|
|
11 |
|
|
|
12 |
use Http_get;
|
|
|
13 |
use strict;
|
|
|
14 |
|
|
|
15 |
my $cfile = '/etc/dnsexit.conf';
|
|
|
16 |
my $proxyservs = 'ip.dnsexit.com;ip2.dnsexit.com;ip3.dnsexit.com';
|
|
|
17 |
my $logfile = '/var/log/dnsexit.log';
|
|
|
18 |
my $cachefile = '/tmp/dnsexit-ip.txt';
|
|
|
19 |
my $pidfile = '/var/run/ipUpdate.pid';
|
|
|
20 |
my $siteurl='http://update.dnsexit.com';
|
|
|
21 |
my $geturlfrom = "$siteurl/ipupdate/dyndata.txt";
|
|
|
22 |
|
|
|
23 |
my $URL_VALIDATE="$siteurl/ipupdate/account_validate.jsp";
|
|
|
24 |
my $URL_DOMAINS="$siteurl/ipupdate/domains.jsp";
|
|
|
25 |
my $URL_HOSTS="$siteurl/ipupdate/hosts.jsp";
|
|
|
26 |
|
|
|
27 |
my $MSG_WELCOME= "Wecome to DNSExit.Com Dynamic IP update setup script.\n".
|
|
|
28 |
"Please run this script as root user.\n".
|
|
|
29 |
"Please follow instructions to setup our script.\n\n";
|
|
|
30 |
my $MSG_USERNAME="Enter the username to dnsexit.com: ";
|
|
|
31 |
my $MSG_PASSWORD="Enter password for your username: ";
|
|
|
32 |
my $MSG_CHECKING_USERPASS="Validating your login credentials...\n";
|
|
|
33 |
my $MSG_CHECKING_DOMAINS="Fetching your DNS domains. It may take a while...\n".
|
|
|
34 |
"Note: You should setup DNS for the domain first at your web account to get the domain listed below.\n\n";
|
|
|
35 |
my $MSG_USERPASSOK="Login Successfully...\n\n";
|
|
|
36 |
my $MSG_HOSTS="Please type password for your username:\n";
|
|
|
37 |
my $MSG_SELECT_DOMAINS="Please select the domains to update:\n";
|
|
|
38 |
my $MSG_FETCHING_HOSTS="Feching hosts in your domains. This may take a while...\n";
|
|
|
39 |
my $MSG_SELECT_HOSTS="Please select host(s) to be updated:\n";
|
|
|
40 |
my $MSG_SELECT_HOSTS_AFTER="Note: to select multiple hosts, separate them by space\nYour selection: ";
|
|
|
41 |
my $MSG_YOU_HAVE_SELECTED="You have selected the following hosts to be updated:\n";
|
|
|
42 |
my $MSG_SELECT_PROXY="If you want to use the IP address of your proxy server instead of the\n".
|
|
|
43 |
"IP of the local host, set the value to \"yes\"\n";
|
|
|
44 |
my $MSG_PROXY_SEL="Your choice [no]: ";
|
|
|
45 |
my $MSG_SELECT_DAEMON="Do you want to run it as a daemon?\n";
|
|
|
46 |
my $MSG_SELECT_INTERVAL="How often (in minutes) should the program checks IP changes ?\n".
|
|
|
47 |
"IP will be posted to dnsExit.com only when IP address has been\n".
|
|
|
48 |
"changed from the last update (minimum 3 minutes):\n";
|
|
|
49 |
my $MSG_INTERVAL_SEL="Your choice [10]: ";
|
|
|
50 |
my $MSG_SELECT_PIDFILE="Select path to pidfile.\n";
|
|
|
51 |
my $MSG_PIDFILE_SEL="Your choice [/var/run/ipUpdate.pid]: ";
|
|
|
52 |
my $MSG_PIDFILE_BAD="You have selected invalid file name.\n";
|
|
|
53 |
my $MSG_GENERATING_CFG="Generating config file: ";
|
|
|
54 |
my $MSG_DONE="Done creating config file. You can run the script now.\n".
|
|
|
55 |
"To do it you can run ipUpdate.pl or use init script.\n\n".
|
|
|
56 |
"File '$cachefile' will cache the ip address of\n".
|
|
|
57 |
"the last successful IP update to our system. For next\n".
|
|
|
58 |
"update, if the IP stays the same, the update request\n".
|
|
|
59 |
"won't be sent to our server. You can simply change the\n".
|
|
|
60 |
"IP at dnsexit-ip.txt file to force the update to DNSEXIT.\n\n";
|
|
|
61 |
my $MSG_PATHS="Here are paths to some intresting files:\n";
|
|
|
62 |
my $MSG_END="Don't forget to read README.txt file in doc directory!\n";
|
|
|
63 |
|
|
|
64 |
|
|
|
65 |
my $ERR_DOMAINS="Can't get list of your domains from the server";
|
|
|
66 |
my $ERR_NO_DOMAINS="You don't have any domains with DNS. You should login to your account ".
|
|
|
67 |
"at www.dnsexit.com and setup DNS for your domains first.\n";
|
|
|
68 |
my $ERR_NO_HOSTS_SELECTED="You have not selected any hosts. Exiting...\n";
|
|
|
69 |
my $ERR_NO_URL="Can't fetach url info from dnsexit.com. Please try again later...\n";
|
|
|
70 |
|
|
|
71 |
my $get = new Http_get;
|
|
|
72 |
print $MSG_WELCOME;
|
|
|
73 |
|
|
|
74 |
#
|
|
|
75 |
# Delete ald cache file
|
|
|
76 |
#
|
|
|
77 |
unlink $cachefile;
|
|
|
78 |
|
|
|
79 |
#
|
|
|
80 |
# Get url from dnsexit.com
|
|
|
81 |
#
|
|
|
82 |
my $url;
|
|
|
83 |
$get->request($geturlfrom);
|
|
|
84 |
if($get->is_success) {
|
|
|
85 |
my $result = $get->content;
|
|
|
86 |
if ( $result =~ /url=(.+)/ ) {
|
|
|
87 |
$url=$1;
|
|
|
88 |
if((my $chr=chop($url)) ne "\n"){
|
|
|
89 |
$url.=$chr;
|
|
|
90 |
}
|
|
|
91 |
}
|
|
|
92 |
}
|
|
|
93 |
if(!$url) {
|
|
|
94 |
print $ERR_NO_URL;
|
|
|
95 |
exit;
|
|
|
96 |
}
|
|
|
97 |
#
|
|
|
98 |
# Get username/password and validate it.
|
|
|
99 |
#
|
|
|
100 |
my $userpassok=0;
|
|
|
101 |
my $message=undef;
|
|
|
102 |
my $username;
|
|
|
103 |
my $password;
|
|
|
104 |
do {
|
|
|
105 |
print "\nError: $message\n\n" if($message);
|
|
|
106 |
# Get username
|
|
|
107 |
$username=ask_value($MSG_USERNAME);
|
|
|
108 |
# Get password
|
|
|
109 |
$password=ask_value($MSG_PASSWORD);
|
|
|
110 |
$password =~ s/ /%20/g;
|
|
|
111 |
print $MSG_CHECKING_USERPASS;
|
|
|
112 |
# Check username/password
|
|
|
113 |
$get->request($URL_VALIDATE."?login=$username&password=$password");
|
|
|
114 |
if($get->is_success) {
|
|
|
115 |
my $result = $get->content;
|
|
|
116 |
if ( $result =~ /(\d+)=(.+)/ ) {
|
|
|
117 |
$userpassok=$1;
|
|
|
118 |
$message=$2;
|
|
|
119 |
if((my $chr=chop($message)) ne "\n"){
|
|
|
120 |
$message.=$chr;
|
|
|
121 |
}
|
|
|
122 |
}
|
|
|
123 |
}
|
|
|
124 |
} until($userpassok==0);
|
|
|
125 |
print $MSG_USERPASSOK;
|
|
|
126 |
|
|
|
127 |
#
|
|
|
128 |
# Get list of domains and ask user which of them should be explored
|
|
|
129 |
#
|
|
|
130 |
my @domains;
|
|
|
131 |
print $MSG_CHECKING_DOMAINS;
|
|
|
132 |
$get->request($URL_DOMAINS."?login=$username&password=$password");
|
|
|
133 |
if($get->is_success) {
|
|
|
134 |
my $result = $get->content;
|
|
|
135 |
if ( $result =~ /(\d+)=(.+)/ ) {
|
|
|
136 |
$message=$2;
|
|
|
137 |
if((my $code=$1)==0) {
|
|
|
138 |
@domains=split(/ +/, $message);
|
|
|
139 |
}
|
|
|
140 |
elsif($code==1) {
|
|
|
141 |
print "\n$ERR_NO_DOMAINS\n\n";
|
|
|
142 |
exit;
|
|
|
143 |
}
|
|
|
144 |
else {
|
|
|
145 |
print"\nError: $message\n\n";
|
|
|
146 |
exit;
|
|
|
147 |
}
|
|
|
148 |
}
|
|
|
149 |
else {
|
|
|
150 |
print "\n$ERR_DOMAINS\n\n";
|
|
|
151 |
exit;
|
|
|
152 |
}
|
|
|
153 |
}
|
|
|
154 |
else {
|
|
|
155 |
print "\n$ERR_DOMAINS\n\n";
|
|
|
156 |
exit;
|
|
|
157 |
}
|
|
|
158 |
|
|
|
159 |
my @selected = make_select(\@domains, $MSG_SELECT_DOMAINS, 1 );
|
|
|
160 |
|
|
|
161 |
my @hosts;
|
|
|
162 |
|
|
|
163 |
#
|
|
|
164 |
# Get list of hosts from selected domains and ask user which should be added
|
|
|
165 |
# to the config file.
|
|
|
166 |
#
|
|
|
167 |
print $MSG_FETCHING_HOSTS;
|
|
|
168 |
foreach my $domain (@selected) {
|
|
|
169 |
$get->request($URL_HOSTS."?login=$username&password=$password&domain=$domain");
|
|
|
170 |
if($get->is_success) {
|
|
|
171 |
my $result=$get->content;
|
|
|
172 |
if ( $result =~ /(\d+)=(.+)/ ) {
|
|
|
173 |
$message=$2;
|
|
|
174 |
if((my $code=$1)==0) {
|
|
|
175 |
my @myhosts=split(/\ /, $message);
|
|
|
176 |
foreach my $host (@myhosts) {
|
|
|
177 |
$host =~ s/\s+//g;
|
|
|
178 |
push (@hosts,$host);
|
|
|
179 |
}
|
|
|
180 |
}
|
|
|
181 |
}
|
|
|
182 |
}
|
|
|
183 |
}
|
|
|
184 |
|
|
|
185 |
@selected = make_select(\@hosts, $MSG_SELECT_HOSTS, 1 );
|
|
|
186 |
my $hosts;
|
|
|
187 |
print "\n".$MSG_YOU_HAVE_SELECTED;
|
|
|
188 |
foreach my $sel ( @selected ) {
|
|
|
189 |
$sel =~ s/\s+//g;
|
|
|
190 |
print "\t$sel\n";
|
|
|
191 |
$hosts.=$sel;
|
|
|
192 |
$hosts.=';';
|
|
|
193 |
}
|
|
|
194 |
chop $hosts;
|
|
|
195 |
|
|
|
196 |
#
|
|
|
197 |
# Ask user whants daemon mode.
|
|
|
198 |
#
|
|
|
199 |
my $daemon= confirm("yes", "no", "Your choice [yes]: ", $MSG_SELECT_DAEMON);
|
|
|
200 |
|
|
|
201 |
#
|
|
|
202 |
# If deamon=YES then ask for an interval
|
|
|
203 |
#
|
|
|
204 |
print "\n";
|
|
|
205 |
my $interval = 0;
|
|
|
206 |
my $autostart="no";
|
|
|
207 |
if($daemon eq 'yes') {
|
|
|
208 |
print $MSG_SELECT_INTERVAL;
|
|
|
209 |
while( $interval < 3 ) {
|
|
|
210 |
$interval = ask_value($MSG_INTERVAL_SEL, "10");
|
|
|
211 |
print "Error: minimum 3 minutes\n" if ( $interval < 3 || ! ( $interval =~ /^\d+$/ ) );
|
|
|
212 |
}
|
|
|
213 |
$interval *= 60; #convert to seconds
|
|
|
214 |
#
|
|
|
215 |
# Ask if want to auto start after reboot
|
|
|
216 |
#
|
|
|
217 |
$autostart=confirm("yes", "no", "Your choice [yes]: ", "Do you want to autostart the IPUpdate script at system startup?\n");
|
|
|
218 |
if($autostart eq "yes")
|
|
|
219 |
{
|
|
|
220 |
my @seldirs=( &programdir, "/usr/local/bin", "/usr/sbin");
|
|
|
221 |
my $sdir=make_select(\@seldirs, "Please select the directory to install the script:\n", 0);
|
|
|
222 |
set_autostart($sdir);
|
|
|
223 |
}
|
|
|
224 |
}
|
|
|
225 |
$interval = 600 if $interval == 0;
|
|
|
226 |
#
|
|
|
227 |
# Generate config and .service files
|
|
|
228 |
#
|
|
|
229 |
print "\n".$MSG_GENERATING_CFG . " $cfile\n";
|
|
|
230 |
open (CFG, "> $cfile") || die "Fail open config file $cfile. Please check if have proper permissions.";
|
|
|
231 |
print CFG "login=$username\n";
|
|
|
232 |
print CFG "password=$password\n";
|
|
|
233 |
print CFG "host=$hosts\n";
|
|
|
234 |
print CFG "daemon=$daemon\n";
|
|
|
235 |
print CFG "autostart=$autostart\n";
|
|
|
236 |
print CFG "interval=$interval\n";
|
|
|
237 |
print CFG "proxyservs=$proxyservs\n";
|
|
|
238 |
print CFG "pidfile=$pidfile\n";
|
|
|
239 |
print CFG "logfile=$logfile\n";
|
|
|
240 |
print CFG "cachefile=$cachefile\n";
|
|
|
241 |
print CFG "url=$url\n";
|
|
|
242 |
close(CFG);
|
|
|
243 |
|
|
|
244 |
print "\n".$MSG_DONE;
|
|
|
245 |
print $MSG_PATHS;
|
|
|
246 |
print " Config file:\t$cfile\n";
|
|
|
247 |
print " Pid file:\t$pidfile\n";
|
|
|
248 |
print " Log file:\t$logfile\n";
|
|
|
249 |
print " Cache file:\t$cachefile\n";
|
|
|
250 |
print "\n".$MSG_END;
|
|
|
251 |
|
|
|
252 |
exit 0;
|
|
|
253 |
|
|
|
254 |
sub ask_value
|
|
|
255 |
{
|
|
|
256 |
my $msg = shift;
|
|
|
257 |
my $default = shift || undef;
|
|
|
258 |
my $invalue="";
|
|
|
259 |
while( $invalue eq "" )
|
|
|
260 |
{
|
|
|
261 |
print $msg;
|
|
|
262 |
chop ( $invalue=<STDIN> );
|
|
|
263 |
$invalue = $default if ( defined $default && $invalue eq "" );
|
|
|
264 |
}
|
|
|
265 |
return $invalue;
|
|
|
266 |
}
|
|
|
267 |
|
|
|
268 |
sub make_select
|
|
|
269 |
{
|
|
|
270 |
my ($arrayRef, $selTitle, $multiselect)=(@_);
|
|
|
271 |
$multiselect = 1 unless defined $multiselect;
|
|
|
272 |
my @items= @$arrayRef;
|
|
|
273 |
SLSTART:
|
|
|
274 |
print $selTitle;
|
|
|
275 |
my $i=0;
|
|
|
276 |
foreach my $item (@items)
|
|
|
277 |
{
|
|
|
278 |
print " " . $i++."\t$item\n";
|
|
|
279 |
}
|
|
|
280 |
print "[separate multi selects by space]\n" if $multiselect;
|
|
|
281 |
print "Your selection: ";
|
|
|
282 |
my $line=<STDIN>;
|
|
|
283 |
chop $line;
|
|
|
284 |
$line =~ s/^\s+|\s+$//g ;
|
|
|
285 |
goto SLSTART if($line eq "");
|
|
|
286 |
my @tofilter=split(/\s+/, $line);
|
|
|
287 |
my @select;
|
|
|
288 |
foreach my $fil (@tofilter)
|
|
|
289 |
{
|
|
|
290 |
goto SLSTART if( ! ( $fil =~ /^\d+$/ ) );
|
|
|
291 |
$fil =~ s/\s+//g;
|
|
|
292 |
next if $fil eq "";
|
|
|
293 |
if($items[$fil]) {
|
|
|
294 |
$items[$fil] =~ s/^\s+|\s+$//g ;
|
|
|
295 |
push @select, $items[$fil];
|
|
|
296 |
}
|
|
|
297 |
}
|
|
|
298 |
if( ! $multiselect && scalar( @select ) > 1)
|
|
|
299 |
{
|
|
|
300 |
print "Please select one only !!\n";
|
|
|
301 |
goto SLSTART;
|
|
|
302 |
}
|
|
|
303 |
goto SLSTART if(!@select);
|
|
|
304 |
return ( @select ) if $multiselect;;
|
|
|
305 |
return $select[0];
|
|
|
306 |
}
|
|
|
307 |
|
|
|
308 |
sub confirm
|
|
|
309 |
{
|
|
|
310 |
my ($answerYes, $answerNo, $question, $title) = ( @_ );
|
|
|
311 |
my $answer="";
|
|
|
312 |
print $title;
|
|
|
313 |
do
|
|
|
314 |
{
|
|
|
315 |
print $question;
|
|
|
316 |
$answer=<STDIN>;
|
|
|
317 |
if ( $answer eq "\n" )
|
|
|
318 |
{
|
|
|
319 |
$answer="yes";
|
|
|
320 |
}
|
|
|
321 |
else
|
|
|
322 |
{
|
|
|
323 |
$answer=lc($answer);
|
|
|
324 |
if((my $chr=chop($answer)) ne "\n"){
|
|
|
325 |
$answer.=$chr;
|
|
|
326 |
}
|
|
|
327 |
}
|
|
|
328 |
} until $answer eq 'yes' || $answer eq 'no';
|
|
|
329 |
return $answer;
|
|
|
330 |
}
|
|
|
331 |
|
|
|
332 |
sub set_autostart
|
|
|
333 |
{
|
|
|
334 |
my $dir="@_";
|
|
|
335 |
my $prodir=programdir();
|
|
|
336 |
my $proname="ipUpdate.pl";
|
|
|
337 |
if ( index( $dir, $prodir ) < 0 )
|
|
|
338 |
{
|
|
|
339 |
my $cmd=qq^cp -f $prodir/$proname $dir/. ; cp -f $prodir/Http_get.pm $dir/.; chmod a+x $dir/$proname^;
|
|
|
340 |
print "$proname installed to $dir\n";
|
|
|
341 |
system( $cmd );
|
|
|
342 |
}
|
|
|
343 |
#my $cmd = qq^( echo "\@reboot $dir/$proname"; crontab -l | grep -v "^\@reboot\s.+$proname") | crontab -^;
|
|
|
344 |
my $cmd = qq^( echo "\@reboot $dir/$proname"; crontab -l | grep -v "\/$proname") | crontab -^;
|
|
|
345 |
system($cmd);
|
|
|
346 |
print "\"\@reboot $dir/$proname\" inserted to crontab\n";
|
|
|
347 |
}
|
|
|
348 |
|
|
|
349 |
sub programdir
|
|
|
350 |
{
|
|
|
351 |
my $self = shift;
|
|
|
352 |
my $PRODIR =`dirname $0`;
|
|
|
353 |
chop $PRODIR;
|
|
|
354 |
if ( $PRODIR eq "." )
|
|
|
355 |
{
|
|
|
356 |
$PRODIR = `pwd`;
|
|
|
357 |
chop $PRODIR;
|
|
|
358 |
}
|
|
|
359 |
return $PRODIR;
|
|
|
360 |
}
|