Как мы облачный PHP-сервис завернули в коробку — с защитой, лицензией, и при этом ускорились

Мы привыкли к облакам и сервисам по подписке (что называется сложным словом SaaS) . Заливаешь данные, строишь календарики — и не задумываешься, на чьих там они серверах хранятся. Удобно? Да. Безопасно? Ну, так… Обычно мы на это забиваем. Или не задумываемся. Или задумываемся, но всё равно забиваем.

Именно сервисом по подписке наша система управления проектами BIPULSE и была. Это такой «отечественный аналог» MS Project + Jira + некоторых других систем управления задачами. Работали долго, крутились в облаке, продавали лицензии. Но это ж B2B, не B2C — и чем дальше, тем больше российские проектные бизнесы переставали доверять облакам. Особенно вот с февраля, пресловутое импортозамещение.

Бизнес хочет решение у себя на сервере, чтобы контролировать данные. Всё-таки информационная безопасность. Там — не забивают. Там — не доверяют. И правильно делают. Поставляйте нам, говорят, коробку. Сервис классный, возьмём. Но как — коробку? У нас обычный веб-сервис, PHP + JS + Postgres. Почти 80% веба на этом стеке, он удобный и выполняет свои задачи. Но — он не предназначен для “отгрузки”, ведь поставлять нужно исходники. А делать это крайне не хочется.

Я расскажу, как нам удалось и защитить PHP-код, и сделать лицензирование, и наладить поставки, и при этом ускориться. В конце будет ссылка на техническую статью.

Как мы облачный PHP-сервис завернули в коробку — с защитой, лицензией, и при этом ускорились

Почему нельзя продавать с открытыми исходниками

Open Source это конечно хорошо, но лишь когда ты потребитель. А когда ты поставщик и тебе хочется кушать, лучше иметь технические средства защиты помимо юридических.

Второй фактор: алгоритмы! Для обычных программ типа Redmine и похожих, там кроме простой прослойки между браузером и базой данных ничего нет. А у нас есть вычисления статистики, расчёт критической цепи (ага, той самой, про которую Э. Голдратт писал) , выравнивание ресурсов и другое — собственно, вся суть нашего продукта, куча функциональности. Это достаточно хитрые алгоритмы и хочется их защитить.

Почему не подходят стандартные средства защиты для PHP

Для PHP есть средства типа ZendEncoder, Ioncube и другие но… но они снимаются легко за счёт выгрузки байт-кода и разворачивания его в исходный текст. А мы хотели иметь чуть лучшую защиту, чтобы направление взлома хотя бы требовало знания ассемблера, а не утилит декомпиляции.

Может, избавиться от PHP и переписать заново?

:))) Конечно же! Чего там, на недельку делов — скажет любой студент. А любой опытный разработчик ответит: “Рабочая система, с 10-летней историей, десятки тысяч строк кода, сотни рабочих интеграционных тестов. Переписать? Это без меня, пожалуйста”. И пошлёт к студенту.

Для очистки совести, мы даже прикидывали варианты. Может, пересобрать это всё с C#, чем-то типа IronPHP? — .NET даст скорость исполнения, но не защитит от вскрытия. Портировать на С++? Синтаксис-то похож, да и часть функций это чистый POSIX (стандарт для unix систем) . — Перестанет быть поддерживаемо, и риск 100%, что увязнем в портировании.

И пока мы раз за разом отчаивались…

KPHP — компилятор PHP-кода от ВКонтакте

В конце 2020 года ВК выложили в open source свой компилятор. Оказывается, бэкенд ВКонтакте полностью написан на PHP, а с помощью KPHP они получают бинарник, который работает значительно быстрее оригинального PHP-кода. Точнее, KPHP транслирует PHP в С++, попутно делая ряд хитрых вещей, и плюсовые исходники уже в бинарник и превращаются.

