Skip to content

Instantly share code, notes, and snippets.

@karlbaillie
Last active December 14, 2015 09:38
Show Gist options
  • Save karlbaillie/08bad4394403ede96a73 to your computer and use it in GitHub Desktop.
Save karlbaillie/08bad4394403ede96a73 to your computer and use it in GitHub Desktop.
cPanel Reseller Account Backup Script
<html>
<!-- START HTML -->
<head>
<title>Reseller Account Backup Script</title>
</head>
<body>
<div id="messages"></div>
</body>
<?php function w($message) { ?>
<script language="javascript">document.getElementById('messages').innerHTML = document.getElementById('messages').innerHTML + "<?=$message;?>";</script>
<?php @ob_flush(); @flush(); } ?>
<!-- END HTML -->
</html>
<?php
// Get start time
$time_start = getMicroTime();
// ########################### Config ###############################
$whm_hostname = 'servers-hostname'; // Your WHM servers hostname or IP
$whm_user = 'whm-username'; // Your WHM username
$whm_pass = 'whm-password'; // Your WHM password
$use_ssl = true; // Use SSL (true/false)
$retry = true;
$cp_ssl = '2083'; // cPanel SSL Port
$whm_ssl = '2087'; // WHM SSL Port
$cp_nossl = '2082'; // cPanel Non-SSL Port
$whm_nossl = '2086'; // WHM Non-SSL Port
$bkup_dest = 'local'; // Backup Destination ('local' OR 'ftp')
// FTP Details (required if backup destination = 'ftp')
$ftp_hostname = ''; // Your FTP servers hostname or IP
$ftp_port = '21'; // Your FTP servers port
$ftp_user = 'user'; // Your FTP username
$ftp_pass = 'pass'; // Your FTP password
$ftp_dir = '/'; // Your FTP directory (e.g. '/' for root, or '/backups/')
// Local Details (required if backup destination = 'local')
$local_dir = '/home/backups/';
// Include domains (leave blank to backup all accounts)
$inc_domains = array();
//$inc_domains['0'] = 'domain1.com';
//$inc_domains['1'] = 'domain2.com';
// Exclude domains (ignored if include domains defined)
$exc_domains = array();
//$exc_domains['0'] = 'domain3.com';
//$exc_domains['1'] = 'domain4.com';
// ########################### Main ###############################
// Remove script time limit
set_time_limit(0);
w("################ CONFIG ###############<br />");
w("Connecting to '".$whm_hostname."'<br />");
// Define SSL/Non-SSL details
if($use_ssl) {
$protocol = 'https://';
$cp_port = $cp_ssl;
$whm_port = $whm_ssl;
w("Using SSL via ports '".$cp_port."' (cPanel) and '".$whm_port."' (WHM)<br />");
} else {
$protocol = 'http://';
$cp_port = $cp_nossl;
$whm_port = $whm_nossl;
w("NOT using SSL via ports '".$cp_port."' (cPanel) and '".$whm_port."' (WHM)<br />");
}
w("Using WHM user '".$whm_user."'<br />");
// If domains have been defined in the config then parse them
if(!empty($inc_domains) OR !empty($exc_domains)){
if(!empty($inc_domains) && !empty($exc_domains)) {
die("<b>RTFM:</b> You cannot both selectively include and exclude domains!");
} else {
w("Selective backup ENABLED<br />");
if(!empty($inc_domains)) {
$check_domains = true;
w("Backing up included domains ONLY<br />");
foreach($inc_domains as $d){
clean_domains($d);
}
} elseif (!empty($exc_domains)) {
$check_domains = true;
w("Backing up all EXCEPT excluded domains<br />");
foreach($inc_domains as $d){
clean_domains($d);
}
}
}
} elseif(empty($inc_domains) && empty($exc_domains)) {
$check_domains = false;
w("Selective backup DISABLED<br />");
$inc_domains = array();
}
w("############# CONFIG END ##############<br /><br />");
// Get the WHM accounts CSV
w("<h2>Retrieving WHM Accounts List</h2>");
$accounts_page = get_curl("$protocol$whm_hostname:$whm_port/scripts/fetchcsv",$whm_user,$whm_pass,false,NULL);
// Place it into an array
$accounts = array();
$accounts = explode("\n", trim($accounts_page));
// Make sense of the data and place it into the account_records array
$account_records = array();
foreach ($accounts as $row) {
$account_records[] = explode(',', $row);
}
if (!$check_domains) {
w("Found: ");
foreach($account_records as $user) {
$show_domain = strip_tags(trim($user[0]));
$show_size = format_bytes(strip_tags(trim($user[13])));
w("'".$show_domain."' (".$show_size.") - ");
}
w("<br /><br />");
}
// Parse accounts CSV and take backups
w("<h2>Downloading Backups</h2>");
foreach($account_records as $match) {
// Clear variables
$account_domain = '';
$account_user = '';
$full_url = '';
$path = '';
$data = '';
// Populate variables
$account_domain = strip_tags(trim($match[0]));
$account_user = strip_tags(trim($match[2]));
$full_url = "$protocol$account_domain:$cp_port/getsysbackup/daily.tar.gz";
$path = $local_dir.$account_user.'_DATE.tar.gz';
if ($check_domains) {
foreach ($inc_domains as $d) {
if ($d === $account_domain) {
w("> Downloading backup for ".$account_domain." (".$account_user.")...<br />");
$data = get_curl($full_url,$account_user,$whm_pass,true,$path);
if($data == FALSE && $retry == TRUE) {
$retry_url = "$protocol$whm_hostname:$cp_port/getsysbackup/daily.tar.gz";
w("<b>RETRYING: using hostname '".$whm_hostname."'</b><br />");
$data = get_curl($retry_url,$account_user,$whm_pass,true,$path);
if($data != FALSE) {
check_file($path,$account_domain,$account_user);
}
} elseif ($data != FALSE) {
check_file($path,$account_domain,$account_user);
}
}
}
} elseif (!$check_domains) {
w("> Downloading backup for ".$account_domain." (".$account_user.")...<br />");
$data = get_curl($full_url,$account_user,$whm_pass,true,$path);
if($data == FALSE && $retry == TRUE) {
$retry_url = "$protocol$whm_hostname:$cp_port/getsysbackup/daily.tar.gz";
w("<b>RETRYING: using hostname '".$whm_hostname."'</b><br />");
$data = get_curl($retry_url,$account_user,$whm_pass,true,$path);
if($data != FALSE) {
check_file($path,$account_domain,$account_user);
}
} elseif ($data != FALSE) {
check_file($path,$account_domain,$account_user);
}
}
}
// Get end time
$time_end = getMicroTime();
$time = $time_end - $time_start;
w("Process time: ".round($time,2)." seconds<br />");
// ########################### Functions ###############################
function check_file($f = '', $d = '', $u = '') {
$filesize = filesize($f);
if ($filesize <= 0) {
w("<b>WARNING: Backup for ".$d." (".$u.") appears incomplete!</b><br /><br />");
} else {
w("File ".$f." saved!<br /><br />");
}
}
function get_curl($url, $user = '', $pass = '', $download = '', $path = '') {
global $use_ssl;
$ch = curl_init();
if ($download) $fp = fopen($path, "w+");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_USERPWD, "$user:$pass");
curl_setopt($ch, CURLOPT_FOLLOWLOCATION,1);
curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
curl_setopt($ch, CURLOPT_MAXREDIRS, 10);
if ($download) curl_setopt($ch, CURLOPT_FILE, $fp);
if ($use_ssl) curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0);
if ($use_ssl) curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);
$result = curl_exec($ch);
if(!curl_errno($ch)) {
$info = curl_getinfo($ch);
w("Took ".$info['total_time']." seconds to request '".$info['url']."'<br/>");
return $result;
} else {
w("<b>CURL Error: ".curl_error($ch)." ('".$url."')</b><br />");
if($retry) {
$result = FALSE;
return $result;
}
}
curl_close($ch);
if ($download) fclose($fp);
}
function format_bytes($bytes, $precision = 2) {
$units = array('B', 'KB', 'MB', 'GB', 'TB');
$bytes = max($bytes, 0);
$pow = floor(($bytes ? log($bytes) : 0) / log(1024));
$pow = min($pow, count($units) - 1);
// Uncomment one of the following alternatives
// $bytes /= pow(1024, $pow);
// $bytes /= (1 << (10 * $pow));
return round($bytes, $precision) . ' ' . $units[$pow];
}
function clean_domains(&$var) {
$var = trim($var);
}
function getMicroTime(){
list($usec, $sec) = explode(" ",microtime());
return ((float)$usec + (float)$sec);
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment