Hi, I am writing a small script to update a DNS entry remotely, to be used to update the IP address of machine with dynamic IP. my client script will authenticate via the url, which will look something like: http://server:8080/tools/dyndns/update.php?domain=domain.com&user=name&pass=pswd I managed to authenticate against the sys_user table, and I was wondering what values should I check to know the user has access to a particular row in the dns_rr table. if anyone is interested, I will share the result (client and server side scripts).
mathematically speaking, the answer is yes. in other words, both. This is what I ended up doing: PHP: $sql = "SELECT * FROM sys_user WHERE USERNAME = '$user' and ( PASSWORT = '".md5($pass)."' or PASSWORT = password('$pass') )"; $app->db->show_error_messages = true; $dbuser = $app->db->queryOneRecord($sql); if ($dbuser === false) error(403, "authentication failed"); $groups = $dbuser['groups']; $id = $app->db->queryOneRecord("SELECT id FROM dns_rr WHERE name = '$domain' AND type = 'A' AND sys_groupid IN ($groups)"); I verify that the dns record row sys_groupid is one of the user groups. what do you think?
great. here is the code, if anyone is interested. I put it in: /usr/local/ispconfig/interface/web/tools/dyndns PHP: <?php$user = $_GET['user'];$pass = $_GET['pass'];$ip = isset($_GET['ip']) ? isset($_GET['ip']) : $_SERVER['REMOTE_ADDR'];$domain = !empty($_GET['domain']) ? $_GET['domain'] : error(500, "missing domain");require_once('../../../lib/config.inc.php');require_once('../../../lib/classes/auth.inc.php');require_once('../../../lib/app.inc.php');global $app;$ip = $app->db->quote($ip);$user = $app->db->quote($user);$pass = $app->db->quote($pass);$domain = $app->db->quote($domain);$sql = "SELECT * FROM sys_user WHERE USERNAME = '$user' and ( PASSWORT = '".md5($pass)."' or PASSWORT = password('$pass') )";$app->db->show_error_messages = true;$dbuser = $app->db->queryOneRecord($sql);if ($dbuser === false) error(403, "authentication failed");$groups = $dbuser['groups'];$id = $app->db->queryOneRecord("SELECT id FROM dns_rr WHERE name = '$domain' AND type = 'A' AND sys_groupid IN ($groups)");if ($id === false) error(404, "DNS record not found");$id = $id['id'];$app->db->query("UPDATE dns_rr SET data = '$ip' WHERE id = $id");function error($code, $msg){ header("HTTP/1.0 $code $msg"); echo $msg; die();}?> Client code example: #! /bin/sh # this code should run from cron.houry of the machine that need to update the dns USER=username PASS=password DOMAINS=(domain1.com. domain2.com.) for DOMAIN in ${DOMAINS[@]} do URL="http://YOUR_ISPCONFIG_SERVER:8080/tools/dyndns/update.php" response=$(HEAD -m GET "$URL?user=$USER&pass=$PASS&domain=$DOMAIN") || echo $response done Note that the domains should be exactly as mentioned in the dns_rr table (including trailing dot).
There is one small modification that I would recommend. Instead of calling: Code: $app->db->query("UPDATE SET WHERE id = $id"); better use: Code: $app->db->datalogUpdate('dns_rr', "data = '$ip'", 'id', $id); This will update the data in the dns_rr table and additionally create a record in the sys_datalog table which is read by the server process. This does not bring you any benefit at the moment, but your code will later benefit when: - Other DNS plugins are available e.g. support for bind. - If plugins at the server have to be called when a dns record changes. Without using the datalogUpdate function, your manual change would be simply ignored by all server related code. - There is a history and undo function planned for the interface to track user interactions and to make it possible to revert changes. Without using this update function, your changes will not be tracked.
I do see some benefits in doing it as you described, but the undo and history would probably be more harm than good. this is expected to be called every hour, it will create 24 changes/day. can really spam the change log.
Thats up to you. It just may happen that your addon becomes incompatible with future versions of ISPConfig that might require to log all activity to datalog. For example your plugin will not work on multi server setups of the next ispconfig release.
I see this is quite an old thread, has this or something similar been integrated into ISPConfig3 yet? I can see anything in the UI but this would be extremely useful for me. Cheers.
Thanks Till. This script appears to update the entire zone rather than just an A record, because I am not a programmer, can someone please advise if I was to set the "domain.com" address to just an A record whether the script will just update that A record? DTC had a similar thing however would only work with HTTPS, really keen to see if I can get this to work with just HTTP on an A record only.
Strange, to me the above seems to update the IP for a domain A record only. However, I am not sure if that is still working in 3.1. I am using dynamic dns too and my way of auto updating my server and all domains in it is here.
Thanks ahrasis. The feature I require is to use a link to update an A record. I have multiple devices in the field that I would like to have "Post" the link which will update the IP for each A record. I will then be able to remotely connect into the device and transfer data as required. The devices are using public dynamic IP's so this solution will work a treat, if I can get it to work.
In that case, the above script should be useful for you, provided you can make it works of course. Have you checked the remote api as well? May be the dns_a_update.php?
The script ill just update that a-record. But you'll have to do the modification that I posted n #6 to make it work properly. And the domain name has to be passed in the URL with a dot at the end "domain.tld." as it is used in DNS.
Did that Till, got this error.. Falsche Anfrage / Wrong QuerySQL-Query = SELECT id FROM dns_rr WHERE name = 'xxxx.xxxx.com.au.' AND type = 'A' AND sys_groupid IN ()
The structure is not the problem here I guess, the problem seems to be that the user that you pass to the script does not exist.