Есть в разработке под заказ один момент, о котором не пишут в учебниках, но который знает каждый фрилансер и агентство: момент передачи кода клиенту, который ещё не заплатил последний транш.
Формально всё по-взрослому: договор есть, акты есть, даже переписка в мессенджере есть, где клиент написал «ок, оплачу на этой неделе». А по факту сайт уже залит на его хостинг, доступы у него, и с этого момента вы находитесь в удивительной юридической позиции «ну да, я прав, но сайт-то у него работает уже без меня». Неделя проходит. Потом вторая. Потом внезапно оказывается, что «финансовый отдел решает вопрос», а сайт при этом отлично зарабатывает деньги без вашего участия.
Знакомо? Мне тоже. Поэтому расскажу, как перестать зависеть от честности слова и договорной дисциплины и переложить эту функцию на код.
Почему «просто добавить проверку лицензии» не работает
Первая мысль у всех одинаковая: сделать функцию checkLicense(), которая стучится на ваш сервер, и вызывать её где-нибудь в начале index.php. Красиво, просто, работает ровно до тех пор, пока клиент (или его «знакомый программист за пиво») не откроет файл и не увидит подозрительный вызов с незнакомым доменом.
Дальше сценарий немного предсказуем:
- вызов находится за пять минут поиском по слову
curl или file_get_contents - строчка удаляется
- сайт продолжает работать как ни в чём не бывало
- защита была скорее психотерапией для вас, чем реальным препятствием
Проблема в том, что отдельная проверка — это отдельная точка, которую можно вырезать без последствий для остального кода. А нам нужно, чтобы вырезание проверки било по чему-то важному, а не по одной изолированной строчке.
Идея: не проверка, а «печать»
Смена подхода простая на словах и приятно вредная на деле: мы не добавляем проверку оплаты как отдельный кусок. Мы шифруем сам рабочий код — тот самый функционал, без которого сайт не сайт: подключение к базе, генерация каталога, расчёт цены, что угодно критичное. Расшифровать этот код можно только ключом, который живёт не в файле клиента, а на вашем сервере, и отдаётся только если лицензия оплачена.
То есть в файле клиента вместо нормального кода лежит нечто вроде:
PHPКопировать код
$criticalCode = "U2FsdGVkX19q...длинная нечитаемая строка...";
А рядом — механизм, который на каждый хит идёт к вам за ключом, расшифровывает этим ключом код и тут же его выполняет. Пока лицензия оплачена — сервер отдаёт ключ, расшифровка проходит, всё работает. Как только оплата прекращается (или клиент решил, что вызов на ваш сервер ему не нравится, и удалил его) — ключа нет, расшифровка выдаёт мусор, и критичная функция сайта просто ложится. Не «работает с ограничениями», а именно ложится, потому что расшифровывать было нечего.
Разница принципиальная: раньше вырезалась проверка, а теперь вырезается ключ к собственному коду сайта. Удалить вызов к вашему серверу — это не «убрать защиту», это «выстрелить себе в само сердце функционала». Специально захочешь — не сделаешь так удачно.
Что происходит по шагам
Если разложить механику без магии:
- на своей машине вы один раз «запечатываете» критичный кусок кода: шифруете его и получаете нечитаемую строку
- эта строка кладётся в файл клиента вместо исходного кода
- на сайте клиента при каждой загрузке страницы происходит короткий запрос к вашему серверу: «домен такой-то, лицензия такая-то, дай ключ»
- ваш сервер сверяет домен и статус оплаты по своей базе и либо отдаёт ключ, либо не отдаёт
- если ключ получен — код расшифровывается и выполняется прямо в памяти, на диске он в открытом виде никогда не появляется
- если ключа нет (просрочена оплата, домен не совпал, запрос вообще не дошёл, потому что его вырезали) — расшифровка возвращает бессмысленный набор байт, и попытка это выполнить закономерно фейлится
Красота ситуации в том, что клиент физически не видит рабочий код в файлах вообще. Он видит шифротекст. Разобрать, что там было, без ключа — задача не «пять минут с гуглом», а скорее «нанять специалиста по реверс-инжинирингу и потратить на это больше денег, чем стоил сам проект».
Немного здорового цинизма
Честно: это не сейф Форт-Нокса. Если у клиента есть неограниченный доступ к серверу, время и желание, теоретически можно вытащить расшифрованный код прямо из памяти процесса в момент выполнения. Абсолютной защиты от человека с root-доступом и упорством не существует — и любой, кто продаёт вам такую защиту, немного вас обманывает.
Но задача была не «сделать невозможным», а «сделать невыгодным». Обычный сценарий недобросовестного клиента — не найм реверс-инженера на две недели, а «попросить знакомого фрилансера полчаса поковыряться». Вот от этого сценария печать защищает почти идеально: полчаса поковыряться там уже не получится, а найм специалиста по цене выше стоимости проекта делает саму идею экономически бессмысленной.
Плюс это всё равно не отменяет договор, акты и человеческую беседу «слушайте, оплатите, пожалуйста». Код — это подстраховка на случай, если беседа не сработала, а не замена ей.
Итог
Работает это примерно как охранная пломба на технике: снять можно, но факт снятия сразу всё портит и виден невооружённым глазом. Клиент, который решит вырезать проверку, получает не «сайт без защиты», а «сайт, который перестал работать», и это куда более убедительный аргумент в переговорах об оплате, чем строчка в договоре про пени за просрочку.