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 Howtoforge Staff

    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 Staff Member ISPConfig Developer

    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
    ahrasis likes this.
  6. till

    till Super Moderator Staff Member ISPConfig Developer

    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 Staff Member ISPConfig Developer

    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.
     
  9. FFH

    FFH Member

    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.
     
    Last edited: Oct 30, 2017
  10. till

    till Super Moderator Staff Member ISPConfig Developer

    This thread is about ISPConfig 3.seems as if it was posted in the wrong forum.
     
  11. FFH

    FFH Member

    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. :)
     
  12. ahrasis

    ahrasis Well-Known Member HowtoForge Supporter

    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.
     
  13. FFH

    FFH Member

    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. :)
     
  14. ahrasis

    ahrasis Well-Known Member HowtoForge Supporter

    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?
     
  15. FFH

    FFH Member

    What remote API?
     
  16. ahrasis

    ahrasis Well-Known Member HowtoForge Supporter

  17. till

    till Super Moderator Staff Member ISPConfig Developer

    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.
     
  18. FFH

    FFH Member

    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 ()
     
  19. FFH

    FFH Member

    Not sure what error means but it would appear to be an issue with the DB structure?
     
  20. till

    till Super Moderator Staff Member ISPConfig Developer

    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.
     

Share This Page