LIMB
Вход Регистрация

тема

[Статья] Как логировать реальный трафик на своём сайте (nginx + Telegram, без мусора и ботов)

Asmodeith · · 1 ответов · 411 просмотров

Всем привет!
Хочу с вами поделиться методом логирования трафика на ваших проектах (сайты, лендинги, фишинги)
Я не видел статей на эту тему нигде (хотя не исключаю что они есть)

Каждый раз, когда мы запускаем любой проект, нам необходимо иметь полное логирование по входящему трафику, банально для формирования и отслеживания метрик, а также для ряда других вещей.
Часто, необходимо понять, кто реально заходит на проект, отсеять ботов, получать события в реальном времени.
Стандартные решения не подходят, потому что:


Режутся прокси/антидетектом
Не дают сырой и прямой доступ к данным
Легко палятся


Бесспорно, существуют различные панельные агрегаторы по этой теме, мне почему-то в голову сразу приходит яндекс директ и множество разных контор - но, разве кто-то хочет платить бабки ежемесячно за то, что можно сделать руками? Сомневаюсь

Специально для этого я создал скрипт отбивающий логи в тг о переходах на проект (логи можно настроить отбивать куда угодно, это не проблема, но фактически в 99% случаев логи нужны именно в телеграме)

Содержание статьи будет следующим:

1. Введение
2. Архитектура решения
3. Установка и настройка nginx логирования
4. Установка и настройка Python-скрипта.
4. Разбор скрипта
5. Итог.

Схема работы скрипта следующая:

Юзер на проекте - nginx - лог - скрипт - фильтрация - очередь - Telegram лог.

nginx - пишет JSON лог
Python - анализирует
Telegram - уведомления



Спойлер: Лог выглядит вот так
":globe_with_meridians: Домен: yanemysor.com
:round_pushpin: IP: 51.77.211.39
:clock3: Время: 2026-04-03 17:23:32 UTC
:desktop: User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36"

Не удалось прогрузить медиа




Спойлер: Установка серверной части nginx
Нам необходим сервер VPS (я использую Debian 12 через Putty для терминала и WinSCP для windows-подобного проводника у сервера, но вы можете использовать то, к чему привыкли), статья подразумевает что у вас на нём уже стоит сайт, но можно делать всё и снуля тоже.
Ключевое на VPS: наличие вирт. окружения с нужным библиотеками под запуск вашего сайта и nginx. Первое вы делаете сами, это не тема статьи, второе объясняю ниже.

Установка nginx:
Пишем в терминал поочередно

sudo apt update - обновление пакетов (если вы пользователь root, то sudo убираем)
sudo apt install nginx -y - установка nginx
sudo systemctl status nginx - проверяю статус, должно быть "active (running)
(Если используется фаерволл, то лучше его вырубить, а если есть потребность в этом, то просто открываете порты 80 и 443, т.к. они нужны для работы nginx)


nginx установлен

Теперь надо настроить nginx-конфиг для логирования трафика


Переходим по этому пути /etc/nginx и находим этот файл nginx.conf
Открываем его и находим строку "http {"
Сразу после неё (в скобках. см скрин) вставляем 
"log_format redirect_log escape=json
  '{"time":"$time_iso8601",'
   '"ip":"$remote_addr",'
   '"domain":"$host",'
   '"agent":"$http_user_agent"}';"

 
Затем находим "access_log /var/log/nginx/access.log;"
И ниже неё добавляем "access_log /var/log/nginx/redirect.log redirect_log;"

В итоге получается вот так:

"http {

    log_format redirect_log escape=json
      '{"time":"$time_iso8601",'
       '"ip":"$remote_addr",'
       '"domain":"$host",'
       '"agent":"$http_user_agent"}';

    ...

    access_log /var/log/nginx/access.log;
    access_log /var/log/nginx/redirect.log redirect_log;

    ...
}"


Два примера правильны конфигов!

Первый, на нулевом сервере где только что установлен nginx.

