ПафНутиЙ-Блог » Статьи » Как защитить свой php-скрипт и привязать его к домену на примере модуля для DLE

Как защитить свой php-скрипт и привязать его к домену на примере модуля для DLE

13.02
77
28319
Как защитить свой php-скрипт и привязать его к домену на примере модуля для DLE


Ни для кого не секрет, что вопрос защиты своего php-скрипта рано или поздно встаёт перед любым разработчиком и сегодня я покажу как просто и эффективно защитить свой скрипт на практическом примере - на простеньком модуле для DLE.

Как то давно я навскидку написал простой модуль вывода информации об аттачменте в любом месте сайта - ShowAttach, но до ума модуль не довёл и публиковать его не стал. Вот этот модуль и возьмём за основу для защиты.
Так же нам понадобятся прямые руки и система PCP-CS от Олега Mofsy.

Что такое pcp-cs


PCP-CS — PHP Code Protect Client-Server. Другими словами клиент-серверное приложение для привязки скриптов к определенным ограничениям (домен, ip сервера и т.д.).

Как работает?


Очень упрощенная схема выглядит так:
Как защитить свой php-скрипт и привязать его к домену на примере модуля для DLE


Ключевые преимущества


  • Лёгкая интеграция в нужный скрипт. Достаточно вставить код клиента в скрипт и прописать необходимые параметры
  • Встроенная админка для управления серверной частью. Система имеет встроенную административную часть для управления лицензиями, просмотра логов и т.п.
  • Продуманная реализация проверок. Проверки лицензии осуществляются сначала из локального ключа, и если период проверки истёк - данные запрашиваются с сервера проверки, и если сервер проверки недоступен - защищаемый скрипт не перестанет функционировать в течении заданного периода времени.


Установка и настройка серверной части PCP-CS


Т.к. на момент написания статьи встроенная админка системы не достаточно функциональна, я буду использовать стороннюю админку, написанную специально для этой системы.
Настройку можно производить как на хостинге, так и на локальной машине. Для локалки рекомендую OpenServer.

  1. Скачиваем с гитхаба админку по кнопке "Download ZIP". Она уже содержит последнюю версию серверной части pcp-cs, так что на данном этапе больше ничего не потребуется.
  2. Распаковываем папку upload в корень.
  3. Выполняем запрос из sql.sql. Если необходимо сразу завести пользователя, то выполняем запрос:
    INSERT INTO `pcp_users` (`user_id`, `email`, `password`, `name`, `user_group`) VALUES (1, 'admin@admin.ru', 'c3284d0f94606de1fd2af172aba15bf3', 'admin', 1);
    логин и пароль в этом случаи будут admin, admin
  4. Настраиваем конфиг в трёх файлах:
    admin/config/db_config.php - Конфиг БД
    admin/config/config.php - Конфиг админки
    api/config.php - Конфиг pcp-cs
    Такое разделение обусловлено независимостью админки от серверной части pcp-cs.
  5. Всё! Адинка готова к работе. Можно приступать к защите подопытного модуля.
    Как защитить свой php-скрипт и привязать его к домену на примере модуля для DLE



Внедрение клиентской части


Прежде всего необходимо настроить серверную часть.
Для этого создаём новый метод проверки данных.
Как защитить свой php-скрипт и привязать его к домену на примере модуля для DLE

Как защитить свой php-скрипт и привязать его к домену на примере модуля для DLE


после успешного создания метода идём в раздел "Лицензии" и добавляе новый лицензионный ключ.
Как защитить свой php-скрипт и привязать его к домену на примере модуля для DLE

Как защитить свой php-скрипт и привязать его к домену на примере модуля для DLE


В результате получаем лицезионный ключ, который в дальнейшем можно отдавать покупателю модуля.

Вот теперь можно внедрять непосредственно код клиента!

Сейчас наш подопытный образец модуля (кстати не рекомендую его использовать на живых проетах т.к. он не доработан как следует и будет вызывать повышение нагрузки на бд) выглядит так:


