blog:2017:0719_dynip_client_fuer_powerdns_the_simple_way_update

dynip client für powerdns (the simple way) **UPDATE**

Ich hatte 2014 schon mal einen Beitrag zu Selbstgehosteten dyndns geschrieben.
Leider wird das alte Script nicht mehr mit php7 unterstützt, daher bin ich her gegangen und habe die Lösung neu gemacht.
Das neue PHP-Script stammt von: https://www.gillwaldt.de/projekte/do-it-yourself/dyndns-mit-bind-und-php/

Wenn jemand Lust hat und das alte Script auf php7 migriert, immer her damit! :)

Ihr braucht nach wie vor noch powerdns mit mysql. Wenn ihr fragen dazu habt, schreibt mir einfach. Dann würde ich einfach noch mal ein Beitrag dazu schreiben.

<?php
// call : https://<dnsserver_url>/dyndns.php?ipaddr=<ipaddr>&username=<username>&password=<pass>&domain=<domain>&ip6addr=<ip6addr>
$accounts[] = array("user"=>"name_des_users", "pass"=>"passwort_des_users", "host"=>"fqdn_des_dyndns_records");
$fp = fopen("/var/log/dyndns.log", "a");
fwrite($fp, "\n[".time()." - ".date('M d H:i:s Y') ."] ". $_SERVER['REMOTE_ADDR']. " called DynDns with " .$_SERVER['REQUEST_URI'] . " by " . $_SERVER['HTTP_USER_AGENT'] );
// find account
$account = NULL;
foreach( $accounts AS $acc ){
  if( isset($_REQUEST['username']) && isset($_REQUEST['domain']) && strcasecmp($acc['user'],$_REQUEST['username'])==0 && strcasecmp($acc['host'],$_REQUEST['domain'])==0 ) $account = $acc;
}
if( count($account)==NULL ){
  fwrite($fp, "\n[".time()." - ".date('M d H:i:s Y') ."] ". $_SERVER['REMOTE_ADDR']. " Username and/or Domain not found. Quit here." );
  fclose($fp);
  die("badauth");
}
fwrite($fp, "\n[".time()." - ".date('M d H:i:s Y') ."] ". $_SERVER['REMOTE_ADDR']. " Account found." );
// check password
if( !isset($_REQUEST['password']) || strcmp($account['pass'],$_REQUEST['password'])!=0 ){
  fwrite($fp, "\n[".time()." - ".date('M d H:i:s Y') ."] ". $_SERVER['REMOTE_ADDR']. " Password wrong. Quit here." );
  fclose($fp);
  die("badauth");
}
fwrite($fp, "\n[".time()." - ".date('M d H:i:s Y') ."] ". $_SERVER['REMOTE_ADDR']. " Auth successful." );
// check if ip overgiven
// TODO: if ip/ipv6 not given, delete the entries from database
if( !isset($_REQUEST['ipaddr']) && !isset($_REQUEST['ip6addr']) ){
  fwrite($fp, "\n[".time()." - ".date('M d H:i:s Y') ."] ". $_SERVER['REMOTE_ADDR']. " No ip given. Quit here." );
  fclose($fp);
  die("noip");
}
// mysql connect
$mysqli = new mysqli("localhost", "pdns", "<mysql_pdns_user_password>", "pdns");
if ($mysqli->connect_errno) {
  fwrite($fp, "\n[".time()." - ".date('M d H:i:s Y') ."] ". $_SERVER['REMOTE_ADDR']. " MySQL server connect failed. Quit here. " . $mysqli->connect_error );
  fclose($fp);
  $mysqli->close();
  die('Error');
}
// ipv6
if( isset($_REQUEST['ip6addr']) ){
  if( filter_var($_REQUEST['ip6addr'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) ){
    $ip = $_REQUEST['ip6addr'];
    $rs = $mysqli->query("SELECT id, content FROM records WHERE name = '".$account['host']."' AND type = 'AAAA';");
    // soa updaten (serial+1)
    $rs_soa = $mysqli->query("SELECT id, content, domain_id FROM records WHERE name = 'dayz.net' AND type = 'SOA';");
    $row_soa = $rs_soa->fetch_assoc();
    $ser = preg_replace("/.*dayz\.net\.[ ]([0-9]*)[ ].*/", "$1", $row_soa['content']);
    $content = preg_replace("/(.*dayz\.net\.[ ])[0-9]*([ ].*)/", "$1###$2", $row_soa['content']);
    $content = str_replace( "###", ($ser+1), $content );
    if( $rs->num_rows==0){
      // create entry
      $sql = "INSERT INTO records ( domain_id, name, type, content, ttl, auth) VALUES ( ".$row_soa['domain_id'].", '".$account['host']."', 'AAAA', '".$ip."', 60, 1 );";
      $mysqli->query( $sql );
      $mysqli->query("UPDATE records SET content = '".$content."' WHERE id = ".$row_soa['id'].";");
      fwrite($fp, "\n[".time()." - ".date('M d H:i:s Y') ."] ". $_SERVER['REMOTE_ADDR']. " Record (Host) not found, created ip v6 record." );
    }else{
      $row_a = $rs->fetch_assoc();
      if( strcasecmp($row_a['content'],$ip)==0 ){
        fwrite($fp, "\n[".time()." - ".date('M d H:i:s Y') ."] ". $_SERVER['REMOTE_ADDR']. " Ip v6 not changed. Skipping." );
      }else{
        // update
        $mysqli->query("UPDATE records SET content = '".$ip."' WHERE id = ".$row_a['id'].";" );
        $mysqli->query("UPDATE records SET content = '".$content."' WHERE id = ".$row_soa['id'].";");
        fwrite($fp, "\n[".time()." - ".date('M d H:i:s Y') ."] ". $_SERVER['REMOTE_ADDR']. " Ip v6 updated." );
      }
    }
  }else{
    fwrite($fp, "\n[".time()." - ".date('M d H:i:s Y') ."] ". $_SERVER['REMOTE_ADDR']. " Ip v6 address not valid. Skipping." );
  }
}else{
  fwrite($fp, "\n[".time()." - ".date('M d H:i:s Y') ."] ". $_SERVER['REMOTE_ADDR']. " No Ip v6 address found. Skipping." );
}
// ipv4
if( isset($_REQUEST['ipaddr']) ){
  if( filter_var($_REQUEST['ipaddr'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) ){
    $ip = $_REQUEST['ipaddr'];
    $rs = $mysqli->query("SELECT id, content FROM records WHERE name = '".$account['host']."' AND type = 'A';");
    // soa updaten (serial+1)
    $rs_soa = $mysqli->query("SELECT id, content, domain_id FROM records WHERE name = 'dayz.net' AND type = 'SOA';");
    $row_soa = $rs_soa->fetch_assoc();
    $ser = preg_replace("/.*dayz\.net\.[ ]([0-9]*)[ ].*/", "$1", $row_soa['content']);
    $content = preg_replace("/(.*dayz\.net\.[ ])[0-9]*([ ].*)/", "$1###$2", $row_soa['content']);
    $content = str_replace( "###", ($ser+1), $content );
    if( $rs->num_rows==0){
      // create entry
      $mysqli->query("INSERT INTO records ( domain_id, name, type, content, ttl, auth) VALUES ( ".$row_soa['domain_id'].", '".$account['host']."', 'A', '".$ip."', 60, 1 );");
      $mysqli->query("UPDATE records SET content = '".$content."' WHERE id = ".$row_soa['id'].";");
      fwrite($fp, "\n[".time()." - ".date('M d H:i:s Y') ."] ". $_SERVER['REMOTE_ADDR']. " Record (Host) not found, created ip v4 record." );
    }else{
      $row_a = $rs->fetch_assoc();
      if( strcasecmp($row_a['content'],$ip)==0 ){
        fwrite($fp, "\n[".time()." - ".date('M d H:i:s Y') ."] ". $_SERVER['REMOTE_ADDR']. " Ip v4 not changed. Skipping." );
      }else{
        // update
        $mysqli->query("UPDATE records SET content = '".$ip."' WHERE id = ".$row_a['id'].";" );
        $mysqli->query("UPDATE records SET content = '".$content."' WHERE id = ".$row_soa['id'].";");
        fwrite($fp, "\n[".time()." - ".date('M d H:i:s Y') ."] ". $_SERVER['REMOTE_ADDR']. " Ip v4 updated." );
      }
    }
  }else{
    fwrite($fp, "\n[".time()." - ".date('M d H:i:s Y') ."] ". $_SERVER['REMOTE_ADDR']. " Ip v4 address not valid. Skipping." );
  }
}else{
  fwrite($fp, "\n[".time()." - ".date('M d H:i:s Y') ."] ". $_SERVER['REMOTE_ADDR']. " No Ip v4 address found. Skipping." );
}
$mysqli->close();
fwrite($fp, "\n[".time()." - ".date('M d H:i:s Y') ."] ".$_SERVER['REMOTE_ADDR'] ." host ".$account['host']." done." );
fclose($fp);
echo "good ".$ip;
?> 

Ich habe es nicht ausprobiert, aber denkbar wäre es, wenn ihr kein IPv6 habt, dass es dann zu einem Fehler kommt.
Daher löscht die IPv6 Sachen in dem Fall einfach raus. Das wäre einmal das PIP6 Zeugs und einmal im updatestring &ip6addr=„$PIP6“

dyn_update.sh
#!/bin/sh

#this is your dyn host
export DYNURL="deine_dyn_url"

#this you username
export USER="dein_user"

#this you password
export PASS="dein_passwort"

export PIP="$(wget -qO- ipv4.icanhazip.com)"
export PIP6="$(wget -qO- ipv6.icanhazip.com)"
export DIP="$(nslookup "$DYNURL" | awk '/^Address: / { print $2 }')"

#here comes your url to dynamic-powerdns with your password
export UPDATESTRING="https://die_url_zur_dynupdate.php?ipaddr="$PIP"&username="$USER"&password="$PASS"&domain="$DYNURL"&ip6addr="$PIP6""

echo $PIP
echo $PIP6
echo $DIP

if [ "$PIP" = "$DIP" ]
  then
    echo "same IP - nothing to do"
  elif [ "$PIP" = "" ]
    then
      echo "Can't obtain IP Adress - check Network connection!"
  elif [ "$DIP" = "" ]
    then
      echo "Call Dynhost Admin his Server is down!!!"
      logger warning Call dynhost Admin his Server is Down #can be deleted if you have systemd
  else
    wget -qO- $UPDATESTRING
fi
  • Zuletzt geändert: 2022/01/07 03:31
  • (Externe Bearbeitung)