Перейти к содержимому
WebShield Docs

Атакуют напрямую по IP сервера

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

Проксирование убирает адрес сервера из DNS, но не меняет его. Если адрес стал известен раньше или утёк другим путём, к серверу можно обратиться напрямую — мимо сигнатур, лимитов, банов и проверки браузера. Один из признаков: в Статистике спокойно, а сервер нагружен.

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

Что получится: сервер отвечает только на запросы, пришедшие через нас; прямое обращение получает отказ, не дойдя до приложения. Понадобится: доступ к конфигурации веб-сервера и запасной вход на сервер — SSH или панель хостинга. Время: 20–30 минут.

Сравните лог сервера со Статистикой за тот же час. Если запросов у вас заметно больше, чем мы передали серверу, — лишнее пришло мимо нас. Быстрая проверка с любой машины:

Terminal window
curl -sk -o /dev/null -w '%{http_code}\n' https://АДРЕС_СЕРВЕРА/ -H 'Host: example.com'

Ответ 200 — сайт открывается напрямую, и закрывать есть что.

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

  • Записи DNS. Поддомены mail, ftp, cpanel, dev, old, которые смотрят на тот же сервер без проксирования. Проверьте каждую A/AAAA в зоне.
  • Почта. Письма, которые сайт отправляет сам — регистрация, сброс пароля, заказы, — несут адрес сервера в заголовках. Отправляйте их через внешний SMTP-сервис.
  • Сертификат на голом IP. Если сервер отвечает по https://АДРЕС/ вашим сертификатом, поисковики по сертификатам (Censys, Shodan) могут связать адрес с доменом. Настройте сервер так, чтобы по IP без имени он не отдавал ничего.
  • История DNS. Сервисы истории DNS помнят, куда домен указывал до подключения к нам. Это не исправить — только сменить адрес.
  • Исходящие запросы. Вебхуки, проверка ссылок, загрузка картинок по URL — всё, что сервер скачивает по просьбе посетителя, показывает адрес тому, кто об этом попросил.

К каждому запросу на ваш сервер мы добавляем заголовок с секретом хоста:

X-WebShield-Origin-Token: wso_…

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

Значение — в кабинете: Хосты → хост → Доступ только через WebShield. У каждого хоста оно своё.

Перед правкой убедитесь, что в DNS у всех имён сайта включено проксирование: иначе вы закроете сайт от собственных посетителей.

nginx — в блоке server сайта:

if ($http_x_webshield_origin_token != "wso_ВАШ_ТОКЕН") { return 444; }

444 закрывает соединение молча, не тратя на ответ ни байта. Применить: nginx -t && systemctl reload nginx.

Caddy:

example.com {
@direct not header X-WebShield-Origin-Token "wso_ВАШ_ТОКЕН"
respond @direct 403
reverse_proxy localhost:3000
}

Apache — в конфигурации сайта или .htaccess:

<If "%{HTTP:X-WebShield-Origin-Token} != 'wso_ВАШ_ТОКЕН'">
Require all denied
</If>

IIS, Traefik, HAProxy и проверка в коде приложения — в справке Доступ к серверу только через WebShield.

Сертификат Let’s Encrypt на сервере продолжит продлеваться: проверка приходит на ваш домен, то есть к нам, и мы передаём её серверу с тем же заголовком. Исключение для /.well-known/acme-challenge/ не нужно.

Секрет закрывает ваш сайт, но сервер по-прежнему отвечает на TLS-рукопожатие и выдаёт сертификат — по нему адрес и находят. Добавьте сайт по умолчанию, который ничего не показывает. Для nginx 1.19.4 и новее:

server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
ssl_reject_handshake on;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
return 444;
}

Теперь на https://АДРЕС/ сервер обрывает рукопожатие, не показывая сертификата.

Секрет отсекает запросы на уровне веб-сервера, а это уже после того, как соединение установлено. Против флуда, который забивает сам канал или сетевой стек, он не поможет: пакеты всё равно летят на ваш адрес. Если адрес известен атакующему, единственное надёжное средство — попросить у хостинга новый, прописать его в DNS у нас и никому больше не показывать. Проксирование спрячет его сразу.

Terminal window
# Напрямую — отказ (403 или оборванное соединение).
curl -sk -o /dev/null -w '%{http_code}\n' https://АДРЕС_СЕРВЕРА/ -H 'Host: example.com'
# Через нас — нормальный ответ.
curl -s -o /dev/null -w '%{http_code}\n' https://example.com/

000 в первой строке — это и есть оборванное соединение после 444.

Симптом Причина и решение
Сайт отвечает ошибкой всем Токен в конфиге не совпадает с кабинетом, взят у другого хоста или после Перевыпустить не обновлён на сервере.
Напрямую по-прежнему 200 Правка не применилась — проверьте конфиг (nginx -t) и перезагрузите веб-сервер — или стоит не в том блоке server.
Прямые запросы приходят на другой поддомен У каждого хоста свой секрет и свой блок server — закройте все имена, у которых есть проксирование.
Сам сервер не может обратиться к своему сайту Он ходит к себе напрямую, например через запись в /etc/hosts. Уберите её, чтобы запросы шли через нас, или разрешите 127.0.0.1 отдельным правилом.