Как защитить свой php-скрипт и привязать его к домену на примере модуля для DLE » Techno-Co — Всё для вебмастера, для создание сайтов с нуля. {title}

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

Так же нам понадобятся прямые руки и система PCP-CS от Олега Mofsy.

Что такое pcp-cs

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

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

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

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

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

Установка и настройка серверной части 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, admin4. Настраиваем конфиг в трёх файлах: admin/config/db_config.php — Конфиг БДadmin/config/config.php — Конфиг админкиapi/config.php — Конфиг pcp-csТакое разделение обусловлено независимостью админки от серверной части pcp-cs.5. Всё! Адинка готова к работе. Можно приступать к защите подопытного модуля.

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

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

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

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

'key' => !empty($key) ? $key : false,

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

// Если есть ключ и задан ID новости — работаем
if ($cfg['newsId'] && $key) {
......
} elseif (!$key) {
    $showAttach = 'Не указан лицензионный ключ.';
}
echo $showAttach;

результат:. Добавляем в строку подключения ключ и проверяем: Теперь нужно добавить проверку введённого ключа с помощью pcp-cs.

Внедряем код клиента в наш модуль. Для экономии ресурсов рекомендую сжать код клиентского класса через любой удобный инструмент. Я использовал сервис PHP-Minifier. Вставляем полученный код перед основным кодом модуля. Если при проверке выдаёт ошибку:

Fatal error: Namespace declaration statement has to be the very first statement in the script in

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

namespace MofsyLicenseClient;

Сразу после кода клиентского класса можно его задействовать и произвести проверку.В комментарияк к коду ниже я расписал что и как происходит.

// Теперь можно запустить проверку лицензии
$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'                       => 'Активна',
    'status_2'                       => 'Внимание: срок действия лицензии закончился.',
    'status_3'                       => 'Внимание: лицензия переиздана. Ожидает повторной активации.',
    'status_4'                       => 'Ошибка: лицензия была приостановлена.',
    'localhost'                      => 'Активна на localhost: используется локальный компьютер, на реальном сервере произойдет активация, если вы правильно ввели лицензионный ключ активации в настройках.',
    'pending'                        => 'Ошибка: лицензия ожидает рассмотрения.',
    'download_access_expired'        => 'Ошибка: ключ активации не подходит для установленной версии. Пожалуйста поставьте более старую версию продукта.',
    'missing_activation_key'         => 'Ошибка: ключ активации не указан.',
    'could_not_obtain_local_key'     => 'Ошибка: невозможно получить новый локальный ключ.',
    'maximum_delay_period_expired'   => 'Ошибка: льготный период локального ключа истек.',
    'local_key_tampering'            => 'Ошибка: локальный лицензионный ключ поврежден или не действителен.',
    'local_key_invalid_for_location' => 'Ошибка: локальный ключ не подходит к данному окружению.',
    'missing_license_file'           => 'Ошибка: создайте следующий пустой файл и папки если их нету:
', 'license_file_not_writable' => 'Ошибка: сделайте для записи следующие пути:
', 'invalid_local_key_storage' => 'Ошибка: не возможно удалить старый локальный ключ.', 'could_not_save_local_key' => 'Ошибка: не возможно записать новый локальный ключ.', 'activation_key_string_mismatch' => 'Ошибка: локальный ключ не действителен для указанного ключа активации.' ); // Запускаем валидацию лицензии $protect->validate(); $license = false; // Если истина, то лицензия в боевом состоянии и можно работать дальше. if($protect->status) { $license = true; }

Немного доработок в условиях:

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

echo $showAttach;

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

Вот, собственно, и вся процедура реализации защиты модуля. Остаётся только закодировать код модуля в IonCube и можно продавать или раздавать бесплатно.

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