Blog. Just Blog

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

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Web-мастеру и не только | Автор: ManHunter
cPanel является одной из самых популярных коммерческих панелей управления аккаунтами на серверах виртуального хостинга. Все действия выполняются обычно через web-интерфейс, но для использования в ваших проектах авторами предоставляется API. К сожалению вообще никакой вменяемой документации разработчикам не предоставляется. Эту позорную отмазку на официальном сайте назвать технической документацией трудно, поэтому при разработке очередного проекта пришлось создавать собственный класс для работы с cPanel. Попутно удалось реализовать несколько недокументированных функций и расширить функционал уже имеющихся.
  1. <?
  2. // -------------------------------------------------------------
  3. // Класс для работы с WHM/cPanel через API
  4. // (C) ManHunter / PCL
  5. // http://www.manhunter.ru
  6. // -------------------------------------------------------------
  7. class cpanel_class {
  8.   var $cpanelaccterr;
  9.   var $host;
  10.   var $user;
  11.   var $accesshash;
  12.   var $usessl;
  13.  
  14.   // -------------------------------------------------------------
  15.   // Изменить пароль на аккаунте
  16.   // Для выполнения нужна авторизация только с рутовым доступом
  17.   // $chuser - аккаунт на сервере
  18.   // $password - новый пароль
  19.   // -------------------------------------------------------------
  20.   function chgpassword ($chuser$password) {
  21.     if ($this->user!="root") {
  22.       $this->cpanelaccterr="Root privileges required";
  23.       return;
  24.     }
  25.     $result $this->whmreq("/scripts/passwd?user=${chuser}&password=${password}&password2=${password}");
  26.     $result=eregi_replace("[\n]{1,}","\n",strip_tags($result));
  27.     if ($this->cpanelaccterr != "") { return; }
  28.     if (strpos($result,"could not be changed")!==false) {
  29.       $this->cpanelaccterr=$result;
  30.       return;
  31.     }
  32.     return $result;
  33.   }
  34.  
  35.   // -------------------------------------------------------------
  36.   // Заблокировать аккаунт
  37.   // $suspenduser - аккаунт на сервере
  38.   // $reason - причина блокировки, сделано на перспективу,
  39.   //           фактически параметр панелью игнорируется
  40.   // -------------------------------------------------------------
  41.   function suspend ($suspenduser$reason="") {
  42.     $reason=str_replace(" ","+",$reason);
  43.     $result $this->whmreq("/scripts/remote_suspend?user=${suspenduser}&reason=${reason}");
  44.     if ($this->cpanelaccterr != "") { return; }
  45.     if (strpos($result,"Access Denied")!==false) {
  46.       $this->cpanelaccterr=$result;
  47.       return;
  48.     }
  49.     return $result;
  50.   }
  51.  
  52.   // -------------------------------------------------------------
  53.   // Разблокировать аккаунт
  54.   // $unsuspenduser - аккаунт на сервере
  55.   // -------------------------------------------------------------
  56.   function unsuspend ($unsuspenduser) {
  57.     $result $this->whmreq("/scripts/remote_unsuspend?user=${unsuspenduser}");
  58.     if ($this->cpanelaccterr != "") { return; }
  59.     if (strpos($result,"Access Denied")!==false) {
  60.       $this->cpanelaccterr=$result;
  61.       return;
  62.     }
  63.     return $result;
  64.   }
  65.  
  66.   // -------------------------------------------------------------
  67.   // Удалить аккаунт
  68.   // $killuser - аккаунт на сервере
  69.   // -------------------------------------------------------------
  70.   function killacct ($killuser) {
  71.     $result $this->whmreq("/scripts/killacct?user=${killuser}&nohtml=1");
  72.     if ($this->cpanelaccterr != "") { return; }
  73.     return $result;
  74.   }
  75.  
  76.   // -------------------------------------------------------------
  77.   // Показать версию WHM/cPanel
  78.   // -------------------------------------------------------------
  79.   function showversion () {
  80.     $result $this->whmreq("/scripts2/showversion");
  81.     if ($this->cpanelaccterr != "") { return; }
  82.     return $result;
  83.   }
  84.  
  85.   // -------------------------------------------------------------
  86.   // Перевести аккаунт на новый тарифный план
  87.   // $upuser - аккаунт на сервере
  88.   // $acctplan - новый тарифный план
  89.   // -------------------------------------------------------------
  90.   function update ($upuser$acctplan) {
  91.     $acctplan=str_replace(" ","+",$acctplan);
  92.     $result $this->whmreq("/scripts2/upacct?user=${upuser}&pkg=${acctplan}");
  93.     if ($this->cpanelaccterr != "") { return; }
  94.     return $result;
  95.   }
  96.  
  97.   // -------------------------------------------------------------
  98.   // Открыть новый аккаунт
  99.   // $acctdomain - домен
  100.   // $acctuser - логин для аккаунта
  101.   // $acctpass - пароль для аккаунта
  102.   // $acctplan - тарифный план
  103.   // $accemail - контактный email аккаунта
  104.   // $acccpmod - стиль cPanel по умолчанию
  105.   // -------------------------------------------------------------
  106.   function createacct ($acctdomain$acctuser$acctpass$acctplan$accemail,
  107.            $acccpmod="bluelagoon") {
  108.     if (!eregi("^[-a-z0-9\.]{4,}$",$acctdomain)) {
  109.       $this->cpanelaccterr="Invalid domain name";
  110.       return;
  111.     }
  112.     $acctplan=str_replace(" ","+",$acctplan);
  113.     $accemail=str_replace("@","%40",$accemail);
  114.     $result $this->whmreq("/scripts/wwwacct?remote=1&nohtml=1&username=${acctuser}&password=${acctpass}&domain=${acctdomain}&plan=${acctplan}&contactemail=${accemail}&cpmod=${acccpmod}");
  115.     if ($this->cpanelaccterr != "") { return; }
  116.     return $result;
  117.   }
  118.  
  119.   // -------------------------------------------------------------
  120.   // Показать список имеющихся на сервере аккаунтов
  121.   // -------------------------------------------------------------
  122.   function listaccts () {
  123.     $result $this->whmreq("/scripts2/listaccts?nohtml=1&viewall=1");
  124.     if ($this->cpanelaccterr != "") { return; }
  125.  
  126.     $page split("\n",$result);
  127.     foreach ($page as $line) {
  128.       list($acct,$contents) = split("="$line);
  129.       if ($acct != "") {
  130.         $allc split(","$contents);
  131.         $accts[$acct] = $allc;
  132.       }
  133.     }
  134.     return($accts);
  135.   }
  136.  
  137.   // -------------------------------------------------------------
  138.   // Показать список заведенных на сервере тарифных планов
  139.   // -------------------------------------------------------------
  140.   function listpkgs () {
  141.     $result $this->whmreq("/scripts/remote_listpkg");
  142.     if ($this->cpanelaccterr != "") { return; }
  143.  
  144.     $page split("\n",$result);
  145.     foreach ($page as $line) {
  146.       list($pkg,$contents) = split("="$line);
  147.       if ($pkg != "") {
  148.         $allc split(","$contents);
  149.         $pkgs[$pkg] = $allc;
  150.       }
  151.     }
  152.     return($pkgs);
  153.   }
  154.  
  155.   // -------------------------------------------------------------
  156.   // Запрос к WHM/cPanel. Используется только для работы внутри
  157.   // класса, извне вызываться не должен
  158.   // -------------------------------------------------------------
  159.   function whmreq ($request) {
  160.     $cleanaccesshash preg_replace("'(\r|\n)'","",$this->accesshash);
  161.     $authstr $this->user ":" $cleanaccesshash;
  162.     $this->cpanelaccterr "";
  163.  
  164.     if (function_exists("curl_init")) {
  165.       $ch curl_init();
  166.       if ($this->usessl) {
  167.         curl_setopt($chCURLOPT_SSL_VERIFYPEER,0);                
  168.         curl_setopt($chCURLOPT_SSL_VERIFYHOST,0);
  169.         curl_setopt($chCURLOPT_URL"https://".$this->host.":2087" $request);
  170.       }
  171.       else {
  172.         curl_setopt($chCURLOPT_URL"http://".$this->host.":2086" $request);
  173.       }
  174.       curl_setopt($chCURLOPT_HEADER0);
  175.       curl_setopt($chCURLOPT_RETURNTRANSFER,1);
  176.       $curlheaders[0] = "Authorization: WHM $authstr";
  177.       curl_setopt($ch,CURLOPT_HTTPHEADER,$curlheaders);
  178.       $data=curl_exec ($ch);
  179.       curl_close ($ch);
  180.     }
  181.     elseif (function_exists("socket_create")) {
  182.       if ($this->usessl) {
  183.         $this->cpanelaccterr "SSL Support requires curl";
  184.         return;
  185.       }
  186.       $service_port 2086;
  187.       $address gethostbyname($this->host);
  188.       $socket socket_create (AF_INETSOCK_STREAM0);
  189.       if ($socket 0) {
  190.         $this->cpanelaccterr "socket_create() failed";
  191.         return;
  192.       }
  193.       $result socket_connect ($socket$address$service_port);
  194.       if ($result 0) {
  195.         $this->cpanelaccterr "socket_connect() failed";
  196.         return;
  197.       }
  198.       $in "GET $request HTTP/1.0\n";
  199.       socket_write($socket,$in,strlen($in));    
  200.       $in "Connection: close\n";
  201.       socket_write($socket,$in,strlen($in));    
  202.       $in "Authorization: WHM $authstr\n\n\n";
  203.       socket_write($socket,$in,strlen($in));    
  204.  
  205.       $inheader 1;
  206.       while(($buf socket_read($socket512)) != false) {
  207.         if (!$inheader) {
  208.           $data .= $buf;
  209.         }
  210.         if (preg_match("'\r\n\r\n$'s"$buf)) {
  211.           $inheader 0;
  212.         }
  213.         if (preg_match("'\n\n$'s"$buf)) {
  214.           $inheader 0;
  215.         }
  216.         if (preg_match("'\r\n$'s"$buf)) {
  217.           $inheader 0;
  218.         }
  219.       }
  220.     }
  221.     else {
  222.       $this->cpanelaccterr "php not compiled with --enable-sockets OR curl";
  223.       return;
  224.     }
  225.     return $data;    
  226.   }
  227. }
  228. ?>
