Медовые ловушки для перечисления имен пользователей: сниппет Cloudflare для сканирования /u/*.json

Мой форум на Discourse подвергается этой безумной активности сканеров: бот перебирает список слов по пути /u/<имя>.json, собирает ответы 404 и выясняет, какие имена пользователей существуют. Каждый такой запрос стоит одного воркера Unicorn и бесплатно предоставляет сканеру ответ.

Я собрал небольшой фрагмент кода (Snippet) для Cloudflare, который перехватывает эти запросы на границе (edge) и возвращает правдоподобный, но фейковый профиль — код 200, стабильный id, производный от имени пользователя, дата регистрации, уровень доверия, количество постов, а также фейковый адрес электронной почты с трекерной строкой (canary string). Реальные посетители проходят насквозь нетронутыми: наличие cookie сессии, referer из того же сайта, заголовок Accept: text/html или ключ API означают «оставить этот запрос в покое». Origin никогда не видит этих запросов, поэтому изменение снижает нагрузку, а не увеличивает её.

Обработки запросов логируются в New Relic с указанием IP, ASN и названия сети, страны, города, расположения дата-центра edge, версии HTTP/TLS, user agent и проверяемого имени пользователя. Есть дашборд из одиннадцати виджетов, который можно импортировать, и запросы NRQL для анализа «кто продолжает возвращаться».

Один слот для фрагмента кода. Никаких KV, Worker, изменений на origin или блокировок.
У вас все еще есть 4 свободных слота, и их можно использовать с другими сайтами в вашей учетной записи.

Репозиторий: GitHub - hhftechnology/cloudflare-honeypot: Cloudflare Snippet honeypot for user-enumeration scans (/u/*.json): fake 200 profile, New Relic logging, zero origin load · GitHub

В документации описано правило Cloudflare (примечание: оператор matches доступен только на тарифе Business — используйте wildcard), импорт в New Relic (нужно заменить два плейсхолдера, иначе импорт завершится ошибкой) и нюансы для Discourse — включая случай, когда встроенная настройка hide user profiles from public является лучшим решением. Но для меня этот вариант не подошел.

Надеюсь, это кому-то поможет. Нагрузка на наш сервер снизилась в течение часа после развертывания.