Защита периметра у российского хостинга: что мы изменили после инцидента у клиента
В феврале 2026 у нашего клиента — частной медицинской клиники из ЮВАО Москвы — лёг сайт с системой записи пациентов. На пятницу, 13:40, в самый пиковый час — пациенты не могут записаться, операторы перезванивают вручную, директор клиники мне в WhatsApp пишет «Семён, у нас ад». Это была классическая атака на инфраструктуру: DDoS L7 на форму записи + одновременный SQL-fuzz на /api/. Через четыре часа мы вывели всё в работу, через две недели — полностью пересобрали защиту периметра. Этот материал — отчёт о том, что мы поменяли, какие выводы сделали о российских хостингах в 2026 и почему теперь рекомендуем нашим клиентам конкретный набор инструментов «без героики». Внутри — конкретные конфиги, ценники, фразы из переписки с хостерами.
Что произошло у клиента 13 февраля 2026
Инфраструктура клиники до атаки выглядела среднестатистически: сайт на WordPress + плагин записи на приём, VDS на Reg.Ru за 1 800 ₽/мес (Ubuntu 22.04, 4 vCPU, 8 GB RAM), MySQL на той же машине, бэкапы средствами хостера раз в сутки. Защита по умолчанию — fail2ban для SSH, базовый ModSecurity в Nginx с правилами CRS, Cloudflare Free для базового CDN.
В 13:40 загрузка CPU виртуалки скакнула с обычных 8% до 100%. nginx начал отдавать 504. В логах — десятки тысяч POST-запросов на /api/booking/check-slot/ в секунду со множества IP. Cloudflare Free пропускал большинство: атака была построена грамотно — каждый IP делал 1-2 запроса за 30 секунд, что не триггерило rate-limit. На пике через сервер проходило около 14 000 RPS вместо обычных 40-60.
Параллельно — попытки эксплуатации в форме поиска врача: SQL-инъекции, путь /wp-json/wp/v2/users (распространённый сбор логинов), попытки brute-force в /wp-admin. По логам ModSecurity — 47 000 заблокированных запросов за 20 минут. Часть пробилась.
Помимо технической части был ещё один интересный момент. На третьем часу атаки в почту директору клиники пришло письмо: «Ваш сайт под нагрузкой, переведите 0,008 BTC на адрес ниже, мы остановим атаку. Иначе будем продолжать». Классическая ransom-DDoS схема. Директор молча переслал нам письмо с подписью «не плачу принципиально».
Как мы выводили клинику из атаки за 4 часа
Шаг 1. Перевод трафика на Cloudflare с включённым «I am Under Attack»
Первое и самое быстрое — перевод DNS A-записи сайта на Cloudflare с включением режима «Under Attack Mode». Это режим, в котором каждый посетитель проходит JavaScript-челлендж перед попаданием на сайт. Боты этот челлендж в большинстве случаев пройти не могут, реальные пациенты — проходят за 5-7 секунд (видят страницу «Checking your browser»).
На это ушло 12 минут, потому что DNS у клиента изначально был на Reg.Ru NS-серверах с TTL 86400 (сутки!). Пришлось менять не только записи, но ждать пропадания старого кэша у провайдеров. Я бы хотел, чтобы у каждого нашего клиента TTL по умолчанию стоял 300 секунд именно для таких ситуаций.
# Cloudflare API: включить Under Attack Mode
curl -X PATCH "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/settings/security_level" \
-H "Authorization: Bearer ${CF_API_TOKEN}" \
-H "Content-Type: application/json" \
--data '{"value":"under_attack"}'
# Дополнительно — включить Bot Fight Mode
curl -X PATCH "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/bot_management" \
-H "Authorization: Bearer ${CF_API_TOKEN}" \
-H "Content-Type: application/json" \
--data '{"fight_mode":true,"sbfm_likely_automated":"managed_challenge"}'
Шаг 2. Перенос nginx за тонкий слой защиты
Параллельно мы поменяли конфигурацию nginx: подняли rate-limit на критичный endpoint /api/booking/check-slot/ до 5 запросов в минуту с одного IP, на /wp-admin — 3 запроса в минуту, добавили блокировку по User-Agent для известных стрессеров (curl/wget/python-requests без явных кастомных заголовков).
# /etc/nginx/sites-enabled/clinic.conf — фрагмент
limit_req_zone $binary_remote_addr zone=booking:10m rate=5r/m;
limit_req_zone $binary_remote_addr zone=admin:10m rate=3r/m;
limit_req_zone $binary_remote_addr zone=api_strict:10m rate=10r/m;
# Блок известных стрессер-патернов
map $http_user_agent $bad_agent {
default 0;
"~*python-requests" 1;
"~*curl/[0-9]" 1;
"~*GoHttpClient" 1;
"~*okhttp/3" 1;
"~*Wget" 1;
"" 1;
}
server {
server_name clinic.ru;
listen 443 ssl http2;
if ($bad_agent) { return 403; }
location /api/booking/check-slot/ {
limit_req zone=booking burst=2 nodelay;
limit_req_status 429;
proxy_pass http://localhost:8080;
}
location /wp-admin/ {
limit_req zone=admin burst=1 nodelay;
allow 192.168.10.0/24; # офис клиники
allow 51.250.84.211; # наш VPN-шлюз
deny all;
}
location /api/ {
limit_req zone=api_strict burst=5 nodelay;
proxy_pass http://localhost:8080;
}
}
Через 25 минут после переключения на Cloudflare и применения rate-limit нагрузка на сервере вернулась к 30%, отказы прекратились, форма записи заработала. Для пациентов это видно как «сайт сначала был медленный, потом нормальный». Для нас — четыре часа адреналина.
Шаг 3. Восстановление пропущенных запросов
Проверили БД на следы успешных SQL-инъекций. ModSecurity заблокировал 99% попыток, но на трёх запросах ошибка стала видна только по логам — успели почистить кеш wp-options и сменить ключи WP_AUTH в wp-config.php. Принудительно сбросили все активные сессии админов через очистку wp_users.user_activation_key. Это формальная гигиена после инцидента.
Что мы изменили в архитектуре после атаки
За две недели после инцидента мы пересобрали защиту периметра почти полностью. Главный принцип, который я сформулировал на встрече с директором клиники: «защита должна быть не в сервере, а перед сервером». Это хорошо звучит и при этом технически правильно — все слои фильтрации поднялись на CDN-уровень, сервер стал «тонким».
Перенос с Reg.Ru на Selectel + Cloudflare Pro
VDS Reg.Ru за 1 800 ₽/мес — для лендинга это нормально, для клиники с EMR-системой — слишком тонко. Перевезли инфраструктуру в Selectel: VDS «Стандарт» 4 vCPU/8 GB/120 GB SSD за 2 600 ₽/мес, плюс резервная копия в Я.Облаке (Object Storage) — около 400 ₽/мес. Параллельно обновили Cloudflare с Free на Pro (около 2 200 ₽/мес) — это даёт WAF с управляемыми правилами, image optimization, расширенную аналитику.
Я уважаю Reg.Ru как регистратора (домены и DNS у клиники там и остались), но как хостинг-провайдер для критичных сервисов — мне здесь не нравится. По моему опыту, у Selectel и Я.Облака сетевая инфраструктура в Москве заметно надёжнее. У клиники после переезда uptime по мониторингу UptimeRobot — 99,98% за два месяца.
WAF-правила Cloudflare под бизнес-логику
На Cloudflare Pro мы написали 14 кастомных WAF-правил, которые закрывают типичные сценарии для клиники:
# WAF Custom Rules (Cloudflare Expression Language)
# Правило 1: блок POST на форму записи без валидного X-Source-Token
(http.request.uri.path eq "/api/booking/check-slot/"
and http.request.method eq "POST"
and not http.request.headers["x-source-token"][0] in {
"frontend-prod-2026-01" "ios-app-2025-12"
})
=> Block
# Правило 2: rate-limit /wp-login.php — 5 попыток в час
(http.request.uri.path eq "/wp-login.php")
=> Managed Challenge (rate: 5r/h per IP)
# Правило 3: блокировка путей-разведчиков
(http.request.uri.path matches "(?i)(/\\.env|/\\.git|/wp-config|/phpmyadmin|/admin\\.php)")
=> Block
# Правило 4: блок known-bad SHODAN/Censys агентов
(http.user_agent contains "Censys" or http.user_agent contains "Shodan"
or http.user_agent contains "MJ12bot" or http.user_agent contains "AhrefsBot")
=> Block
# Правило 5: только Россия и СНГ для админки
(http.request.uri.path matches "^/wp-admin"
and not ip.geoip.country in {"RU" "BY" "KZ" "AM"})
=> Block
Бэкапы по схеме 3-2-1 без оптимизма
До атаки у клиента бэкап был один — снимок виртуалки на стороне хостера, делается раз в сутки, хранится 7 дней. Этого катастрофически мало. Я ввёл схему 3-2-1: три копии (продуктив + два бэкапа), на двух разных носителях, одна — оффсайт.
#!/bin/bash
# /usr/local/bin/clinic-backup.sh — запуск через cron каждый час для БД,
# раз в сутки для файлов
set -euo pipefail
BACKUP_DIR=/var/backups/clinic
S3_BUCKET=s3://clinic-backups-itfresh
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
RETENTION_DAYS=14
RETENTION_S3_DAYS=90
# 1. БД — каждый час
mysqldump --single-transaction --quick \
--triggers --routines --events \
-u backup -p"${MYSQL_BACKUP_PASS}" \
clinic_main | gzip -9 > "${BACKUP_DIR}/db-${TIMESTAMP}.sql.gz"
# 2. Файлы и uploads — раз в сутки
if [ "$(date +%H)" = "03" ]; then
tar czf "${BACKUP_DIR}/files-${TIMESTAMP}.tar.gz" \
/var/www/clinic/wp-content/uploads \
/var/www/clinic/wp-config.php \
/etc/nginx /etc/letsencrypt
fi
# 3. Заливка в Я.Облако Object Storage (S3-совместимый)
aws s3 cp "${BACKUP_DIR}/db-${TIMESTAMP}.sql.gz" "${S3_BUCKET}/db/" \
--endpoint-url=https://storage.yandexcloud.net \
--storage-class=STANDARD_IA
# 4. Локальный rotation
find "${BACKUP_DIR}" -name "db-*.sql.gz" -mtime +${RETENTION_DAYS} -delete
find "${BACKUP_DIR}" -name "files-*.tar.gz" -mtime +${RETENTION_DAYS} -delete
# 5. Уведомление в Telegram о статусе
curl -s "https://api.telegram.org/bot${TG_BOT_TOKEN}/sendMessage" \
-d "chat_id=${TG_CHAT_ID}" \
-d "text=Backup OK at ${TIMESTAMP} — $(du -sh ${BACKUP_DIR} | cut -f1)"
Раз в две недели я сам тестирую restore из S3-бэкапа в изолированной среде — это единственный способ убедиться, что бэкапы рабочие. Не тестируешь — не имеешь.
Мониторинг 24/7 через Prometheus + Telegram
На отдельной виртуалке Selectel поднял Prometheus + Alertmanager + Grafana, настроил blackbox-exporter для проверки доступности сайта с трёх точек (Москва, Питер, Нидерланды через наш VPS). Алерты в Telegram дежурный канал ITfresh при простое больше 60 секунд.
# prometheus.yml — фрагмент
scrape_configs:
- job_name: 'blackbox-clinic'
metrics_path: /probe
params:
module: [http_2xx]
static_configs:
- targets:
- https://clinic.ru/
- https://clinic.ru/api/booking/check-slot/
- https://clinic.ru/wp-login.php
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: instance
- target_label: __address__
replacement: localhost:9115
# alertmanager rules
groups:
- name: clinic_critical
rules:
- alert: ClinicDown
expr: probe_success{job="blackbox-clinic"} == 0
for: 60s
labels:
severity: critical
annotations:
summary: "Сайт клиники недоступен с {{ $labels.instance }}"
- alert: ClinicSlowResponse
expr: probe_duration_seconds{job="blackbox-clinic"} > 3
for: 5m
labels:
severity: warning
Что мы поняли про российские хостинги в 2026
За 15 лет в IT-аутсорсе в Москве я видел эволюцию российского хостинга от «один поднял VDS на коленке» до серьёзных облачных провайдеров. К 2026 году расклад такой.
Топ для критичных сервисов
Yandex Cloud — флагман российского облака, стабильная сеть, хорошая защита от DDoS на уровне инфраструктуры, прогнозируемые цены. У нас там живут резервные шлюзы и Object Storage у трёх клиентов. Selectel — для VDS и dedicated, отличный аптайм, разумные цены, нормальная техподдержка. Использую как основной провайдер для большинства корпсайтов клиентов. VK Cloud — конкурентоспособный по цене, неплохая дока, но техподдержка медленнее, чем у Selectel. Cloud.ru (бывший SberCloud) — корпоративный сегмент, высокий ценник, но сертификаты ФСТЭК и УЦ если кому-то это критично.
Шаред-хостинг и небольшие провайдеры
Reg.Ru, Beget, Sprinthost — нормальная разметка для лендингов, малых корпоративных сайтов, сайтов-визиток. Ставить туда EMR-систему клиники, биллинг или критичный 1С-сервис — не стоит. FirstVDS, Timeweb, RuVDS — VDS сегмента «дёшево и под себя», для тестовых стендов и личных сайтов разработчиков. Aeza — отдельный кейс: дешёвая, в основном европейская инфраструктура, но репутация у разных клиентов очень разная.
Кого мы не рекомендуем
Без названий, но по характеристикам: провайдеры, которые: не отвечают на abuse-репорты в течение 72 часов; не поддерживают IPv6 в 2026 году; имеют публично известные случаи длительного простоя без компенсаций; работают по предоплате на год вперёд без возможности возврата. Таких в реестре RIPE десятки.
Цифры проекта и история одного писка в 4 утра
Полный пересбор защиты после инцидента занял две рабочих недели. Стоимость: 96 000 ₽ за инженерные работы (28 часов на проектирование, миграцию, настройку, тесты), 4 600 ₽/мес на новый хостинг и Cloudflare Pro, 6 000 ₽/мес на сопровождение и мониторинг. Сравнили с альтернативой: «купить корпоративный антиDDoS у Stack-Group за 18-25 тысяч в месяц» — такой бюджет клиника не потянула, наша схема через CDN+VDS оказалась в 4 раза дешевле.
Самый драматичный момент случился через месяц после внедрения. Telegram-канал мониторинга в 4:12 утра выплюнул алерт «ClinicDown». Я вскочил, открыл ноутбук, прокинулся через VPN в Selectel — сайт работал. Проверил мониторинг — действительно, на 90 секунд была недоступность с проверки из Нидерландов. Оказалось — у Selectel в 4:10 был кратковременный сбой на одном из коммутаторов, восстановили за 92 секунды. Реальные пользователи (которых ночью на сайте было 2-3 человека) получили обычный «попробуйте через минуту». Алерт сработал ровно так, как задуман — мне за 5 минут до восстановления уже был чёткий план, что делать. С тех пор у меня к Selectel доверия только больше: они не скрывают мелкие сбои, и инфраструктура восстанавливается без потери данных.
FAQ: что чаще всего спрашивают клиенты
Какой хостинг сейчас выбирать в России для бизнес-сайта?
По нашему опыту 2024-2026 годов: для критичных сервисов — Я.Облако, VK Cloud, Selectel, Cloud.ru. У них стабильная сеть, разумная DDoS-защита по умолчанию, нормальная техподдержка. Шаред-хостинг Reg.Ru, Beget, FirstVDS — годятся для лендингов и небольших корпоративных сайтов, но не для важных бизнес-приложений. DDoS-Guard, Stack-Group — отдельная история для специализированных задач.
Что делать, если на ваш сайт пошёл DDoS?
Первый шаг — связаться с хостером, у нормальных провайдеров есть встроенный DDoS-фильтр L3-L4, который активируется по запросу. Второй — переключить трафик через CDN с DDoS-защитой (Cloudflare, Selectel CDN, Я.Cloud CDN). Третий — если атака L7 (HTTP-flood) — настроить rate-limiting на nginx и WAF (например, ModSecurity с правилами OWASP CRS). На пике крупной атаки нужно действовать в первые 15 минут, иначе репутация сервиса страдает быстрее, чем доступность.
Можно ли защититься от DDoS бесплатно?
Полностью — нет. Бесплатный Cloudflare и базовая DDoS-защита у Selectel закроют 90% мелких атак (до 1-5 Gbps), которые делают подростки через стрессеры. От серьёзных атак (10+ Gbps, ботнеты IoT) нужна платная защита — от 1 500 ₽/мес у Cloudflare Pro до 15-30 тысяч у российских специализированных провайдеров. Бизнесу выгоднее заплатить за защиту, чем выгребать последствия одного успешного DDoS.
Что такое стрессер и насколько это серьёзная угроза?
Стрессер — это сервис, продающий DDoS-атаки в розницу: 200-500 ₽ за 10 минут атаки на любой адрес. Их клиенты — подростки, конкуренты, шантажисты. Угроза реальная: за 200 ₽ ваш сайт могут положить на полчаса, а у нас на практике клиента пытались таким образом шантажировать раз в три недели. Защита через CDN с фильтрацией закрывает 95% таких атак автоматически.
Сколько стоит защитить периметр сайта клиники у вас?
Базовая защита для бизнес-сайта 2-5 страниц + админка: настройка Cloudflare с WAF-правилами, перенастройка nginx, бэкапы 3-2-1, мониторинг — 12-15 рабочих часов инженера, 60-75 тысяч рублей. Дальше Cloudflare Pro — 1 500 ₽/мес, мониторинг — 6 000 ₽/мес. Для клиники с EMR-системой — 95-120 тысяч за внедрение комплекса с резервным каналом.
Итог
Защита периметра — это не один большой бронежилет, это набор прозрачных слоёв: правильный хостинг, CDN с WAF, бэкапы 3-2-1, мониторинг, понятный план действий на момент атаки. Для медицинской клиники в Москве это окупилось 96 000 ₽ единовременно и 10 600 ₽/мес — против шантажа с 0,008 BTC и потенциальной потери данных пациентов, которая стоила бы клинике лицензии. Главный вывод после инцидента, который директор клиники повторяет на встречах с коллегами: «Безопасность дешевле, чем последствия её отсутствия. Только её должны делать те, кто умеет — а не сам сисадмин в свободное от поддержки 1С время».
Похожая задача в вашей компании?
Расскажите, что у вас сейчас — пришлю план работ и оценку в течение рабочего дня.
Написать в Telegram или +7 903 729-62-41
Семёнов Е.С., руководитель ITfresh