Для работы с этими функциями требуется доступ с правами администратора, и только для chgpassword требуется рутовый доступ. PHP должен быть собран с модулем curl или enable-sockets. При наличии навыков класс можно легко расширять другими функциями, доступными через web-интерфейс WHM/cPanel.

Пример использования:
  1. <?
  2. // Подключение модуля
  3. $cpanel=new cpanel_class;
  4. // IP или имя сервера для подключения
  5. $cpanel->host '176.34.112.5';
  6. // Логин (админский или рутовый)
  7. $cpanel->user 'manhunter';
  8. // Хэш для SSL-авторизации. Он большой, тут целиком не привожу, потому что лениво
  9. $cpanel->accesshash '1123bf11a009821 .... 8772b99a55e99c9d';
  10. // Не использовать SSL
  11. $cpanel->usessl 0;
  12.  
  13. // Создать новый аккаунт
  14. $acctdomain="manhunter.ru";        // Домен для регистрация
  15. $acctuser="manhunter";             // Аккаунт
  16. $acctpass="gyQuletExygeJIWesASUV"// Пароль для аккаунта
  17. $acctplan="Basic500";              // Название тарифа из WHM
  18. $accemail="manhunter@omen.ru";     // Адрес E-mail владельца аккаунта
  19. $result=$cpanel->createacct($acctdomain$acctuser$acctpass$acctplan,
  20.                      $accemail$acccpmod="bluelagoon");
  21. if ($cpanel->cpanelaccterr!="") {
  22.   echo "Ошибка: ".$cpanel->cpanelaccterr;
  23. }
  24. else {
  25.   echo $result;
  26. }
  27.  
  28. // Заблокировать аккаунт
  29. $acctuser="manhunter";             // Аккаунт
  30. $reason="Non payment";             // Причина блокировки
  31. $result=$cpanel->suspend($acctuser,$reason);
  32. if ($cpanel->cpanelaccterr!="") {
  33.   echo "Ошибка: ".$cpanel->cpanelaccterr;
  34. }
  35. else {
  36.   echo $result;
  37. }
  38.  
  39. // Удалить аккаунт
  40. $acctuser="manhunter";             // Аккаунт
  41. $result=$cpanel->killacct($acctuser);
  42. if ($cpanel->cpanelaccterr!="") {
  43.   echo "Ошибка: ".$cpanel->cpanelaccterr;
  44. }
  45. else {
  46.   echo $result;
  47. }
  48. ?>
