Failover2

From XpertDNS

http://www.gnu.org/licenses/gpl.txt

Failover Monitor2 is used to monitor website, and if it were to go down it would update DNS to redirect traffic to another IP address. This script has been designed to work with Dynamic DNS at XpertDNS.com. This version has been updated to support our new DynDNS API.

Tested on PHP4 and PHP5 - Requires cURL support

You will need to configure your Dynamic DNS on your account for the domains you wish to update. Mainly for domains with www. and without. You can modify it to fit your needs.

Configure the script with the proper information and run this script in a cron job. You can run it as often as you like. In this example it will run every 5 minutes

*/5     *       *       *       *       php     /path/to/failover.php > /dev/null 2>&1

Source Code

<?php

### GPL
# Failover Monitor2 is used to monitor website, and if it were to go 
# down it would update DNS to redirect traffic to another IP address. 
# This script has been designed for http://www.xpertdns.com.
# Copyright (C) 2007  Michael Donnarumma  Xpert Group Technologies, Inc.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
###

############ Configuration Variables Start ############

## XpertDNS Login

$UNAME="username";     
$PASSWORD="passw0rd_hash"; #https://www.xpertdns.com/md5form.php 

## Tolerance

$tol = "3";     # How many consecutive failures before DNS is updated.

## Domain name and DynIDs

$domainname = "domain.com";
$domainname_id ="00";
$wwwdomainname = "www." . $domainname;
$wwwdomainname_id = "00";

## Server IPs

# Primary Server
$ipaddress = "192.168.0.1";

# Failover Server
$ipaddress2 = "192.168.0.2";


## File Paths
$filepath = '/tmp/';                    # This will need to be a path where php can write a file to keep track previous server state.
$logname = $filepath."failover.log";
$filename = $filepath."status.txt";

## Notification

# Where email is to be sent
$email = "user@domain.com";   

# Email's from address
$fromemail = "user@domain.com";   

# Body of message when site on primary server is goes down 
$downbody = "This message is to inform you that the site $domainname and $wwwdomainname at server $ipaddress cannot be reached and has been changed to $ipaddress2";

# Body of message when site on primary server is goes up
$upbody = "This message is to inform you that the site $domainname and $wwwdomainname at server $ipaddress can be reached and has been changed to $ipaddress";

############ Configuration Variables End ############

### Functions

function dns_get_headers($ip,$url,$format=0) {
       $url_info=parse_url($url);
       $port = "80";
       $fp=fsockopen($ip, $port, $errno, $errstr, 1);
       if($fp) {
           $head = "HEAD ".@$url_info['path']."?".@$url_info['query'];
           $head .= " HTTP/1.0\r\nHost: ".@$url_info['host']."\r\n\r\n";
           fputs($fp, $head);
           while(!feof($fp)) {
               if($header=trim(fgets($fp, 1024))) {
                   if($format == 1) {
                       $h2 = explode(':',$header);
                       if($h2[0] == $header) {
                           $headers['status'] = $header;
                       }
                       else {
                           $headers[strtolower($h2[0])] = trim($h2[1]);
                       }
                   }
                   else {
                       $headers[] = $header;
                   }
               }
           }
           return $headers;
       }
       else {
           return false;
       }
   }

function sendemail($email, $fromemail, $ipaddress, $ipaddress2, $domainname, $wwwdomainname, $body, $domainname_update, $wwwdomainname_update, $status) {
        $to = $email;
        $subject = "Failover Monitor - Host: $domainname $status";
        $message = $body;
        $message .= "\n\nUpdate Status:";
        $message .= "\n" . $domainname . " - "  . $domainname_update;
        $message .= "\n" . $wwwdomainname . " - "  . $wwwdomainname_update;
        $headers = "From: " . $fromemail;
        $headers .= "\r\nReply-To: " . $fromemail;
        $sentOk = mail($to,$subject,$message,$headers);
        global $logname;
        faillog($logname, "Message sent ".$sentOk);
}

function dnsupdate($DYNID, $ip, $UNAME, $PASSWORD) {
        $path="dynid=$DYNID&ip=$ip&uname=$UNAME&password=$PASSWORD";
        $sessions = curl_init();
                curl_setopt($sessions, CURLOPT_URL,'https://www.xpertdns.com/dyndns.php');
                curl_setopt($sessions, CURLOPT_POST, 1);
                curl_setopt($sessions, CURLOPT_POSTFIELDS, $path);
                curl_setopt($sessions, CURLOPT_FOLLOWLOCATION,0);
                curl_setopt($sessions, CURLOPT_RETURNTRANSFER,1);
        $my_load_page = curl_exec($sessions);
        return $my_load_page;
}

function writestat($filename, $data) {
        if (!$file_handle = fopen($filename,"w")) { echo "Cannot open file"; }
        if (!fwrite($file_handle, $data)) { echo "Cannot write to file"; }
        fclose($file_handle);
}

