Перейти до вмісту

Блог ·

Як продавати вебхостинг із Plesk

Перетворення сервера Plesk на продукт хостингу: один ключ на два API, пастка призупинення, що ховає обліковий запис від опитування, і чого ми не просимо.

Автор: Provibr

Plesk без проблем вестиме для вас сотню підписок. Чого він не зробить, так це прийняти замовлення, зібрати гроші, помітити, що рахунок лишився несплаченим, або призупинити відповідний обліковий запис. Саме в цьому розриві між «панеллю, яка хостить сайти» і «бізнесом на хостингу» лежить робота, і ця сторінка розповідає про те, як подолати його, не ступивши в жодне з чотирьох місць, у які легко ступити.

Що Plesk уже вам дає

Підписка є одиницею, яку ви продаєте: головний домен, сервісний план, ліміти диска й трафіку та все, що під ними. Сервісний план є власним описом цього пакета в панелі: квота, місячний трафік, скільки доменів і поштових скриньок, які служби ввімкнено. Обидва поняття вже існують, тож ви не винаходите модель продукту, а лише називаєте ту, що вже є.

API добрий в одному сенсі, що особливо важливий для продукту хостингу: один виклик зчитує кожну підписку на сервері, з її планом, статусом, квотою та використанням. Ми виміряли це на рівні 0,33 секунди незалежно від їхньої кількості. Три виклики зчитування дають повну картину сервера (підписки, клієнти, плани), і це число не зростає з кількістю ваших клієнтів. Побудувати ту саму картину через REST потребувало б одного виклику плюс три на кожну підписку.

Один ключ відкриває два API, і вам потрібні обидва

У Plesk є сучасний REST v2 API і старіший XML/RPC API. Жоден із них не є повним сам по собі, і це не питання вподобань.

REST v2 не має ні підписок, ні сервісних планів. Ми перелічили його 43 шляхи з його ж документа OpenAPI; /subscriptions і /service-plans серед них немає, а запит до них повертає 404, відображений як HTML-сторінка, а не JSON. Оскільки сервісний план і є пакетом хостингу, увесь бік пакетів має працювати через XML.

Що рятує становище, так це облікові дані. Ключ, виданий POST /api/v2/auth/keys, працює без змін в обох: як X-API-Key у REST і як KEY на XML-кінцевій точці. Виміряно, той самий ключ, обидва API. Тож в оператора ви просите одне значення, а не два.

Коштує це вам двох словників помилок. REST відповідає на непридатний ключ HTTP 401 і цілком порожнім тілом. XML відповідає на той самий ключ HTTP 200 і кодом помилки всередині документа. Що й підводить нас до гострого краю.

Помилка автентифікації, що має вигляд порожнього сервера

Оскільки XML API повертає HTTP 200 для хибного ключа, клієнт, який перевіряє код статусу, читає помилку автентифікації як успішний обхід, що нічого не знайшов. А успішний обхід, що нічого не знайшов, має значення на будь-якій платформі хостингу: кожен обліковий запис, що був тут учора, зник.

Наслідком є не зламана панель приладів. Це система, яка позначає кожного вашого клієнта як видаленого через те, що ключ протермінувався. Правило, яке з цього випливає, абсолютне: на XML API код статусу не несе жодної інформації взагалі, навіть про автентифікацію. Розбирайте документ і трактуйте нечитабельну відповідь як невідому, а не як порожню.

Порожній сервер теж не видає помилки: він видає єдиний порожній результат, що є правильною відповіддю, коли їх справді немає. Відрізнити ці два випадки і є вся робота.

Пастка призупинення: записувати й читати те саме поле

Призупинити підписку в Plesk можна двома способами, і вони записують не те саме поле.

Що ви робитеXML gen_info.statusСтатус підписки в REST
нічого (активна)0active
PUT /domains/{id}/status на suspended0suspended
CLI subscription --webspace-off1suspended
XML <webspace><set> зі статусом 1616suspended

Перечитайте другий рядок. Призупинення через REST лишає нулем те поле, яке читає групове опитування. Тож продукт хостингу, який призупиняє через REST, а опитує через XML, показуватиме обліковий запис як активний, тоді як насправді він призупинений. Ніщо не дає помилки. Ніщо не червоніє. Ваша панель і ваш сервер просто розходяться, і першим, хто це помічає, стає клієнт, який не може дістатися сайту, що ви вважаєте працюючим.

Правило: призупиняйте й відновлюйте через те саме поле, яке ви читаєте. Provibr використовує XML <webspace><set><gen_setup><status>, і після цього обидва подання рухаються разом: XML-поле повідомляє 16, а REST повідомляє suspended.

gen_info.status є бітовою маскою, а значення, які ми виміряли, це 0 для активної, 1 для webspace-off і 16 для вимкненої адміністратором. Усе, що не є нулем, вважається призупиненим, і це єдине прочитання, яке переживе значення, якого ми ще не бачили.

Два набори даних, яких ми ніколи не просимо в панелі

XML API Plesk створений для адміністрування, тож два його набори даних повертають облікові дані тому, хто їх запитує:

  • <webspace><get> з набором даних hosting повертає FTP-пароль облікового запису у відкритому вигляді, із полем, що явно позначає його як відкритий.
  • <customer><get> з набором даних gen_info повертає хеш пароля клієнта (bcrypt) разом із типом хешу.

Для адміністративного API це розумно. Але це не те, що платформа хостингу мала б регулярно тягнути мережею за розкладом.

Шар приховування є хибною відповіддю на це. Правильна відповідь полягає в тому, щоб не питати. Опитування Provibr запитує рівно чотири набори даних (загальну інформацію, ліміти, статистику та підписки), і ми пройшли їх поле за полем, щоб пересвідчитися, що жоден не несе секрету. Список клієнтів надходить із REST, у якому взагалі немає поля пароля.