Параметр $reason в функции suspend официально не поддерживается и при обработке игнорируется. Несколько месяцев вместе с администраторами пытаемся достучаться до невменяемой техподдержки cPanel с просьбой о включении обработки этого параметра, но безрезультатно. Пока приходится вносить причину блокировки вручную. Надеюсь, что в будущем ситуация все-таки изменится к лучшему.

Поделиться ссылкой ВКонтакте
Просмотров: 7856 | Комментариев: 9

Метки: PHP, серверы
Внимание! Статья опубликована больше года назад, информация могла устареть!

Комментарии

Отзывы посетителей сайта о статье
Vanek (17.05.2018 в 12:13):
Огромное спасибо ;)
infor_searcher (19.11.2013 в 03:24):
Понятно. Спасибо.
ManHunter (18.11.2013 в 20:20):
Тогда деньги в кассу и готовь заказ тем, кто силен. Я этим точно заниматься не буду, от хостинг-провайдера я уже давно ушел и никакого интереса не испытываю.
infor_searcher (18.11.2013 в 19:01):
Огромное спасибо.
Но это понятно. Я бы хотел найти более понятные варианты.
Тем более что не очень силён во всём этом.
ManHunter (18.11.2013 в 08:39):
Если у них на сайте еще не появилось, то нигде.
http://docs.cpanel.net/twiki/b...tion/WebHome
infor_searcher (18.11.2013 в 03:49):
Добрый день.
Хотел узнать, есть желание использовать cPanel dns
Как и где можно почитать про API под это дело?
ManHunter (14.10.2010 в 16:01):
Ага, спасибо, поправил.
Andrey (14.10.2010 в 15:58):
Во втором листинге вместо $this->cpanelaccterr нужно использовать $cpanel->cpanelaccterr
Ivan (26.10.2009 в 11:55):
Спасибо за статью. Как раз пишу простенький билинг под WHM. Информация очень пригодилась.

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2025
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.07 сек. / MySQL: 2 (0.0088 сек.) / Память: 4.5 Mb
Наверх