Вот такой внешний вид вывода данных этим модулем:
Как защитить свой php-скрипт и привязать его к домену на примере модуля для DLE


Нам необходимо заблокировать работу скрипта, если он используется без лицензии.

Для начала добавим в конфиг модуля параметр key, в который будем передавать полученный лицензионный ключ.
'key' => !empty($key) ? $key : false,

и завернём рабочий код в условие с проверкой этого параметра, а так же добавим отдельное условие для вывода сообщения об отсутствии ключа.
// Если есть ключ и задан ID новости — работаем
if ($cfg['newsId'] && $key) {
......
} elseif (!$key) {
$showAttach = '<span style="color: red;">Не указан лицензионный ключ.</span>';
}
echo $showAttach;

результат:
Как защитить свой php-скрипт и привязать его к домену на примере модуля для DLE


Добавляем в строку подключения ключ и проверяем:
Как защитить свой php-скрипт и привязать его к домену на примере модуля для DLE


Теперь нужно добавить проверку введённого ключа с помощью pcp-cs.
  1. Внедряем код клиента в наш модуль. Для экономии ресурсов рекомендую сжать код клиентского класса через любой удобный инструмент. Я использовал сервис PHP-Minifier. Вставляем полученный код перед основным кодом модуля. Если при проверке выдаёт ошибку:
    Fatal error: Namespace declaration statement has to be the very first statement in the script in

    просто удалите этот код:
    namespace MofsyLicenseClient;

  2. Сразу после кода клиентского класса можно его задействовать и произвести проверку.
    В комментарияк к коду ниже я расписал что и как происходит.
    // Теперь можно запустить проверку лицензии
    $protect = new Protect();

    // Секретный ключ из созданного метода проверки
    $protect->secret_key = 'mqgAqWnSwZZM8YX7BEd9';

    // Куда будем класть локальный (зашифрованный) ключ?
    $protect->local_key_path = ENGINE_DIR . '/data/';

    // Имя и расширение локального ключа
    $protect->local_key_name = 'showattach.lic';

    // Адрес сервера проверки
    $protect->server = 'http://pcp-cs.loc/api.php';

    // Дата релиза модуля (пригодится если лицензия даётся на определённую версию модуля)
    $protect->release_date = '2015-02-10';

    // Ключ активации (лицензионный ключ), тот, который передаётся в параметрах строки подключения модуля
    $protect->activation_key = $key;

    // Сообщения о различных ошибках
    $protect->status_messages = array(
    'status_1' => '<span style="color:green;">Активна</span>',
    'status_2' => '<span style="color:darkblue;">Внимание</span>: срок действия лицензии закончился.',
    'status_3' => '<span style="color:orange;">Внимание</span>: лицензия переиздана. Ожидает повторной активации.',
    'status_4' => '<span style="color:red;">Ошибка</span>: лицензия была приостановлена.',
    'localhost' => '<span style="color:orange;">Активна на localhost</span>: используется локальный компьютер, на реальном сервере произойдет активация, если вы правильно ввели лицензионный ключ активации в настройках.',
    'pending' => '<span style="color:red;">Ошибка</span>: лицензия ожидает рассмотрения.',
    'download_access_expired' => '<span style="color:red;">Ошибка</span>: ключ активации не подходит для установленной версии. Пожалуйста поставьте более старую версию продукта.',
    'missing_activation_key' => '<span style="color:red;">Ошибка</span>: ключ активации не указан.',
    'could_not_obtain_local_key' => '<span style="color:red;">Ошибка</span>: невозможно получить новый локальный ключ.',
    'maximum_delay_period_expired' => '<span style="color:red;">Ошибка</span>: льготный период локального ключа истек.',
    'local_key_tampering' => '<span style="color:red;">Ошибка</span>: локальный лицензионный ключ поврежден или не действителен.',
    'local_key_invalid_for_location' => '<span style="color:red;">Ошибка</span>: локальный ключ не подходит к данному окружению.',
    'missing_license_file' => '<span style="color:red;">Ошибка</span>: создайте следующий пустой файл и папки если их нету:<br />',
    'license_file_not_writable' => '<span style="color:red;">Ошибка</span>: сделайте для записи следующие пути:<br />',
    'invalid_local_key_storage' => '<span style="color:red;">Ошибка</span>: не возможно удалить старый локальный ключ.',
    'could_not_save_local_key' => '<span style="color:red;">Ошибка</span>: не возможно записать новый локальный ключ.',
    'activation_key_string_mismatch' => '<span style="color:red;">Ошибка</span>: локальный ключ не действителен для указанного ключа активации.'

    );

    // Запускаем валидацию лицензии
    $protect->validate();

    $license = false;

    // Если истина, то лицензия в боевом состоянии и можно работать дальше.
    if($protect->status) {
    $license = true;
    }


    Немного доработок в условиях:
    // Если есть ключ и задан ID новости и проверка лицензии прошла успешно — работаем
    if ($cfg['newsId'] && $key && $license) {
    ....
    }
    if (!$key) {
    // Если ключ не передан — надо бы сообщить об этом
    $showAttach = '<span style="color: red;">Не указан лицензионный ключ.</span>';
    }
    if (!$license) {
    // Если лицензия не проверилась - скжем об этом
    $showAttach = (!$protect->errors) ? 'Ошибка лицензии.' : $protect->errors;
    }

    echo $showAttach;


    Если всё сделано правильно — файл с лицензией будет успешно создан в нужной папке, скрипт будет работать., а в админке PCP-CS появится запись о том, где активирован ключ.
    Как защитить свой php-скрипт и привязать его к домену на примере модуля для DLE

    Как защитить свой php-скрипт и привязать его к домену на примере модуля для DLE


    Для проверки попробуйте изменить данные лицензионного ключа в строке подключения.