Є проєктний наслідок, який варто назвати. FTP- або системний користувач підписки був би привабливим коротким ідентифікатором, але він живе лише в наборі даних hosting, тож використання його як особи означало б завантаження пароля кожного клієнта на кожному циклі опитування. Звідси й домен натомість.

Ідентифікатором підписки є доменне імʼя

У Plesk підписка називається за своїм головним доменом. Саме це показує панель, за цим фільтрує її API, і саме це має зберігати будь-яка інтеграція.

Це справжня відмінність від cPanel і DirectAdmin, де обліковий запис має окремо короткий логін і домен, і вона має один практичний наслідок: домен згодом не можна змінити. Хоч би що ваша система білінгу зберігала як ідентифікатор підписки Plesk, це доменне імʼя, і клієнт, який хоче перейменувати свій сайт, просить нову підписку, а не редагування.

Дві менші речі, виміряні дорогою. Власна специфікація Plesk каже, що пароль клієнта має бути від 5 до 14 символів; пароль із 22 символів було прийнято без нарікань, тож задокументований ліміт не є тим, що застосовується. А IP-адресу Plesk обирає сам зі свого пулу, тому обліковий запис хостингу в Provibr має порожнє поле адреси, доки панель не повідомить її.

Невдале замовлення може лишити по собі половину підписки

Виміряно: створення домену із сервісним планом, якого не існує, відповідає HTTP 404 із чітким повідомленням, і обʼєкт домену все одно існує після цього, без типу хостингу та з порожнім кореневим каталогом документів. Plesk спочатку створює обʼєкт, а тоді застосовує план, і нічого не відкочує, коли другий крок зазнає невдачі.

Клієнт заплатив, замовлення провалилося, і наступна спроба тепер провалюється інакше, бо домен уже зайнято обліковим записом, якого він так і не отримав. Тож шукайте план перед тим, як щось створювати, у списку планів, який ви вже завантажили, і прибирайте після будь-якого невдалого створення. Для контрасту: помилка перевірки поля, як-от дубльований логін, повертається як HTTP 400 і не лишає нічого по собі: ця перевірка виконується до створення, і лише пошук плану відбувається запізно.

Жодної затримки, що трапляється рідше, ніж мало б

Перелік використання в DirectAdmin відстає від реальності приблизно на три секунди в обох напрямках, що змушує робити другий авторитетний виклик. Plesk так не робить. Ми виміряли створення й видалення проти групового зчитування:

text
    0 ms  create
 4519 ms  create returns 201
 4957 ms  bulk read sees the subscription      <- immediately
 4957 ms  delete
12622 ms  delete returns 200
13001 ms  bulk read no longer sees it          <- immediately

Plesk транзакційний: щойно виклик відповідає, зміна вже видима в груповому зчитуванні. Одне авторитетне джерело, жодного другого виклику, жодного очікування.

Самі значення часу варто відзначити. Створення підписки триває 4,1 до 4,5 секунди, а видалення триває 7,7 секунди: достатньо довго, щоб клієнту, який дивиться на форму замовлення, треба було сказати, що щось відбувається. Зміна плану триває 1,5 секунди, а призупинення 0,78 секунди.

Що Provibr робить з усім цим

Provibr стоїть між вашим білінгом і вашим сервером Plesk. Ви підключаєте сервер одним ключем API, і після цього підписка є звичайним рядком: замовити її, призупинити, відновити, перевести на інший сервісний план, видалити.

  • Один ключ, бо той самий ключ відкриває обидва API.
  • Призупинення проходить через поле, яке читає опитування, тож панель і сервер не можуть розійтися.
  • Опитування ніколи не запитує набір даних, що містить пароль, тож жоден секрет клієнта не потрапляє на платформу.
  • План визначається до створення, а невдале створення прибирається, а не лишається по собі.
  • Нічому не вірять на слово. Кожна зміна завершується повторним зчитуванням підписки.
  • Агент встановлює вихідне зʼєднання з вашої мережі, тож порт 8443 не дивиться в інтернет, і на сервер Plesk нічого не встановлюється.
  • Підписки, які ви не замовляли через Provibr, лишаються недоторканими, доки ви їх не імпортуєте, що робить сервер із двомастами наявними клієнтами придатним до перейняття, а не до перебудови.

Чого воно не робить

Воно керує підписками на сервері Plesk, який ви експлуатуєте, а не самим сервером: служби, DNS-зони, маршрутизація пошти й власні налаштування панелі лишаються на місці. Консолі немає, бо обліковий запис хостингу не є машиною. Поштові скриньки, бази даних і DNS усередині підписки належать Plesk і вашому клієнту.

Одна чесна прогалина: усе тут вимірювалося з ключем адміністратора. Чи може ключ, обмежений реселером або клієнтом, узагалі користуватися XML API, не перевірено, тож інтеграція зондує під час підключення й відмовляє в облікових даних, які здатні бачити лише частину панелі, замість того щоб тихо керувати її половиною.

Читайте далі

Виміряно на Plesk Obsidian 18.0.80 у серпні 2026 року, з усіма відповідями, записаними як фікстури. Поведінку з ключем, обмеженим реселером, з більш ніж однією підпискою на клієнта та під реальним навантаженням трафіку не вимірювали, про що зазначено вище.

Читати далі

Почніть з одного хоста й одного агента

Створіть обліковий запис, встановіть агента однією командою та підключіть свій перший хост Proxmox. Пробний період триває 14 днів і не потребує платіжних даних.