C++! Бинарник! Вот ключевое слово для нас. Ведь бинарник — это по сути и есть коробка. Если упаковать туда весь код, сделать раздачу картинок и JS, закрыть лицензией… Может, ещё и ускорится? Ведь KPHP нужен ВК для производительности прежде всего.

Завести KPHP: хакатон длиной в полгода

Если после бессонных суток за компом исчезает блеск в глазах — не бескопойтесь: через ещё одни сутки он опять появляется:)

Это было реально долго. И не с первого раза. По трём причинам:

Во-первых, ВКонтакте делают в KPHP только то, что нужно им в работе. Например, базы данных PostgreSQL и Sqlite не поддержаны — а нам нужно. Сначала думали, что вообще не получится ничего — но потом ВК реализовали поддержку FFI (способ подключения любых внешних модулей), накидали прототип — базы заработали! Казалось бы, всё остальное — дело техники, но…

Во-вторых, KPHP не может взять и "прожевать" любой PHP-код. Код должен быть строгим, с типизацией, примерно как в С++ или Java. А обычно PHP-проекты пишутся не так, обычно PHP-код насыщен конструкциями, которых лучше бы не было. KPHP много ругался, и ругался по делу. Одних только ошибок типизации было 30 тысяч штук. Исправляли, матерились. Мол, компилятор, если ты такой умный — возьми и сам исправь :) Но тут гигантский плюс: мы нашли участки кода, которые работали лишь потому что везло, и могли сломаться в любой момент. Переход на строгую типизацию и отсутствие «грязных PHP-хаков» сделало код значительно надёжнее и понятнее, поддерживать его стало заметно проще. Эта боль стоила того.

В-третьих, помимо баз данных, KPHP много чего не умеет, что опять-таки не нужно было ВК. Запуск процессов, парсинг XML и прочее. Мы были на связи с разработчиками компилятора. Что-то они добавляли, что-то фиксили, где-то мы вставляли костыли и подпорки. Иногда падало, иногда работало по-другому. Почти всему находилось объяснение, почти всегда дело было в нашем коде. Месяца два мы были в состоянии “почти-почти”, казалось бы вот ещё исправить и заработает, но нет, что-то находилось ещё, а потом ещё и ещё. И это когда тебя бизнес каждую неделю пингует — нучотам, когда коробка?

И да. Мы завели. Доделали. И реально — работает!

В августе-сентябре мы начали поставки коробок клиентам, большим и маленьким. Пройдя семь кругов рефакторинга, сумели сделать лицензию. И скорость! Расчёты расписания ускорились в 3 раза. При этом мы вообще не занимались оптимизациями — а внутри KPHP есть много хитростей, коих нет в обычном PHP и что позволяет выжать ещё больше. Когда-нибудь поисследуем.

По хронологии, вышло так:

  • декабрь 2021 — плавно начинаем миграцию
  • январь 2022 — ничего не работает
  • март 2022 — а-а-а-а-а, MS Project Server ушел с российского рынка, клиенты ищут замену, Лёха лови их!
  • апрель 2022 — кажись, что-то заработало
  • май 2022 — ура, приёмочное тестирование на 100% пройдено
  • июнь 2022 — подключили PostgreSQL, собрали установочный образ, развернулись на облачных клиентов
  • июль 2022 — а-а-а-а, срочно исправляйте
  • сентябрь 2022 — стабилизировались, все системы в норме. Есть установочный пакет и Руководство Администратора для развёртывания на сервере Клиента.

Итоги

