Dynamic DNS

Discussion in 'Developers' Forum' started by omry, Sep 17, 2008.

  1. omry

    omry New Member

    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).
     
  2. falko

    falko Super Moderator

    Is this an ISPConfig or MyDNSConfig question?
     
  3. omry

    omry New Member

    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 === falseerror(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?
     
  4. till

    till Super Moderator

    This looks correct.
     
  5. omry

    omry New Member

    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 === falseerror(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 === falseerror(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).
     
    Last edited: Sep 19, 2008
  6. till

    till Super Moderator

    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.
     
    Last edited: Sep 19, 2008
  7. omry

    omry New Member

    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.
     
  8. till

    till Super Moderator

    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.
     

Share This Page