---
title: "Настройка автономного сервера DynDNS на FreeBSD с BIND и Apache 0 Сети/интернет"
description: "В статье рассматривается настройка локального домена mydomain.local на базе FreeBSD и BIND. Удален..."
author: "root-kz"
published: "2010-12-13T13:30:49+00:00"
modified: "2011-01-12T06:20:55+00:00"
locale: "ru"
canonical_url: "https://yvision.kz/post/nastroyka-avtonomnogo-servera-dyndns-na-freebsd-s-bind-i-apache-0-seti-internet-95235"
markdown_url: "https://yvision.kz/post/nastroyka-avtonomnogo-servera-dyndns-na-freebsd-s-bind-i-apache-0-seti-internet-95235/markdown"
site_name: "Yvision.kz"
---

# Настройка автономного сервера DynDNS на FreeBSD с BIND и Apache 0 Сети/интернет

> В статье рассматривается настройка локального домена mydomain.local на базе FreeBSD и BIND. Удален...

![Настройка автономного сервера DynDNS на FreeBSD с BIND и Apache 0 Сети/интернет](http://assets.devx.com/HotList/26_freebsd.gif)

В статье рассматривается настройка локального домена mydomain.local на базе FreeBSD и BIND. Удаленные точки (клиенты на Windows XP) регистрируются в локальной доменной зоне и доступны по имени из локальной сети офиса.

Иногда есть необходимость обращаться по имени клиента, а не по адресу (в случае, если адреса динамические). Сейчас это частично реализовано. Допустим, есть локальный домен mydomain.local, удаленные точки регистрируются в локальной доменной зоне и доступны по имени из локальной сети офиса. Решение тестировалось на:
- сервере FreeBSD 7.2 и 8.0 с Apache 2.2, PHP, BIND 9;
- клиентах Windows XP с curl, BIND 9.

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

{"source": " Alias /ipaddress \"/usr/local/www/ipaddress/\"\n \n Options Indexes\n AllowOverride All\n DirectoryIndex index.php\n Order allow,deny\n Allow from All\n AuthName \"Who are you?\"\n AuthType Basic\n AuthUserFile /usr/local/www/ipaddress/.htpasswd\n Require valid-user\n ", "language": "cpp", "insert": "Вставить", "cancel": "Отменить"}

``` Alias /ipaddress "/usr/local/www/ipaddress/" Options Indexes AllowOverride All DirectoryIndex index.php Order allow,deny Allow from All AuthName "Who are you?" AuthType Basic AuthUserFile /usr/local/www/ipaddress/.htpasswd Require valid-user ```

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

``` mkdir /usr/local/www/ipaddress ```

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

{"source": "", "language": "php", "insert": "Вставить", "cancel": "Отменить"}

``` ```

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

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

{"source": " htpasswd -cb /usr/local/www/ipaddress/.htpasswd firstsuser userpassword", "language": "text", "insert": "Вставить", "cancel": "Отменить"}

Для проверки в браузере введем [http://ip-address/ipaddress/](http://ip-address/ipaddress/) — в результате должны увидеть приглашение ввести имя пользователя и пароль, вводим и любуемся своим внешним адресом. Если нет — проверяем логи Apache.

Теперь — сервер имен. С помощью *rndc-confgen* генерируем ключ. В */etc/namedb/named.conf* добавим следующую запись:

{"source": "key \"rndc-key\" {\n algorithm hmac-md5;\n secret \"только_что_сгенерированный_ключ==\";\n};\n \nzone \"mydomain.local\" {\n type master;\n file \"dynamic/mydomain.local\";\n allow-update { key \"rndc-key\"; };\n};", "language": "cpp", "insert": "Вставить", "cancel": "Отменить"}

``` key "rndc-key" { algorithm hmac-md5; secret "только_что_сгенерированный_ключ==";}; zone "mydomain.local" { type master; file "dynamic/mydomain.local"; allow-update { key "rndc-key"; };}; ```

И создадим файл зоны *dynamic/mydomain.local* — я просто скопировал файл для localhost и подправил.

Для проверки попробуем с помощью *nsupdate* обновить запись в зоне *mydomain.local* — я для этого использовал файл *nsupdate.conf*:

{"source": "server 192.168.0.1\nkey rndc-key только_что_сгенерированный_ключ==\nzone mydomain.local.\nupdate delete test.mydomain.local. A\nupdate add test.mydomain.local. 600 A 192.168.0.182\nsend", "language": "cpp", "insert": "Вставить", "cancel": "Отменить"}

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

Выполним:

``` nsupdate nsupdate.conf ```

{"source": " nsupdate nsupdate.conf", "language": "text", "insert": "Вставить", "cancel": "Отменить"}

И проверим:

``` nslookup test.mydomain.local 192.168.0.1 ```

{"source": " nslookup test.mydomain.local 192.168.0.1", "language": "text", "insert": "Вставить", "cancel": "Отменить"}

Должен вернуться адрес тестовой машины. Если нет — включаем и смотрим логи сервера имен.

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

{"source": "var WshShell = new ActiveXObject(\"WScript.Shell\");\nvar fso = new ActiveXObject(\"Scripting.FileSystemObject\");\n \nvar workdir = \"d:\\\\nsupdate\\\\\";\nvar lastaddrr = \"lastaddrr.txt\";\nvar lastip = \"127.0.0.1\";\n \nif (fso.FileExists(lastaddrr))\n{\n var fileObj = fso.GetFile(workdir + lastaddrr);\n var ts = fileObj.OpenAsTextStream(1, -2);\n \n // если файл создался десять минут назад и более, затираем его\n var x=new Date(fileObj.DateLastModified);\n var y=new Date();\n if (Math.floor((y-x)/(1000*60)) >= 10)\n {\n ts.Close();\n fso.DeleteFile(workdir + lastaddrr, true);\n }\n // иначе читаем из него адрес\n else\n {\n var lastip = ts.ReadLine();\n ts.Close();\n }\n}\n \nvar stdout = WScript.StdOut;\nvar stdin = WScript.StdIn;\n \n// определим программы и их аргументы\nvar curl = workdir + \"curl.exe -u firstuser:userpassword [192.168.0.1/ipaddress/index.php](http://192.168.0.1/ipaddress/index.php)\";\nvar nsupdate = workdir + \"nsupdate.exe\";\n \n// если наш ДНС пингуется, пытаемся получить свой адрес и обновить зону\n// иначе молча выходим\nvar objLocalWMI = GetObject(\"Winmgmts:\");\nvar enumPingStatus = new Enumerator(objLocalWMI.ExecQuery(\"Select StatusCode from Win32_PingStatus Where Address='192.168.0.1'\"));\nif(enumPingStatus.item().StatusCode == 0)\n{\n // определяем внешний IP-address\n var oExec = WshShell.Exec(curl);\n \n // проинициализируем переменные\n var currentip = oExec.stdout.ReadLine();\n \n if (lastip !== currentip)\n {\n var server = \"server 192.168.0.1\";\n var key = \"key rndc-key только_что_сгенерированный_ключ==\";\n var zone = \"zone mydomain.local.\";\n var update_del = \"update delete mydomain.local. A\";\n var update_add = \"update add mydomain.local. 600 A\" + \"\\ \" + currentip;\n var send = \"send\";\n \n // отправим данные серверу\n oExec = WshShell.Exec(nsupdate);\n oExec.StdIn.Write(server + \"\\n\");\n oExec.StdIn.Write(key + \"\\n\");\n oExec.StdIn.Write(zone + \"\\n\");\n oExec.StdIn.Write(update_del + \"\\n\");\n oExec.StdIn.Write(update_add + \"\\n\");\n oExec.StdIn.Write(send + \"\\n\");\n \n // save current ip to file\n ts = fso.CreateTextFile(workdir + lastaddrr, true);\n ts.WriteLine(currentip);\n ts.Close();\n }\n}", "language": "javascript", "insert": "Вставить", "cancel": "Отменить"}

``` 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)){ var fileObj = fso.GetFile(workdir + lastaddrr); var ts = fileObj.OpenAsTextStream(1, -2); // если файл создался десять минут назад и более, затираем его var x=new Date(fileObj.DateLastModified); var y=new Date(); if (Math.floor((y-x)/(1000*60)) >= 10) { ts.Close(); fso.DeleteFile(workdir + lastaddrr, true); } // иначе читаем из него адрес else { var lastip = ts.ReadLine(); ts.Close(); }} 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){ // определяем внешний IP-address var oExec = WshShell.Exec(curl); // проинициализируем переменные var currentip = oExec.stdout.ReadLine(); if (lastip !== currentip) { var server = "server 192.168.0.1"; var key = "key rndc-key только_что_сгенерированный_ключ=="; var zone = "zone mydomain.local."; var update_del = "update delete mydomain.local. A"; var update_add = "update add mydomain.local. 600 A" + "\ " + currentip; var send = "send"; // отправим данные серверу oExec = WshShell.Exec(nsupdate); oExec.StdIn.Write(server + "\n"); oExec.StdIn.Write(key + "\n"); oExec.StdIn.Write(zone + "\n"); oExec.StdIn.Write(update_del + "\n"); oExec.StdIn.Write(update_add + "\n"); oExec.StdIn.Write(send + "\n"); // save current ip to file ts = fso.CreateTextFile(workdir + lastaddrr, true); ts.WriteLine(currentip); ts.Close(); }} ```

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

P.S. Надеюсь статья пригодится :)

---

Source: [https://yvision.kz/post/nastroyka-avtonomnogo-servera-dyndns-na-freebsd-s-bind-i-apache-0-seti-internet-95235](https://yvision.kz/post/nastroyka-avtonomnogo-servera-dyndns-na-freebsd-s-bind-i-apache-0-seti-internet-95235)