PostHeaderIcon автономный DynDNS

Иногда есть необходимость обращаться по имени клиента, а не по адресу (адреса динамические). Сейчас это частично реализовано — есть локальный домен mydomain.local удаленные точки регистрируются в локальном домене и доступны по имени из локальной сети офиса.
Тестировалось на:
сервере freebsd 7.2 и freebsd 8.0, софт: apache 2.2, php, php-extensions (возможно не нужен), bind9;
клиентах Windows XP, софт: curl, bind9.

Настройка сервера.
В /usr/local/etc/apache22/http.conf добавим следующую секцию:

1
2
3
4
5
6
7
8
9
10
11
12
Alias /ipaddress "/usr/local/www/ipaddress/"
<directory "="" usr="" local="" www="" ipaddress"="">
&nbsp; &nbsp; Options Indexes
&nbsp; &nbsp; AllowOverride All
&nbsp; &nbsp; DirectoryIndex index.php
&nbsp; &nbsp; Order allow,deny
&nbsp; &nbsp; Allow from All
&nbsp; &nbsp; AuthName "Who are you?"
&nbsp; &nbsp; AuthType Basic
&nbsp; &nbsp; AuthUserFile /usr/local/www/ipaddress/.htpasswd
&nbsp; &nbsp; Require valid-user
</directory>

Далее создадим каталог:

1
mkdir /usr/local/www/ipaddress

И положим файл index.php следующего содержания (взял на http://www.phpfaq.ru/ip):

1
2
3
4
<!--?php
   $ip=$_SERVER['REMOTE_ADDR'];
   echo $ip;
?-->

При обращении к этой страничке клиенты узнают свой «белый адрес» с помощью curl. Далее определим тех пользователей, которым необходимо получать свой адрес:

1
htpasswd -cb /usr/local/www/ipaddress/.htpasswd firstsuser userpassword

Для проверки в браузере введем: http://ip-address/ipaddress/. В результате должны увидеть приглашение ввести имя пользователя и пароль, вводим и любуемся своим внешним адресом. Если нет — проверяем логи apache.
С апачем покончено, далее сервер имен. С помощью rndc-confgen генерируем ключ.
В /etc/namedb/named.conf добавим следующую запись:

1
2
3
4
5
6
7
8
9
10
key "rndc-key" {
&nbsp; &nbsp; &nbsp; algorithm hmac-md5;
&nbsp; &nbsp; &nbsp; secret "только_что_сгенерированный_ключ==";
};

zone "mydomain.local"&nbsp; &nbsp; &nbsp; {
&nbsp; &nbsp; &nbsp; &nbsp; type&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;master;
&nbsp; &nbsp; &nbsp; &nbsp; file&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;"dynamic/mydomain.local";
&nbsp; &nbsp; &nbsp; &nbsp; allow-update&nbsp; &nbsp; &nbsp;{ key "rndc-key"; };
};

И создадим файл зоны dynamic/mydomain.local. Я просто скопировал файл для локалхост и подправил.
Для проверки попробуем nsupdate обновить запись в зоне mydomain.local, я для этого использовал файл nsupdate.conf:

1
2
3
4
5
6
server 192.168.0.1
key rndc-key только_что_сгенерированный_ключ==
zone mydomain.local.
update delete test.mydomain.local. A
update add test.mydomain.local. 600 A 192.168.0.182
send

Выполним:

1
nsupdate nsupdate.conf

И проверим:

1
nslookup test.mydomain.local 192.168.0.1

Должен вернуть адрес тестовой машины, если нет, включаем и смотрим логи сервера имен.
С сервером закончили.
Для клиентской части нужен curl (распространяется с поддержкой ssl и без) и bind9. Из пакета bind9 нам понадобится только nsupdate, его библиотеки и vcredist_x86.exe. На стороне клиента выполняется следующий скрипт, там все понятно, описывать нечего:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
var WshShell = new ActiveXObject("WScript.Shell");
var fso = new ActiveXObject("Scripting.FileSystemObject");

var workdir = "d:\\nsupdate\";
var lastaddrr = "
lastaddrr.txt";
var lastip = "
127.0.0.1";

if (fso.FileExists(lastaddrr))
{
&nbsp; var fileObj = fso.GetFile(workdir + lastaddrr);
&nbsp; var ts = fileObj.OpenAsTextStream(1, -2);

&nbsp; // если файл создался два и более часов назад затираем его
&nbsp; var x=new Date(fileObj.DateLastModified);
&nbsp; var y=new Date();
&nbsp; if (Math.floor((y-x)/(1000*60)) &gt;= 10)
&nbsp; {
&nbsp; &nbsp; ts.Close();
&nbsp; &nbsp; fso.DeleteFile(workdir + lastaddrr, true);
&nbsp; }
&nbsp; // иначе читаем из него адрес
&nbsp; else
&nbsp; {
&nbsp; var lastip = ts.ReadLine();
&nbsp; ts.Close();
&nbsp; }
}

var stdout = WScript.StdOut;
var stdin = WScript.StdIn;

// определим программы и их аргументы
var curl = workdir + "
curl.exe -u firstuser:userpassword http://192.168.0.1/ipaddress/index.php";
var nsupdate = workdir + "nsupdate.exe";

// если наш ДНС пингается, пытаемся получить свой адрес и обновить зону
// иначе молча выходим
var objLocalWMI = GetObject("Winmgmts:");
var enumPingStatus = new Enumerator(objLocalWMI.ExecQuery("Select StatusCode from Win32_PingStatus Where Address='192.168.0.1'"));
if(enumPingStatus.item().StatusCode == 0)
{
&nbsp; // определяем внешний IP-address
&nbsp; var oExec = WshShell.Exec(curl);

&nbsp; // проинициализируем переменные
&nbsp; var currentip = oExec.stdout.ReadLine();

&nbsp; if (lastip !== currentip)
&nbsp; {
&nbsp; &nbsp; var server = "server 192.168.0.1";
&nbsp; &nbsp; var key = "key rndc-key только_что_сгенерированный_ключ==";
&nbsp; &nbsp; var zone = "zone mydomain.local.";
&nbsp; &nbsp; var update_del = "update delete mydomain.local. A";
&nbsp; &nbsp; var update_add = "update add mydomain.local. 600 A" + "\ " + currentip;
&nbsp; &nbsp; var send = "send";

&nbsp; &nbsp; // отправим данные серверу
&nbsp; &nbsp; oExec = WshShell.Exec(nsupdate);
&nbsp; &nbsp; oExec.StdIn.Write(server + "\n");
&nbsp; &nbsp; oExec.StdIn.Write(key + "\n");
&nbsp; &nbsp; oExec.StdIn.Write(zone + "\n");
&nbsp; &nbsp; oExec.StdIn.Write(update_del + "\n");
&nbsp; &nbsp; oExec.StdIn.Write(update_add + "\n");
&nbsp; &nbsp; oExec.StdIn.Write(send + "\n");

&nbsp; &nbsp; // save current ip to file
&nbsp; &nbsp; ts = fso.CreateTextFile(workdir + lastaddrr, true);
&nbsp; &nbsp; ts.WriteLine(currentip);
&nbsp; &nbsp; ts.Close();
&nbsp; }
}

Этот jscript запускаем на выполнение каждые 5 минут в планировщике. Если сервер не пингуется — молча выходим, если адрес не менялся — ничего обновлять не будем, если в течение 10 минут адрес не менялся (определим по времени создания файла) адрес все равно обновим, а файл удалим, последний полученный адрес сохраним в файл и на него будем ориентироваться в течение следующих 10 минут.

Оставить комментарий

PR-CY.ru