function faillog($logname, $l) {
        $d = date('Y-m-d H:i:s T');
        $data = "\n".$d." ".$l;
        if (!$file_handle = fopen($logname,"a")) { echo "Cannot open file"; }
        if (!fwrite($file_handle, $data)) { echo "Cannot write to file"; }
        fclose($file_handle);
}

#### Script Start
### Get current status of server
$response = @dns_get_headers($ipaddress,"http://$domainname/", 0);
if (!$response) {
        $curstatus = "1";
}elseif($response[0]='HTTP/1.1 200 OK'){
        $curstatus = "0";
}

### Check if file exists
## File does exist

if (file_exists($filename) && filesize($filename)>'0') {
        $fh = fopen($filename, 'r');
        $status = fread($fh, filesize($filename));
        fclose($fh);

## Site was online
        if($status=='0') {
                if($curstatus=='0') {
                echo "Nothing to see here";
                exit;
                }elseif($curstatus=='1'){
                        writestat($filename, $curstatus);
                        if ($tol == $curstatus){
                                $stat = "DOWN!";
                                $l = "Host $stat - Updating DNS";
                                faillog($logname, $l);
                                $ip = $ipaddress2;


                                $body = $downbody;
                                $domainname_update = dnsupdate($domainname_id, $ip, $UNAME, $PASSWORD);
                                $wwwdomainname_update = dnsupdate($wwwdomainname_id, $ip, $UNAME, $PASSWORD);
                                sendemail($email, $fromemail, $ipaddress, $ipaddress2, $domainname, $wwwdomainname, $body, $domainname_update, $wwwdomainname_update, $stat);
                        }
                }
## Site was not online
        }elseif($status>='1') {
                if($curstatus=='1') {
                        $tolstat = $status + 1;
                        writestat($filename, $tolstat);
                        if ($tol == $status){
                                $stat = "DOWN!";
                                $l = "Host DOWN! - Tolerance ($status/$tol) reached, Updating DNS";
                                faillog($logname, $l);
                                $ip = $ipaddress2;
                                $body = $downbody;
                                $domainname_update = dnsupdate($domainname_id, $ip, $UNAME, $PASSWORD);
                                $wwwdomainname_update = dnsupdate($wwwdomainname_id, $ip, $UNAME, $PASSWORD);
                                sendemail($email, $fromemail, $ipaddress, $ipaddress2, $domainname, $wwwdomainname, $body, $domainname_update, $wwwdomainname_update, $stat);
                        }elseif($tol > $status){
                                $l = "Host DOWN! - Tolerance ($status/$tol) not reached, waiting a bit longer";
                                faillog($logname, $l);
                        }elseif($tol < $status){
                                $l = "Host DOWN! - Tolerance ($status/$tol) exceeded, waiting for server to become available";
                                faillog($logname, $l);
                        }
                }elseif($curstatus=='0'){
                        if ($tol <= $status){
                                $stat = "UP!";
                                $l = "Host $stat - Updating DNS";
                                faillog($logname, $l);
                                $ip = $ipaddress;
                                $body = $upbody;
                                $domainname_update = dnsupdate($domainname_id, $ip, $UNAME, $PASSWORD);
                                $wwwdomainname_update = dnsupdate($wwwdomainname_id, $ip, $UNAME, $PASSWORD);
                                sendemail($email, $fromemail, $ipaddress, $ipaddress2, $domainname, $wwwdomainname, $body, $domainname_update, $wwwdomainname_update, $stat);
                                writestat($filename, $curstatus);
                        }elseif($tol > $status){
                                $l = "Host UP! - Tolerance ($status/$tol) not reached, no need to update";
                                faillog($logname, $l);
                                writestat($filename, $curstatus);
                        }
                }
        }

<ul></ul>
## File does not exist
} else {
                if($curstatus=='1') {
                        writestat($filename, $curstatus);
                        $stat = "DOWN!";
                        $l = "Creating status file - Host $stat - Updating DNS";
                        faillog($logname, $l);
                        $ip = $ipaddress2;
                        $body = $downbody;
                        $domainname_update = dnsupdate($domainname_id, $ip, $UNAME, $PASSWORD);
                        $wwwdomainname_update = dnsupdate($wwwdomainname_id, $ip, $UNAME, $PASSWORD);
                        sendemail($email, $fromemail, $ipaddress, $ipaddress2, $Domainname, $wwwdomainname, $body, $domainname_update, $wwwdomainname_update, $stat);
                }elseif($curstatus=='0'){
                        writestat($filename, $curstatus);
                        $stat = "UP!";
                        $l = "Creating status file - Host $stat - Updating DNS";
                        faillog($logname, $l);
                        $ip = $ipaddress;
                        $body = $upbody;
                        $domainname_update = dnsupdate($domainname_id, $ip, $UNAME, $PASSWORD);
                        $wwwdomainname_update = dnsupdate($wwwdomainname_id, $ip, $UNAME, $PASSWORD);
                        sendemail($email, $fromemail, $ipaddress, $ipaddress2, $domainname, $wwwdomainname, $body, $domainname_update, $wwwdomainname_update, $stat);
                }
}

?>