====== dynip client für powerdns (the simple way) **UPDATE** ====== Ich hatte [[blog:2017:0719_dynip_client_fuer_opendns_the_simple_way | 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 [[https://github.com/zundg/dynamic-powerdns |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.\\ ====== ====== /dyndns.php?ipaddr=&username=&password=&domain=&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", "", "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"\\ #!/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