PHP

Работа с недокументированными API WHM и cPanel

cPanel является одной из самых популярных коммерческих панелей управления аккаунтами на серверах виртуального хостинга. Все действия выполняются обычно через web-интерфейс, но для использования в ваших проектах авторами предоставляется API. К сожалению вообще никакой вменяемой документации разработчикам не предоставляется. Эту позорную отмазку на официальном сайте назвать технической документацией трудно, поэтому при разработке очередного проекта пришлось создавать собственный класс для работы с cPanel. Попутно удалось реализовать несколько недокументированных функций и расширить функционал уже имеющихся.
<?
// -------------------------------------------------------------
// Класс для работы с WHM/cPanel через API
// (C) ManHunter / PCL
// http://www.manhunter.ru
// -------------------------------------------------------------
class cpanel_class {
  var $cpanelaccterr;
  var $host;
  var $user;
  var $accesshash;
  var $usessl;
 
  // -------------------------------------------------------------
  // Изменить пароль на аккаунте
  // Для выполнения нужна авторизация только с рутовым доступом
  // $chuser - аккаунт на сервере
  // $password - новый пароль
  // -------------------------------------------------------------
  function chgpassword ($chuser, $password) {
    if ($this->user!="root") {
      $this->cpanelaccterr="Root privileges required";
      return;
    }
    $result = $this->whmreq("/scripts/passwd?user=${chuser}&password=${password}&password2=${password}");
    $result=eregi_replace("[\n]{1,}","\n",strip_tags($result));
    if ($this->cpanelaccterr != "") { return; }
    if (strpos($result,"could not be changed")!==false) {
      $this->cpanelaccterr=$result;
      return;
    }
    return $result;
  }
 
  // -------------------------------------------------------------
  // Заблокировать аккаунт
  // $suspenduser - аккаунт на сервере
  // $reason - причина блокировки, сделано на перспективу,
  //           фактически параметр панелью игнорируется
  // -------------------------------------------------------------
  function suspend ($suspenduser, $reason="") {
    $reason=str_replace(" ","+",$reason);
    $result = $this->whmreq("/scripts/remote_suspend?user=${suspenduser}&reason=${reason}");
    if ($this->cpanelaccterr != "") { return; }
    if (strpos($result,"Access Denied")!==false) {
      $this->cpanelaccterr=$result;
      return;
    }
    return $result;
  }
 
  // -------------------------------------------------------------
  // Разблокировать аккаунт
  // $unsuspenduser - аккаунт на сервере
  // -------------------------------------------------------------
  function unsuspend ($unsuspenduser) {
    $result = $this->whmreq("/scripts/remote_unsuspend?user=${unsuspenduser}");
    if ($this->cpanelaccterr != "") { return; }
    if (strpos($result,"Access Denied")!==false) {
      $this->cpanelaccterr=$result;
      return;
    }
    return $result;
  }
 
  // -------------------------------------------------------------
  // Удалить аккаунт
  // $killuser - аккаунт на сервере
  // -------------------------------------------------------------
  function killacct ($killuser) {
    $result = $this->whmreq("/scripts/killacct?user=${killuser}&nohtml=1");
    if ($this->cpanelaccterr != "") { return; }
    return $result;
  }
 
  // -------------------------------------------------------------
  // Показать версию WHM/cPanel
  // -------------------------------------------------------------
  function showversion () {
    $result = $this->whmreq("/scripts2/showversion");
    if ($this->cpanelaccterr != "") { return; }
    return $result;
  }
 
  // -------------------------------------------------------------
  // Перевести аккаунт на новый тарифный план
  // $upuser - аккаунт на сервере
  // $acctplan - новый тарифный план
  // -------------------------------------------------------------
  function update ($upuser, $acctplan) {
    $acctplan=str_replace(" ","+",$acctplan);
    $result = $this->whmreq("/scripts2/upacct?user=${upuser}&pkg=${acctplan}");
    if ($this->cpanelaccterr != "") { return; }
    return $result;
  }
 
  // -------------------------------------------------------------
  // Открыть новый аккаунт
  // $acctdomain - домен
  // $acctuser - логин для аккаунта
  // $acctpass - пароль для аккаунта
  // $acctplan - тарифный план
  // $accemail - контактный email аккаунта
  // $acccpmod - стиль cPanel по умолчанию
  // -------------------------------------------------------------
  function createacct ($acctdomain, $acctuser, $acctpass, $acctplan, $accemail,
           $acccpmod="bluelagoon") {
    if (!eregi("^[-a-z0-9\.]{4,}$",$acctdomain)) {
      $this->cpanelaccterr="Invalid domain name";
      return;
    }
    $acctplan=str_replace(" ","+",$acctplan);
    $accemail=str_replace("@","%40",$accemail);
    $result = $this->whmreq("/scripts/wwwacct?remote=1&nohtml=1&username=${acctuser}&password=${acctpass}&domain=${acctdomain}&plan=${acctplan}&contactemail=${accemail}&cpmod=${acccpmod}");
    if ($this->cpanelaccterr != "") { return; }
    return $result;
  }
 
  // -------------------------------------------------------------
  // Показать список имеющихся на сервере аккаунтов
  // -------------------------------------------------------------
  function listaccts () {
    $result = $this->whmreq("/scripts2/listaccts?nohtml=1&viewall=1");
    if ($this->cpanelaccterr != "") { return; }
 
    $page = split("\n",$result);
    foreach ($page as $line) {
      list($acct,$contents) = split("=", $line);
      if ($acct != "") {
        $allc = split(",", $contents);
        $accts[$acct] = $allc;
      }
    }
    return($accts);
  }
 