А стоило оно того, чтобы инвестировать уйму времени? Да!

  1. Главное требование бизнеса — коробка! И наше ответное требование — лицензионная защита. Мы накрываем готовый бинарник стандартными средствами защиты С++ кода.
  2. Ушли много рисков с утечками и числом лицензий. Теперь мы можем поставлять даже 1-2 лицензии, что по стоимости соответствует тому же MS Project Professional, но с функциями сервера и кросспроектными связями.
  3. Вычисления стали работать в 3 раза быстрее. Расписание на 20 000 работ с выравниванием ресурсов вычисляется всего за 5 секунд против 15-20 ранее.
  4. Даже если бы мы защитили PHP-код — всякие скрипты и картинки пришлось бы поставлять в оригинале. А здесь защищены и они. Они тоже упакованы в KPHP-бинарник, и пользователь не может их менять. При этом раздаются мгновенно напрямую из памяти.
  5. Поддерживаемость кода. Много ошибок теперь ловится компилятором, а не в бою у пользователя. Значит, ещё +150 единиц к качеству.

Кстати, отдельно поясню: это НЕ переписывание на другой язык. Мы по-прежнему разрабатываем и тестируем на обычном PHP — а KPHP только для поставки в прод. В течение всего периода адаптации система оставалась рабочей и всегда запускалась на PHP. Исправили — проверили. Порефакторили — проверили. И в конце концов KPHP всё прожевал. Это эволюция, а не переписывание. Так можно. Переписывать — нет.

В общем, теперь команде ВКонтакте придётся поддерживать обратную совместимость: )

А за техническими подробностями — на Хабр

1313
9 комментариев

Спасибо за то, что поделились крутым опытом. Тоже присматриваемся к KPHP для создания коробочных версий из SaaS и думаем над технической защитой кода.

Что касается защиты кода, то видим смысл защищать только код PHP. Всякие картинки, стили, скрипты - не видим смысла, потому что веб-ресурсы открытые.

Чтобы сократить возможные трудности по переходу с PHP на KPHP, мы тупо сокращаем объем PHP-кода по следующей стратегии:
1. Фронтенд пытаемся сделать максимально независимым от бекенда. Считайте, UI просто принимает на вход данные в формате JSON. Никакого SSR. Где можно, там SPA.
2. Обмен данными с сервером - RPC. Так нам проще контролировать.
3. На бекенде код PHP изначально пишется с указанием типов.

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

Кстати, вы упаковываете только сервер в коробку? Браузер в нее не добавляете?

1
Ответить

У нас была миграция на React/JSL с XSLT в 2020 году примерно. Это тоже было больно, но реальных шаблонов на PHP у нас никогда не было. Поэтому миграция была простой. После миграции на PHP/JSL всё приложение стало SPA и миграция в KPHP стала доступной (ввиду отсутствия LIBXML внтури).

Упаковка картинок и скриптов внутрь кода повышает скорость их отдачи, и уменьшает вероятность нарушения целостности при обновлениях и разных размещениях.

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

Старый код у нас был еще под PHP4 написан, в технической статье (внизу ссылка) детали раскрыты. Поэтому на типизации мы огребли сильно. Но сейчас конечно сразу проверка идёт по типам потому что сборка выполняется.

1
Ответить

Очень интересно, спасибо что поделились опытом.

Прочитав название, вспомнился продукт от Гевина Бэлсона - the Box)) https://www.youtube.com/watch?v=OSZOf9pyepc

Кажется это будет все более и более актуально. Переходить из облака в серверные решения внутри предприятия.

1
Ответить

С названием у нас длинная история. Был "Бизнес Пульс " (чтобы держать руку на пульсе бизнеса) при перезапуске в 2015 году сменили на BI PULSE , потом убрали пробел. Потом отделили Методику от системы https://pulsemanagement.org/ сейчас система начала отставать от Методики.

Ответить

Так а как защищаетесь от того, что клиент тупо виртуалки накопирует для всех своих друзей? Если там что-то типа запроса на центральный сервер каждые 5 минут для валидации ключа, то чем это лучше облака для клиента (что так, что так, все может превратиться в тыкву)?

1
Ответить

Сервер пока не спрашиваем, но привязка есть к железу. Так как решение корпоративное, то "накопирует для друзей" маловероятно, но даже если и так, то значит пойдем по пути Windows %))

Ответить