Вот, собственно, и вся процедура реализации защиты модуля. Остаётся только закодировать код модуля в IonCube и можно продавать или раздавать бесплатно.
Так же не забывайте, что лучше всего реализовать в модуле возможность кеширования и проверять лицензию при отсутствии кеша модуля, так экономятся ресурсы хостинга и ускоряется работа.
После всех действий код модуля должен выглядеть как то так:


В качестве дополнения


Код pcp-cs очень хорошо прокомментирован и для реализации различных вариантов проверки достаточно почитать что там написано. К примеру для использования модуля на локалке без активации достаточно прописать параметр:
$protect->use_localhost = true;

Ну и конечно же если у вас есть идеи и пожелания - мы с Олегом будем всегда рады видеть эти пожелания на гитхабе

Похожие материалы

  • Пишем свой модуль для DLE - подробная инструкция
  • Увеличение скорости загрузки сайта на DLE (часть 2)
  • {AJAX FULL-STORY} — модуль AJAX-загрузки полной новости для DLE
  • UniForm — модуль универсальных ajax-форм для DataLife Engine
Закрыть

Комментировать могут только зарегистрированные пользователи

+

Комментарии

b-en-der
b-en-der 14 февраля 2015 21:03
Ответов: 0 #4635
Павел, огромное спасибо за этот пост и за ваши труды, молодцы! smile
Kamikadze4GAME
Kamikadze4GAME 18 февраля 2015 02:15
Ответов: 1 #4643
Я дико извиняюсь, но мне нужна помощь.
Как добавить новый редактор текста в dle, но чтобы там вообще не было панели управления. Просто текстовое поле. И как его добавить, а не заменить уже имеющееся.
Заранее спасибо.
Еще раз извините, что не по теме. Если получу жалобы - пойму.
ПафНутиЙ
ПафНутиЙ 18 февраля 2015 09:03
Ответов: 0 #4646
Ioncube
Ioncube 8 марта 2015 15:57
Ответов: 1 #4678
Интересует пару вопросов.
1. Я так понимаю, такая реализация давно гуляет по инету? Вы просто взяли и немного напильником доработали?
2. Почему реализовали лицензию как отдельный файл? Почему не сделать в конфиг модуля?
3. Можно ли как-то автоматизировать получение лицензионного ключа пользователю? Чтобы, не я каждый раз выдавали его, а пользователь сам, зашел где размещен pcp-cs, ввел домен и получил ключ, потом зашел в админку прописал и всё.
ПафНутиЙ
ПафНутиЙ 8 марта 2015 22:25
Ответов: 0 #4680
1. Принципы защиты придуманы давно. Однако мы не брали за основу ничего гуляющего по интернету, Олег писал с нуля, под свои нужды, а потом уже дорабатывал для масс.
2. Потому, что проверка лицензии может проходить в нескольких файлах держать код лицензии переменной нет смысла, к том же он там должен храниться определённое время, а е постоянно.
3. Можно, если вы сможете описать универсальный алгоритм для любого варианта внедрения, или хотябы в DLE - мы обязательно это реализуем. Ну а пока вы можете сделать функционал получения лицензии в автоматическом режиме самостоятельно, од свой проект (именно так я и сделал для себя).
locksmith
locksmith 5 мая 2015 16:47
Ответов: 5 #4758
Я вот не пойму, а разве сам ioncube не имеет инструментов лицензиования?
ПафНутиЙ
ПафНутиЙ 5 мая 2015 17:08
Ответов: 4 #4759
А разве имеет?
locksmith
locksmith 5 мая 2015 17:12
Ответов: 3 #4760
Вроде умеет. IonCube Encoder — набор бинарных файлов для разных ОС, при помощи которых можно кодировать исходный код, производить его обфускацию и генерировать лицензии. На оф сайте тоже есть. Только он платный. А pcp-cs полностью бесплатен?
ПафНутиЙ
ПафНутиЙ 5 мая 2015 17:22
Ответов: 2 #4761
ioncube с такими возможностями начинается от 300 зелёных. PCP-CS бесплатен.
Надо кстати туда воткнуть будет mit лицензию для точности.
locksmith
locksmith 5 мая 2015 18:13
Ответов: 1 #4762
Чем тогда бесплатно закодировать код не подскажите?
ПафНутиЙ
ПафНутиЙ 5 мая 2015 19:03
Ответов: 0 #4763
Тут не подскажу т.к. хотя бы приблизительно близкое к ioncube качество не обработки знаю.
Например закодированный init.php в DLE последних версий раскодируется на 5 минут, включая скачивание и распаковку архива с офсайта.
locksmith
locksmith 8 мая 2015 05:51
Ответов: 1 #4767
Можно ли сделать один ключ на всех до определенного периода для демонстрации модуля?
ПафНутиЙ
ПафНутиЙ 9 мая 2015 00:19
Ответов: 0 #4768
Думаю да, просто не привязывать к домену.
locksmith
locksmith 9 мая 2015 14:53
Ответов: 0 #4769
У меня выдало ошибку при активации ключа (локально) а сервер PCP стоит внешний вот такую:
Ошибка: локальный ключ не подходит к данному окружению.
А в админке пишет, что лицензия активна и правильно показывает домен.
locksmith
locksmith 9 мая 2015 15:32
Ответов: 0 #4770
Также при указании параметра
$protect->use_localhost = true;