  // -------------------------------------------------------------
  // Показать список заведенных на сервере тарифных планов
  // -------------------------------------------------------------
  function listpkgs () {
    $result = $this->whmreq("/scripts/remote_listpkg");
    if ($this->cpanelaccterr != "") { return; }
 
    $page = split("\n",$result);
    foreach ($page as $line) {
      list($pkg,$contents) = split("=", $line);
      if ($pkg != "") {
        $allc = split(",", $contents);
        $pkgs[$pkg] = $allc;
      }
    }
    return($pkgs);
  }
 
  // -------------------------------------------------------------
  // Запрос к WHM/cPanel. Используется только для работы внутри
  // класса, извне вызываться не должен
  // -------------------------------------------------------------
  function whmreq ($request) {
    $cleanaccesshash = preg_replace("'(\r|\n)'","",$this->accesshash);
    $authstr = $this->user . ":" . $cleanaccesshash;
    $this->cpanelaccterr = "";
 
    if (function_exists("curl_init")) {
      $ch = curl_init();
      if ($this->usessl) {
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER,0);                
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST,0);
        curl_setopt($ch, CURLOPT_URL, "https://".$this->host.":2087" . $request);
      }
      else {
        curl_setopt($ch, CURLOPT_URL, "http://".$this->host.":2086" . $request);
      }
      curl_setopt($ch, CURLOPT_HEADER, 0);
      curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
      $curlheaders[0] = "Authorization: WHM $authstr";
      curl_setopt($ch,CURLOPT_HTTPHEADER,$curlheaders);
      $data=curl_exec ($ch);
      curl_close ($ch);
    }
    elseif (function_exists("socket_create")) {
      if ($this->usessl) {
        $this->cpanelaccterr = "SSL Support requires curl";
        return;
      }
      $service_port = 2086;
      $address = gethostbyname($this->host);
      $socket = socket_create (AF_INET, SOCK_STREAM, 0);
      if ($socket < 0) {
        $this->cpanelaccterr = "socket_create() failed";
        return;
      }
      $result = socket_connect ($socket, $address, $service_port);
      if ($result < 0) {
        $this->cpanelaccterr = "socket_connect() failed";
        return;
      }
      $in = "GET $request HTTP/1.0\n";
      socket_write($socket,$in,strlen($in));    
      $in = "Connection: close\n";
      socket_write($socket,$in,strlen($in));    
      $in = "Authorization: WHM $authstr\n\n\n";
      socket_write($socket,$in,strlen($in));    
 
      $inheader = 1;
      while(($buf = socket_read($socket, 512)) != false) {
        if (!$inheader) {
          $data .= $buf;
        }
        if (preg_match("'\r\n\r\n$'s", $buf)) {
          $inheader = 0;
        }
        if (preg_match("'\n\n$'s", $buf)) {
          $inheader = 0;
        }
        if (preg_match("'\r\n$'s", $buf)) {
          $inheader = 0;
        }
      }
    }
    else {
      $this->cpanelaccterr = "php not compiled with --enable-sockets OR curl";
      return;
    }
    return $data;    
  }
}
?>

Для работы с этими функциями требуется доступ с правами администратора, и только для chgpassword требуется рутовый доступ. PHP должен быть собран с модулем curl или enable-sockets. При наличии навыков класс можно легко расширять другими функциями, доступными через web-интерфейс WHM/cPanel.

Пример использования:
<?
// Подключение модуля
$cpanel=new cpanel_class;
// IP или имя сервера для подключения
$cpanel->host = '176.34.112.5';
// Логин (админский или рутовый)
$cpanel->user = 'manhunter';
// Хэш для SSL-авторизации. Он большой, тут целиком не привожу, потому что лениво
$cpanel->accesshash = '1123bf11a009821 .... 8772b99a55e99c9d';
// Не использовать SSL
$cpanel->usessl = 0;
 
// Создать новый аккаунт
$acctdomain="manhunter.ru";        // Домен для регистрация
$acctuser="manhunter";             // Аккаунт
$acctpass="gyQuletExygeJIWesASUV"; // Пароль для аккаунта
$acctplan="Basic500";              // Название тарифа из WHM
$accemail="manhunter@omen.ru";     // Адрес E-mail владельца аккаунта
$result=$cpanel->createacct($acctdomain, $acctuser, $acctpass, $acctplan,
                     $accemail, $acccpmod="bluelagoon");
if ($cpanel->cpanelaccterr!="") {
  echo "Ошибка: ".$cpanel->cpanelaccterr;
}
else {
  echo $result;
}
 
// Заблокировать аккаунт
$acctuser="manhunter";             // Аккаунт
$reason="Non payment";             // Причина блокировки
$result=$cpanel->suspend($acctuser,$reason);
if ($cpanel->cpanelaccterr!="") {
  echo "Ошибка: ".$cpanel->cpanelaccterr;
}
else {
  echo $result;
}
 
// Удалить аккаунт
$acctuser="manhunter";             // Аккаунт
$result=$cpanel->killacct($acctuser);
if ($cpanel->cpanelaccterr!="") {
  echo "Ошибка: ".$cpanel->cpanelaccterr;
}
else {
  echo $result;
}
?>

Параметр $reason в функции suspend официально не поддерживается и при обработке игнорируется. Несколько месяцев вместе с администраторами пытаемся достучаться до невменяемой техподдержки cPanel с просьбой о включении обработки этого параметра, но безрезультатно. Пока приходится вносить причину блокировки вручную. Надеюсь, что в будущем ситуация все-таки изменится к лучшему.
Теги:
API, WHM, cPanel
Добавлено: 22 Сентября 2013 12:19:48 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...