vipstrizhkasobak.ru — сайт груминг-студии в Москве, собранный заново после того, как её прежний сайт на Joomla взломали. Стек выбрали такой, в котором нечего ломать: чистый PHP и JSON, без CMS, без базы данных, без загрузки файлов. Через три недели после запуска взломали весь хостинг-аккаунт целиком, и это стало проверкой боем: ни один файл сайта не пострадал.
Клиент: груминг-студия «ЭСТА», Москва, Измайлово · Сайт: https://vipstrizhkasobak.ru · Категория: сайт
Коротко о главном
- Стек без дыр. Чистый PHP 8.3 плюс JSON-файлы. Нет CMS, нет базы данных, нет загрузки файлов.
- Сайт нашли ИИ-поисковики. За пять дней его прочитали ChatGPT (37 визитов), Perplexity и Claude. Это результат GEO-инфраструктуры, а не случайность.
- Главная отдаётся за 0,34 секунды и весит 9,8 КБ в сжатом виде.
- Интерактивный маскот вместо всплывающего окна: шесть состояний, восемь анимаций, меню связи по клику.
- Мониторинг целостности проверяет сайт каждые полчаса и пишет владельцу в Telegram.
- 89 позиций прайса и 30 страниц пород владелец правит сам, без программиста.
Технологический стек
- Бэкенд: чистый PHP 8.3 без фреймворка.
- Данные: JSON-файлы, база данных отсутствует как класс.
- Фронт: PHP-шаблоны, адаптивная вёрстка mobile-first, шрифт Exo 2.
- Хостинг: общий PHP-хостинг, деплой по SSH.
- Заявки: PHP-обработчик, запись в JSON плюс мгновенное уведомление в Telegram.
- Генерация ассетов: rembg для вырезания фона, fal.ai для генерации изображений, PIL для нормализации, exiftool для метаданных.
- Аналитика: Яндекс.Метрика.
У клиента общий хостинг без Node на сервере. Поэтому всю тяжёлую работу (вырезать собаку из фотографии, сгенерировать фон, привести 79 снимков к единому квадрату, проставить EXIF) делали локально в Docker-контейнерах, а на сервер уезжал готовый результат. Docker при этом повторяет прод: тот же Apache, тот же PHP, тот же .htaccess. Поэтому «у меня работает» и «на сервере работает» означают одно и то же.
С чего всё началось
Прежний сайт студии стоял на Joomla, и его взломали. Типичная история для старой CMS на общем хостинге, где движок и плагины годами не обновлялись. Восстанавливать заражённую систему смысла не было: те же дыры вернули бы ту же проблему через месяц.
Задачу сформулировали прямо: сделать сайт, который физически нечем ломать.
Старый сайт при этом пригодился как источник данных. С него аккуратно, только на чтение, вытащили 200 фотографий, весь прайс, структуру из 41 адреса, тексты по 30 породам и юридические документы. Ни строчки чужого кода в новый проект не попало.
Полный список реализованных функций
🌐 Сайт и страницы
- Главная с героем: вырезанная собака на сгенерированном фоне
- Блок о студии с фотографией мастера, преимущества, популярные породы, работы, отзывы, форма записи
- Адаптив под 375, 768 и 1024 пикселя
- Шапка сворачивается в одну строку при прокрутке
- Ступенчатый зум интерфейса на широких мониторах
🐕 30 страниц пород
- Отдельная страница на каждую породу: цена комплекса, таблица «груминг, гигиена, СПА», состав процедуры
- Всё рендерится из одного JSON-файла, новая порода добавляется через админку за минуту
💰 89 позиций прайса
- Хаб-страница с четырьмя карточками и четыре подстраницы с таблицами
- 44 позиции по собакам (от 2000 до 6600 ₽), 3 по кошкам, 13 дополнительных услуг, 29 СПА-комплексов
- Цена через дробь означает выбор между стрижкой и триммингом, что важно для жесткошёрстных пород
- Владелец правит прайс сам, изменения видны сразу
🐩 Интерактивный маскот
- Нарисованный пёс в углу вместо всплывающего окна, которое закрывают не читая
- Шесть состояний, микроанимация, восемь вариантов случайной смены кадра каждые восемь секунд
- Реплики вроде «Комплекс от 3300 ₽, посмотри цены»
- По клику разворачивается меню: WhatsApp, Telegram, звонок, цены, запись
🛠 Админ-панель
- Вход с сессиями и защитой от подделки запросов
- Дашборд, правка контактов, цен и пород, список заявок
- Атомарная запись в JSON: две одновременные заявки не перетирают друг друга
📨 Заявки и защита от спама
- Форма пишет заявку в файл и сразу отправляет её в Telegram-группу студии
- Ползунок «сдвиньте вправо»: тянется мышью, пальцем и управляется с клавиатуры
- Подписанный токен на сервере с проверкой времени: отправка быстрее трёх секунд или без валидной подписи отклоняется
- Скрытое поле-ловушка для примитивных ботов
Настоящая проверка живёт на сервере. Ползунок можно обойти скриптом, а подписанный токен с проверкой времени уже нет.
🖼 Галерея и отзывы
- 79 работ «до и после», приведённых к единому квадрату 600 × 600
- Отзывы в трёх лентах (Яндекс, WhatsApp, Авито) со звёздами, нарисованными кодом, и перетаскиванием мышью
- 146 изображений, в каждом прописаны EXIF-данные студии
📄 Юридические документы
- Оферта, политика конфиденциальности по 152-ФЗ, два согласия на обработку данных, правила бытового обслуживания
- Оригинальные тексты под конкретный бизнес, с реквизитами оператора персональных данных и надзорными органами
- Паспортные данные на сайт не выносятся
🔍 SEO
- Динамическая карта сайта на 46 адресов, обновляется сама при правках в админке
- Разметка Schema.org на каждой странице, канонические адреса, Open Graph, уникальные заголовки
- 301-редиректы со всех старых адресов Joomla: накопленный вес страниц не потерялся при переезде
🤖 GEO: оптимизация под ИИ-поиск
- llms.txt с кратким описанием студии и картой ссылок
- llms-full.txt с полным содержимым: контакты, все 89 позиций прайса, 30 пород с ценами
- В robots.txt явно разрешены GPTBot, OAI-SearchBot, PerplexityBot, ClaudeBot, Google-Extended
- Оба файла генерируются из тех же данных, что и сайт, поэтому не устаревают
⚡ Скорость и безопасность
- Сжатие, кэширование статики, заголовки безопасности, принудительный HTTPS
- Служебные папки закрыты от прямого доступа
- PHP подняли с мёртвой версии 7.3 до актуальной 8.3.31
Взлом, который сайт не заметил
Через три недели после запуска на хостинге случилась катастрофа. Рассказываем честно, потому что это лучшее доказательство правильности выбранного стека.
Что произошло. На том же хостинг-аккаунте жил ещё один сайт клиента, старая Joomla. Её взломали 26 июня. 25 июля в 06:17:28 злоумышленник запустил массовое заражение аккаунта: за минуту по всем папкам разлетелись 13 копий веб-шелла filefuns.php, больше 20 подменённых файлов .htaccess и два паразитных домена-дорвея, которых владелец не создавал.
Самое неприятное было в памяти сервера. Там поселился процесс php -f /tmp/httpd.conf. Он стёр себя с диска сразу после запуска и работал в бесконечном цикле, пересоздавая вредоносные файлы каждые 0,3 секунды. Именно поэтому заражение возвращалось после каждой чистки. Процесс прожил 12 суток, и увидеть его можно было только через SSH: по FTP процессы не видны.
Что при этом случилось с нашим сайтом. Ничего. Мы сверили контрольные суммы всех файлов проекта с локальными эталонами, совпали все до единого. Заражение подбросило файлы рядом, но не смогло ничего изменить внутри сайта, потому что менять было нечего: нет ни CMS с уязвимыми плагинами, ни базы данных, ни загрузки файлов, ни выполнения кода. Веб-логи подтверждают, что через сайт не прошла ни одна попытка проникновения.
Как чистили. Подключились по SSH и нашли резидентный процесс, невидимый по FTP. Извлекли код червя прямо из памяти через /proc, потому что на диске файла уже не было, и получили доказательство для хостинга. Остановили процесс, удалили 13 бэкдоров, вернули оригинальные .htaccess, снесли два паразитных домена. Прогнали сигнатурный скан всего аккаунта: 0 веб-шеллов, 0 обфусцированного кода, планировщик задач чист. Составили для хостинга отчёт с точным временем, идентификатором процесса и кодом вредоноса.
Что сделали, чтобы это не повторилось. Написали сторож целостности, который работает на стороне разработчика, а не на сервере: сторож, которого можно взломать вместе с сайтом, бесполезен. Каждые 30 минут скрипт заходит по ключу, сверяет контрольные суммы всех файлов с эталоном, ищет известные имена бэкдоров и обфусцированный код, проверяет список процессов и планировщик. Сообщения приходят в Telegram в двух случаях: если что-то изменилось и один раз в сутки утром со словами «всё чисто». Проверено подбросом тестового файла: тревога приходит с точным путём.
Отдельная история про Installatron. Позже, когда владелец удалял в панели остатки старых приложений, встроенный установщик хостинга решил, что наш сайт тоже относится к удаляемой установке, и снёс часть файлов. Сайт лежал час двадцать. Восстановили за минуту заливкой из локального проекта, потому что весь код лежит в системе контроля версий, а деплой воспроизводим. Заявки и настройки не пострадали. В логах отчётливо видно виновника: запросы к файлам удаления шли от Installatron Plugin с адреса самого сервера.
Результаты
Сайт нашли ИИ-ассистенты
Данные из журнала сервера за пять дней, с 14 по 19 августа 2026 года:
| Кто заходил | Визитов |
|---|---|
| ChatGPT (OAI-SearchBot и ChatGPT-User) | 37 |
| Bytespider (ИИ ByteDance) | 391 |
| PetalBot | 4 |
| PerplexityBot | 3 |
| Google-Extended | 2 |
| ClaudeBot | 1 |
Визиты ChatGPT-User означают, что живые люди спрашивали ассистента про студию, и он ходил на сайт за ответом. Ради этого и делалась GEO-инфраструктура.
Классический поиск
| Поисковик | Визитов за пять дней |
|---|---|
| YandexBot | 144 |
| Googlebot | 82 |
| bingbot | 73 |
Поисковики обходят и породы, и цены, и документы, корректно проходя по настроенным редиректам со старых адресов. Есть переходы с карточки студии в Яндекс.Картах.
PageSpeed Insights, отчёт от 19 августа 2026
| Категория | Баллы |
|---|---|
| Производительность | 96 |
| Специальные возможности | 93 |
| Рекомендации | 96 |
| Поисковая оптимизация | 100 |
| Агентный просмотр | 3 из 3 |
Метрики загрузки: First Contentful Paint 0,8 секунды, Largest Contentful Paint 1,2 секунды, Total Blocking Time 10 миллисекунд, Cumulative Layout Shift 0,001, Speed Index 1,0 секунды.
Техника
| Показатель | Значение |
|---|---|
| Страниц в карте сайта | 46 |
| Отдача главной | 0,34 секунды, 9,8 КБ сжато |
| Версия PHP | 8.3.31 |
| Объём кода | 1648 строк |
| Изображений на сайте | 146 |
| Запросов к сайту за пять дней | 3466 |
| Спам-заявок отсеяно капчей | 5 |
| Файлов сайта повреждено при взломе аккаунта | 0 |