все равно выдает ту же ошибку.
locksmith
locksmith 9 мая 2015 15:47
Ответов: 0 #4771
также в папке data появляется полноценный showattach.lic
locksmith
locksmith 9 мая 2015 16:39
Ответов: 1 #4772
В логе проверки лицензий тоже все в порядке.
ПафНутиЙ
ПафНутиЙ 9 мая 2015 17:11
Ответов: 0 #4773
Все вопросы пишите на гитхаб. Тут только обсуждение общих вопросов.
locksmith
locksmith 9 мая 2015 17:17
Ответов: 0 #4774
А писать там куда? в идеи для админки?
chapser
chapser 28 августа 2015 14:44
Ответов: 1 #5045
Доброго времени суток! А как привязать защиту не к DLE, а любому другому скрипту? Что для этого нужно? Спасибо!
ПафНутиЙ
ПафНутиЙ 28 августа 2015 14:51
Ответов: 0 #5046
Защите не имеет привязки к какому либо движку, поэтому её можно интегрировать куда угодно.
Действуйте по аналогии с модулем для DLE.
Или посмотрите как реализован пример в репозитории.
chapser
chapser 28 августа 2015 14:52
Ответов: 1 #5047
А где там можно посмотреть?
ПафНутиЙ
ПафНутиЙ 28 августа 2015 14:54
Ответов: 0 #5049
В репозитории PCP-CS
chapser
chapser 28 августа 2015 14:53
Ответов: 0 #5048
Вот что выдает
Статус: Ошибка: локальный ключ не действителен для указанного ключа активации.
Имя, на которое выдан ключ активации: user1
Ключ действует вечно
Выполнялось 0.0051229000091553 секунд
chapser
chapser 28 августа 2015 15:57
Ответов: 1 #5050
Какая-то фигня выходит