Спойлер: Первый вариант
Code:
user www-data;
worker_processes auto;
pid /run/nginx.pid;
error_log /var/log/nginx/error.log;
include /etc/nginx/modules-enabled/*.conf;


events {
    worker_connections 768;
    # multi_accept on;
}


http {
      


   log_format redirect_log escape=json
   '{"time":"$time_iso8601",'
   '"ip":"$remote_addr",'
   '"domain":"$host",'
   '"agent":"$http_user_agent"}';
      
    ##
    # Basic Settings
    ##


    sendfile on;
    tcp_nopush on;
    types_hash_max_size 2048;
    # server_tokens off;


    # server_names_hash_bucket_size 64;
    # server_name_in_redirect off;


    include /etc/nginx/mime.types;
    default_type application/octet-stream;


    ##
    # SSL Settings
    ##


    ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
    ssl_prefer_server_ciphers on;


    ##
    # Logging Settings
    ##


    access_log /var/log/nginx/access.log;
        access_log /var/log/nginx/redirect.log redirect_log;


    ##
    # Gzip Settings
    ##


    gzip on;


    # gzip_vary on;
    # gzip_proxied any;
    # gzip_comp_level 6;
    # gzip_buffers 16 8k;
    # gzip_http_version 1.1;
    # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;


    ##
    # Virtual Host Configs
    ##


    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}




#mail {
#    # See sample authentication script at:
#    # http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript
#
#    # auth_http localhost/auth.php;
#    # pop3_capabilities "TOP" "USER";
#    # imap_capabilities "IMAP4rev1" "UIDPLUS";
#
#    server {
#        listen     localhost:110;
#        protocol   pop3;
#        proxy      on;
#    }
#
#    server {
#        listen     localhost:143;
#        protocol   imap;
#        proxy      on;
#    }
#}

Второй вариант, где конфиг собран по самому лютому фаршу (не все элементы из этого конфига относятся к этому скрипту, но он рабочий)
Спойлер: Второй вариант
Code:
user www-data;
worker_processes auto;
pid /run/nginx.pid;


# РћСЃРЅРѕРІРЅРѕР№ error_log
error_log /var/log/nginx/error.log;


# Модули
include /etc/nginx/modules-enabled/*.conf;


events {
    worker_connections 1024;
    multi_accept on;
}


http {
    ##
    # Базовые настройки
    ##
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;


    types_hash_max_size 2048;
    server_tokens off;
    client_max_body_size 100M;


    server_names_hash_bucket_size 128;


    include /etc/nginx/mime.types;
    default_type application/octet-stream;


    ##
    # Реальный IP за Cloudflare
    ##
    real_ip_header CF-Connecting-IP;
    set_real_ip_from 173.245.48.0/20;
    set_real_ip_from 103.21.244.0/22;
    set_real_ip_from 103.22.200.0/22;
    set_real_ip_from 103.31.4.0/22;
    set_real_ip_from 141.101.64.0/18;
    set_real_ip_from 108.162.192.0/18;
    set_real_ip_from 190.93.240.0/20;
    set_real_ip_from 188.114.96.0/20;
    set_real_ip_from 197.234.240.0/22;
    set_real_ip_from 198.41.128.0/17;
    set_real_ip_from 162.158.0.0/15;
    set_real_ip_from 104.16.0.0/13;
    set_real_ip_from 104.24.0.0/14;
    set_real_ip_from 172.64.0.0/13;
    set_real_ip_from 131.0.72.0/22;


    # Локалки
    set_real_ip_from 127.0.0.1;
    set_real_ip_from 10.0.0.0/8;
    set_real_ip_from 172.16.0.0/12;
    set_real_ip_from 192.168.0.0/16;


    real_ip_recursive on;


    ##
    # Твой общий JSON-лог для других проектов (оставляем как было)
    ##
    log_format json_analytics escape=json
      '{"time":"$time_iso8601",'
       '"ip":"$realip_remote_addr",'
       '"domain":"$host",'
       '"path":"$request_uri",'
       '"agent":"$http_user_agent",'
       '"referer":"$http_referer",'
       '"method":"$request_method",'
       '"status":"$status",'
       '"bytes":"$body_bytes_sent",'
       '"forwarded_for":"$http_x_forwarded_for",'
       '"cf_connecting_ip":"$http_cf_connecting_ip",'
       '"cf_ipcountry":"$http_cf_ipcountry"}';


    access_log /var/log/nginx/access.log json_analytics;
    error_log  /var/log/nginx/error.log  warn;


    ##
    # TLS
    ##
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;


    ##
    # Сжатие
    ##
    gzip on;
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_buffers 16 8k;
    gzip_http_version 1.1;
    gzip_types
        text/plain
        text/css
        text/xml
        text/javascript
        application/json
        application/javascript
        application/xml+rss
        application/atom+xml
        image/svg+xml;


    ##
    # Кэш дескрипторов
    ##
    open_file_cache max=1000 inactive=20s;
    open_file_cache_valid 30s;
    open_file_cache_min_uses 2;
    open_file_cache_errors on;


    ##
    # Лимиты
    ##
    limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;


    ##
    # Твои существующие проекты
    ##
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;


    ##
    # === ВАЖНО: MirrorHub — объявляем формат логов ДО серверов ===
    ##
    include /etc/nginx/sites-available/mirrorhub.conf;


    ##
    # MirrorHub — карта доменов (используется скриптами/шаблонами по желанию)
    ##
    map $host $mirrorhub_hit {
        default 0;
        include /etc/nginx/mirrorhub/domains_map.conf;
    }


    ##
    # MirrorHub — per-domain конфиги (server{}), генерируются nginx_sync.py
    ##
    include /etc/nginx/sites-mirrorhub.d/*.conf;


    ##
    # (опционально) дефолт-заглушки
    ##
    # server {
    #     listen 80 default_server;
    #     server_name _;
    #     return 444;
    # }
    # server {
    #     listen 443 ssl default_server;
    #     server_name _;
    #     return 444;
    # }
}




Теперь прописываем
nginx -t
systemctl reload nginx (поочередно)

Если всё ок - значит вы всё правильно поставили

/var/log/nginx/redirect.log - теперь по этому пути при заходе на любой сайт, который у вас установлен через nginx (!!!), туда будет биться лог


Как теперь сделать чтобы всё это дело корректно в телеграм билось?
Нам нужен скрипт (скрипт можете увидеть ссылкой на гугл диск в самом низу статьи)

Для работы скрипта создаём стандартное вирт. окружение, в которое устанавливаем requests (pip install requests)

Перед запуском скрипта вам необходимо отредактировать код:


На 19 строке вставить свой бот токен от бота, который будет отбивать логи
на 20 строке вставить айди канала, в который логи будут приходить (добыть айди можно путём пересылки сообщения из канала в этот бот @LeadConverterToolkitBot , только предварительно обязательно сначала надо добавить бота, который будет отбивать логи, и дать ему права, затем уже брать айди.
Спойлер: Строки
TELEGRAM_BOT_TOKEN = os.getenv("TELEGRAM_BOT_TOKEN", "ваше значение").strip()
TELEGRAM_CHAT_ID = os.getenv("TELEGRAM_CHAT_ID", "ваше значение").strip()"
(лучше это делать в .env, но мне удобнее под такую задачу всё в одном файле хранить, для моих целей это не критично)
На 88 строке вставить http прокси (чтобы в телеграм отбивало без проблем логи, в связи с последними ограничениями)
Спойлер: Строка
PROXY = "ваше значение"





Затем заходим в телеграм, создаём канал и добавляем в него бота, бот токен которого указан в коде, и даём ему все админские права.
Не удалось прогрузить медиа



После этого можем запускать скрипт и у вас всё будет работать!

Спойлер: Разбор Python-скрипта
Скрипт написан на Python и выполняет несколько задач:

1. Читает лог nginx в реальном времени
2. Фильтрует шум и ботов
3. Убирает дубликаты
4. Отправляет события в Telegram


Ключевые части:

Чтение логов в реальном времени
Python:
for line in follow_file(NGINX_LOG_PATH):

Функция follow_file работает как tail -F:

Отслеживает файл логов
Автоматически подхватывает ротацию
Читает новые строки без перезапуска


Это позволяет получать события в реальном времени.

///

Парсинг JSON логов

Python:
obj = json.loads(line_stripped)

Nginx пишет лог в JSON, поэтому:

Каждая строка - это объект
Мы можем легко достать нужные поля

Если строка повреждена - она пропускается.


///

Извлечение реального IP

Python:
real_ip = extract_real_ip_from_obj(obj)

Функция проверяет несколько источников:

cf_connecting_ip - если используется Cloudflare
x-forwarded-for - если есть прокси
remote_addr - базовый IP

Это важно, потому что реальный пользователь часто скрыт за CDN или прокси.


Python:
if is_bot_user_agent(agent):
    continue

Скрипт отсекает:

Googlebot
GPTBot
Ahrefs
Сканеры
curl / python-requests

Это снижает шум и оставляет только реальных пользователей.

///

Антиспам по IP


Python:
if not limiter.allow(real_ip):
    continue

максимум N запросов за X секунд по одному IP
если превышено - события игнорируются


Это фактическая защита от:

Сканеров
Брутфорса
Флуда


///

Дедупликация

Python:
if deduper.is_duplicate(key):
    continue

Если событие уже было недавно:
Оно не отправляется повторно

Ключ строится из:

IP
домена
User-Agent

Это экономит лимиты Telegram и убирает дубли.

///


Worker (отправка)

Python:
worker = SendWorker(send_q, stop_event, SEND_DELAY_SEC)

Отдельный поток:

Берёт события из очереди
Отправляет в телегу
Делает задержку между отправками


///

Отправка в телегу

Python:
requests.post(...)

Реализовано:

Повторные попытки (retry)
Обработка rate limit (429)
Поддержка прокси



Формирование сообщения
Python:
build_msg(ev)

Формируется читаемый лог:

Домен
IP
время
User-Agent


Всё форматируется через HTML для телеги

///

Heartbeat (жив ли скрипт)


Скрипт периодически отправляет сообщение:

“логгер жив”



Итог по скрипту:

Скрипт решает сразу несколько задач

Сбор трафика в реальном времени
Фильтрация мусора
Защита от флуда
Стабильная доставка в телегу


При этом он:

Не требует тяжёлых библиотек
Легко масштабируется
Работает на любом VPS




P.S.

У данного скрипта существует масса модификаций. Если статья зайдёт, поставьте в курс и я сделаю продолжение статьи с модификациями.


Скрипт Python
👍26 🔥3 😮4 🤔2
ОтветAsmodeith

яндекс директ

Через яндекс директ запускают рекламу. Для анализа трафика используется яндекс метрика и она бесплатная. Также ты можешь через claude[.]ai написать свою собственную метрику подключив скрипт к cloudflare (бесплатно) и выгружать по api информацию о кликах по твоему офферу.

Не удалось прогрузить медиа


ОтветAsmodeith

Стабильная доставка в телегу

Сейчас телеграм крайне не стабилен особенно из РФ. Также его могут и поблочить другие страны. Аккаунт твой могут снести с ботом, лучше делать решение через cloudflare и оттуда выгружать необходимые тебе данные.

Обращаться будешь сюда: https://api.cloudflare.com/client/v4/accounts/$CF_ACCOUNT/analytics_engine/sql 

через sql запросы дергать нужную инфу. Разве не удобнее?

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

Пишите еще, в следующий раз может получится пройти требования и мы оплатим вашу статью!
👍1

Гостевой просмотр. Чтобы отвечать и ставить реакции, войдите или зарегистрируйтесь.