Я использовал следующий скрипт php для обновления динамической записи DNS через мой веб-сервер, как описано в этой ссылке собственность- DDNS:
<?php
// configuration of user and domain
$user_domain = array( 'user' => array('subdomain','sub2'), 'user2' => array('sub4') );
// main domain for dynamic DNS
$dyndns = "dyndns.example.org";
// DNS server to send update to
$dnsserver = "localhost";
// port of DNS server
$dnsport = "";
// short sanity check for given IP
function checkip($ip)
{
$iptupel = explode(".", $ip);
foreach ($iptupel as $value)
{
if ($value < 0 || $value > 255)
return false;
}
return true;
}
// retrieve IP
$ip = $_SERVER['REMOTE_ADDR'];
// retrieve user
if ( isset($_SERVER['REMOTE_USER']) )
{
$user = $_SERVER['REMOTE_USER'];
}
else if ( isset($_SERVER['PHP_AUTH_USER']) )
{
$user = $_SERVER['PHP_AUTH_USER'];
}
else
{
syslog(LOG_WARN, "No user given by connection from $ip");
exit(0);
}
// open log session
openlog("DDNS-Provider", LOG_PID | LOG_PERROR, LOG_LOCAL0);
// check for given domain
if ( isset($_POST['DOMAIN']) )
{
$subdomain = $_POST['DOMAIN'];
}
else if ( isset($_GET['DOMAIN']) )
{
$subdomain = $_GET['DOMAIN'];
}
else
{
syslog(LOG_WARN, "User $user from $ip didn't provide any domain");
exit(0);
}
// check for needed variables
if ( isset($subdomain) && isset($ip) && isset($user) )
{
// short sanity check for given IP
if ( preg_match("/^(\d{1,3}\.){3}\d{1,3}$/", $ip) && checkip($ip) && $ip != "0.0.0.0" && $ip != "255.255.255.255" )
{
// short sanity check for given domain
if ( preg_match("/^[\w\d-_\*\.]+$/", $subdomain) )
{
// check whether user is allowed to change domain
if ( in_array("*", $user_domain[$user]) or in_array($subdomain, $user_domain[$user]) )
{
if ( $subdomain != "-" )
$subdomain = $subdomain . '.';
else
$subdomain = '';
// shell escape all values
$subdomain = escapeshellcmd($subdomain);
$user = escapeshellcmd($user);
$ip = escapeshellcmd($ip);
// prepare command
$data = "<<EOF
server $dnsserver $dnsport
zone $dyndns
update delete $subdomain$user.$dyndns A
update add $subdomain$user.$dyndns 300 A $ip
send
EOF";
// run DNS update
exec("/usr/bin/nsupdate -k /etc/named/K$dyndns*.private $data", $cmdout, $ret);
// check whether DNS update was successful
if ($ret != 0)
{
syslog(LOG_INFO, "Changing DNS for $subdomain$user.$dyndns to $ip failed with code $ret");
}
}
else
{
syslog(LOG_INFO, "Domain $subdomain is not allowed for $user from $ip");
}
}
else
{
syslog(LOG_INFO, "Domain $subdomain for $user from $ip with $subdomain was wrong");
}
}
else
{
syslog(LOG_INFO, "IP $ip for $user from $ip with $subdomain was wrong");
}
}
else
{
syslog(LOG_INFO, "DDNS change for $user from $ip with $subdomain failed because of missing values");
}
// close log session
closelog();
?>
У меня проблема с PHP-скриптом, когда я выполняю nsupdate:
/usr/bin/nsupdate -k /etc/named/Kdyndns.example.com*.private <<EOF
server ns.example.com
zone dyndns.example.com
update delete subdomain.user.dyndns.example.com A
update add subdomain.user.dyndns.example.com 300 A W.X.Y.Z
send
show
answer
debug
EOF
Результат $cmdout
:
Array
(
[0] => Outgoing update query:
[1] => ;; ->>HEADER<<- opcode: UPDATE, status: NOERROR, id: 0
[2] => ;; flags:; ZONE: 0, PREREQ: 0, UPDATE: 0, ADDITIONAL: 0
[3] => ;; ZONE SECTION:
[4] => ;dyndns.example.com. IN SOA
[5] =>
[6] => Answer:
[7] => ;; ->>HEADER<<- opcode: UPDATE, status: REFUSED, id: 17305
[8] => ;; flags: qr ra; ZONE: 1, PREREQ: 0, UPDATE: 0, ADDITIONAL: 0
[9] => ;; ZONE SECTION:
[10] => ;dyndns.example.com. IN SOA
[11] =>
)
$ret=2 // update failed
Но когда я выполняю ту же команду вручную, она работает правильно (я использовал команду, сгенерированную из сценария php, отображаемую функцией echo):
[root@server ~]# /usr/bin/nsupdate -k /etc/named/Kdyndns.example.com*.private <<EOF
server ns.example.com
zone dyndns.example.com
update delete subdomain.user.dyndns.example.com A
update add subdomain.user.dyndns.example.com 300 A W.X.Y.Z
send
show
answer
debug
EOF
echo ret=$?
Outgoing update query:
;; ->>HEADER<<- opcode: UPDATE, status: NOERROR, id: 0
;; flags:; ZONE: 0, PREREQ: 0, UPDATE: 0, ADDITIONAL: 0
;; ZONE SECTION:
;dyndns.example.com. IN SOA
Answer:
;; ->>HEADER<<- opcode: UPDATE, status: NOERROR, id: 17305
;; flags: qr ra; ZONE: 1, PREREQ: 0, UPDATE: 0, ADDITIONAL: 0
;; ZONE SECTION:
;dyndns.example.com. IN SOA
ret=0 //successful update
Я проверил представление, все в порядке, я добавил пользователя Apache в группу именованных, но все еще не работает:
[root@server ~]# usermod -a apache -G named
В чем ошибка в php скрипте?
Я использовал следующий скрипт php для обновления динамической записи DNS через мой веб-сервер, как описано в этой ссылке собственность- DDNS:
<?php
// configuration of user and domain
$user_domain = array( 'user' => array('subdomain','sub2'), 'user2' => array('sub4') );
// main domain for dynamic DNS
$dyndns = "dyndns.example.org";
// DNS server to send update to
$dnsserver = "localhost";
// port of DNS server
$dnsport = "";
// short sanity check for given IP
function checkip($ip)
{
$iptupel = explode(".", $ip);
foreach ($iptupel as $value)
{
if ($value < 0 || $value > 255)
return false;
}
return true;
}
// retrieve IP
$ip = $_SERVER['REMOTE_ADDR'];
// retrieve user
if ( isset($_SERVER['REMOTE_USER']) )
{
$user = $_SERVER['REMOTE_USER'];
}
else if ( isset($_SERVER['PHP_AUTH_USER']) )
{
$user = $_SERVER['PHP_AUTH_USER'];
}
else
{
syslog(LOG_WARN, "No user given by connection from $ip");
exit(0);
}
// open log session
openlog("DDNS-Provider", LOG_PID | LOG_PERROR, LOG_LOCAL0);
// check for given domain
if ( isset($_POST['DOMAIN']) )
{
$subdomain = $_POST['DOMAIN'];
}
else if ( isset($_GET['DOMAIN']) )
{
$subdomain = $_GET['DOMAIN'];
}
else
{
syslog(LOG_WARN, "User $user from $ip didn't provide any domain");
exit(0);
}
// check for needed variables
if ( isset($subdomain) && isset($ip) && isset($user) )
{
// short sanity check for given IP
if ( preg_match("/^(\d{1,3}\.){3}\d{1,3}$/", $ip) && checkip($ip) && $ip != "0.0.0.0" && $ip != "255.255.255.255" )
{
// short sanity check for given domain
if ( preg_match("/^[\w\d-_\*\.]+$/", $subdomain) )
{
// check whether user is allowed to change domain
if ( in_array("*", $user_domain[$user]) or in_array($subdomain, $user_domain[$user]) )
{
if ( $subdomain != "-" )
$subdomain = $subdomain . '.';
else
$subdomain = '';
// shell escape all values
$subdomain = escapeshellcmd($subdomain);
$user = escapeshellcmd($user);
$ip = escapeshellcmd($ip);
// prepare command
$data = "<<EOF
server $dnsserver $dnsport
zone $dyndns
update delete $subdomain$user.$dyndns A
update add $subdomain$user.$dyndns 300 A $ip
send
EOF";
// run DNS update
exec("/usr/bin/nsupdate -k /etc/named/K$dyndns*.private $data", $cmdout, $ret);
// check whether DNS update was successful
if ($ret != 0)
{
syslog(LOG_INFO, "Changing DNS for $subdomain$user.$dyndns to $ip failed with code $ret");
}
}
else
{
syslog(LOG_INFO, "Domain $subdomain is not allowed for $user from $ip");
}
}
else
{
syslog(LOG_INFO, "Domain $subdomain for $user from $ip with $subdomain was wrong");
}
}
else
{
syslog(LOG_INFO, "IP $ip for $user from $ip with $subdomain was wrong");
}
}
else
{
syslog(LOG_INFO, "DDNS change for $user from $ip with $subdomain failed because of missing values");
}
// close log session
closelog();
?>
У меня проблема с PHP-скриптом, когда я выполняю nsupdate:
/usr/bin/nsupdate -k /etc/named/Kdyndns.example.com*.private <<EOF
server ns.example.com
zone dyndns.example.com
update delete subdomain.user.dyndns.example.com A
update add subdomain.user.dyndns.example.com 300 A W.X.Y.Z
send
show
answer
debug
EOF
Результат $cmdout
:
Array
(
[0] => Outgoing update query:
[1] => ;; ->>HEADER<<- opcode: UPDATE, status: NOERROR, id: 0
[2] => ;; flags:; ZONE: 0, PREREQ: 0, UPDATE: 0, ADDITIONAL: 0
[3] => ;; ZONE SECTION:
[4] => ;dyndns.example.com. IN SOA
[5] =>
[6] => Answer:
[7] => ;; ->>HEADER<<- opcode: UPDATE, status: REFUSED, id: 17305
[8] => ;; flags: qr ra; ZONE: 1, PREREQ: 0, UPDATE: 0, ADDITIONAL: 0
[9] => ;; ZONE SECTION:
[10] => ;dyndns.example.com. IN SOA
[11] =>
)
$ret=2 // update failed
Но когда я выполняю ту же команду вручную, она работает правильно (я использовал команду, сгенерированную из сценария php, отображаемую функцией echo):
[root@server ~]# /usr/bin/nsupdate -k /etc/named/Kdyndns.example.com*.private <<EOF
server ns.example.com
zone dyndns.example.com
update delete subdomain.user.dyndns.example.com A
update add subdomain.user.dyndns.example.com 300 A W.X.Y.Z
send
show
answer
debug
EOF
echo ret=$?
Outgoing update query:
;; ->>HEADER<<- opcode: UPDATE, status: NOERROR, id: 0
;; flags:; ZONE: 0, PREREQ: 0, UPDATE: 0, ADDITIONAL: 0
;; ZONE SECTION:
;dyndns.example.com. IN SOA
Answer:
;; ->>HEADER<<- opcode: UPDATE, status: NOERROR, id: 17305
;; flags: qr ra; ZONE: 1, PREREQ: 0, UPDATE: 0, ADDITIONAL: 0
;; ZONE SECTION:
;dyndns.example.com. IN SOA
ret=0 //successful update
Я проверил представление, все в порядке, я добавил пользователя Apache в группу именованных, но все еще не работает:
[root@server ~]# usermod -a apache -G named
В чем ошибка в php скрипте?