Статус: Ошибка: локальный ключ не подходит к данному окружению.
Имя, на которое выдан ключ активации: client
Ключ действует до 31 August 2015, 00:00
Выполнялось 0.079596996307373 секунд

Опишите please варианты подключения с скриптам, только не на примере DLE, я с DLE совсем не дружу...
ПафНутиЙ
ПафНутиЙ 28 августа 2015 16:48
Ответов: 0 #5051
DLE - это всего лишь код, написанный на php.
У вас проблемы не с DLE точно, а с php.
chapser
chapser 28 августа 2015 16:57
Ответов: 0 #5052
Ну вот сделал, как описано здесь, на домен cl.ru закинул example.php и client.class.php. В example.php в $protect->server прописал сервер лицензий, т.е srv.ru/api.php. Создал метод и лицензию для домена cl.ru. Запускаю клиент, подгружается файл лицензии, но ошибка:

Статус: Ошибка: локальный ключ не действителен для указанного ключа активации.
Имя, на которое выдан ключ активации: client
Ключ действует до 31 August 2015, 00:00
Выполнялось 0.0037238597869873 секунд

Какой локальный ключ? Он должен быть одинаковым для сервера и клиента или что тут имеется в виду?

Подскажите, пожалуйста, что нужно прописать, например в index.php мой CMS, чтобы проверка проводилась и какие локальные ключи имеются в виду...

Предлагаю разработчику внедрить php-кодировщик. У себя на локалке внедрил, все работает, закодированный исходник такого вида:

<?php
function nehxWQAZEzChezGRR($ctQfPMrabVnif){ $ctQfPMrabVnif=gzinflate(base64_decode($ctQfPMrabVnif)); for($i=0;$i<strlen($ctQfPMrabVnif);$i++) { $ctQfPMrabVnif[$i] = chr(ord($ctQfPMrabVnif[$i])-1);} return $ctQfPMrabVnif;} eval( nehxWQAZEzChezGRR("dVdH7jxJVt5PS3OHn0a96J7UKG1VZqnpRXpf6S1C...

Unreal Licensing v2 - вот стоящее решение и без всяких лишних классов на сервере клиента... Достаточно прописать код, который генерит система для определенного продукта. Ключ универсальный, т.к. позволяет ставить скрипт как на основной домен, так и на поддомены в рамках основного домена.
savvato
savvato 14 сентября 2015 18:34
Ответов: 1 #5103
Такой вопрос, на сервере изменил статус лицензии на приостановлена. Но лицензия все равно активна. Пока не удалишь локальный ключ. Через какой период времени обновляется локальный ключ при смене статуса ключа?
ПафНутиЙ
ПафНутиЙ 14 сентября 2015 19:03
Ответов: 0 #5106
Локальный ключ проверяется с периодичностью, заданной в настройках метода проверки.
chapser
chapser 14 сентября 2015 18:48
Ответов: 1 #5104
даже, если удалить ключ, сайт все равно будет работать но только на одном домене. Этот скрипт бесполезен. Вот тема стоящая - phpmylicense.com. У меня есть русский вариант, даже улучшенный...

никаких сторонних файлов на стороне клиента не нужно, просто CURL

Информация

Посетители, находящиеся в группе Гости, не могут оставлять комментарии к данной публикации.