DevOps

3x-UI не показывает трафик и статус с NGINX прокси

Настройка 3x-UI с промежуточным NGINX или HAProxy: включите proxy protocol v2, access.log в Xray, права доступа. Пошаговая диагностика, конфиги и чеклист для отображения трафика клиентов и статуса онлайн/оффлайн.

3x-ui не отображает трафик и статус клиентов при использовании промежуточного сервера

Ситуация

Так, у меня тут такая ситуация: есть схема подключения, где клиент подключается к серверу 1, а тот уже перенаправляет трафик на сервер 2, который выходит в интернет.

Конфигурация

На первом сервере настроен NGINX с такой конфигурацией:

nginx
load_module /usr/lib/nginx/modules/ngx_stream_module.so;

events {}

stream {
 upstream tcp_back {
 server <ip сервера 2>:443;
 }

 server {
 listen 443;
 proxy_pass tcp_back;
 proxy_protocol on;
 }
}

А на втором сервере стоит 3x-ui, причем с включенным proxy protocol.

Проблема

Вот в чем дело: 3x-ui видит реальные IP-адресов клиентов и даже может блокировать доступ, если с одного IP подключается несколько устройств. Но при этом:

  • Не отображается количество использованного трафика
  • Не показывается статус клиентов (онлайн/офлайн)

Попытка решения

Я попробовал использовать HAProxy с такой конфигурацией:

haproxy
frontend tcp_front
 bind *:443
 mode tcp
 default_backend tcp_back

backend tcp_back
 mode tcp
 server srv2 <ip сервера 2>:443 send-proxy

Но проблема осталась - 3x-ui все равно не отображает трафик и статус клиентов.

Вопрос

Так как же настроить этот промежуточный сервер (NGINX или HAProxy), чтобы 3x-ui наконец-то корректно показывал трафик и статус клиентов?

3x-UI обычно не показывает трафик и статус, когда промежуточный прокси не передаёт 3x-UI всю информацию о сессии: либо PROXY-протокол передан неправильно (версия/порядок), либо Xray не пишет или 3x-UI не читает access.log, из которого панель считает байты и offline/online. Решение — настроить фронт‑прокси так, чтобы он корректно отправлял PROXY (для TLS предпочтительна v2), включить в Xray access.log и в 3x-UI Enable Proxy Protocol, и обеспечить 3x‑UI доступ к файлу логов; ниже — подробные проверки и примеры конфигов для NGINX и HAProxy.


Содержание


Почему 3x-UI не отображает трафик и статус при проксировании

3x-UI рассчитывает трафик и статус клиентов по двум основным источникам: записям access.log Xray и событиям PROXY‑протокола, которые информируют панель о начале/конце соединения и реальном IP клиента. Если промежуточный сервер передаёт только IP, но не даёт панели доступа к логам или не вставляет PROXY‑заголовок корректно (в нужном месте и версии), то 3x-UI увидит IP, но не узнает, сколько байт прошло и когда соединение закрылось. Подробно это описано в официальной документации 3x-UI: Configuration.

Коротко возможные причины в вашем случае:

  • PROXY передаётся, поэтому вы видите реальный IP, но Xray не пишет access.log или 3x-UI не может его прочитать.
  • PROXY передаётся в неподходящей форме (v1/v2, не в начале потока) — для TLS часто требуется v2.
  • 3x-UI пытается получить статистику через RPC/Xray API и получает ошибку (см. сообщения вида “Failed to fetch Xray traffic…”) — значит проблема на уровне взаимодействия сервисов. Подробнее о типичных проблемах — Common questions and problems.

Пошаговая диагностика: что проверить в первую очередь

  1. Убедитесь в версии 3x-UI: нужна версия ≥ v1.7.0 для надёжной поддержки Proxy Protocol.
  2. Проверьте, что Xray действительно пишет access.log и где он находится (путь в config.json). Пример:
  • Откройте config.json Xray и убедитесь в секции log: { “access”: “/var/log/xray/access.log”, “loglevel”: “warning” }.
  1. Наблюдайте лог при подключении клиента:
  • sudo tail -F /var/log/xray/access.log
  • Сделайте тест‑подключение (с клиента через прокси) — должна появиться строка с байтами/временем.
  1. Посмотрите логи 3x-UI на предмет ошибок получения трафика (systemd / docker logs). Пример ошибки из сообщества: “Failed to fetch Xray traffic: rpc error…” — ссылка на обсуждение: https://qna.habr.com/q/1404630.
  2. Проверьте права на файл access.log: может быть, Xray пишет файл, но 3x-UI не имеет прав читать его.
  3. Снимите трафик tcpdump’ом на сервере 2, чтобы убедиться, что PROXY‑заголовок реально приходит первым байтом до TLS-handshake:
  • sudo tcpdump -s0 -A -i any ‘tcp port 443’ и посмотрите на начало соединения — для v1 вы увидите ASCII “PROXY”, для v2 — бинарный заголовок (не ASCII).
  1. Попробуйте временно подключиться напрямую к серверу 2 (обходя сервер 1). Если после прямого подключения трафик в 3x-UI отображается — значит проблема в промежуточном прокси.

Настройка NGINX (stream) для корректной передачи PROXY

Если вы используете stream (TCP pass‑through), то правильная конфигурация NGINX должна отправлять PROXY-заголовок к upstream. Пример корректного минимального конфига:

nginx
load_module /usr/lib/nginx/modules/ngx_stream_module.so;

events {}

stream {
 upstream tcp_back {
 server <IP_сервера_2>:443;
 }

 server {
 listen 443;
 proxy_pass tcp_back;
 proxy_protocol on; # отправка PROXY-протокола на сервер 2
 }
}

Пояснения и нюансы:

  • Директива proxy_protocol on в stream‑server инструктирует NGINX отправить PROXY‑заголовок upstream. Upstream (Xray/3x-UI) должен быть настроен на приём PROXY.
  • Если NGINX принимает PROXY от предыдущего прокси, используют listen 443 proxy_protocol; — это другое направление (приём).
  • Если вы делаете HTTP‑reverse (TLS терминируется на nginx), то вместо PROXY нужно прокидывать заголовки: proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; — об этом подробно в практическом примере проксирования подписок: https://ivanbayan.com/index.php/2024/12/31/how-to-proxy-a-3x-ui-subscription-service-via-nginx-on-a-different-host/.

Если вы уже видите реальные IP в 3x-UI, но не трафик — скорее всего Xray не пишет access.log (или 3x-UI не видит файл). Проверьте пункт про access.log ниже.


Настройка HAProxy: send-proxy-v2 для TLS

Если вы используете HAProxy как TCP‑прокси, рекомендую отправлять PROXY v2 при работе с TLS, потому что v2 бинарный и лучше совместим с TLS‑handshake (и поддерживает TLV):

Пример конфига:

haproxy
global
 log /dev/log local0

defaults
 log global
 mode tcp
 option tcplog
 timeout connect 10s
 timeout client 1m
 timeout server 1m

frontend tcp_front
 bind *:443
 mode tcp
 default_backend tcp_back

backend tcp_back
 mode tcp
 server srv2 <IP_сервера_2>:443 send-proxy-v2

Ключевые замечания:

  • Для TLS лучше send-proxy-v2; send-proxy (v1) может работать, но иногда вызывает несовместимости. Подробно: https://www.haproxy.com/documentation/haproxy-configuration-tutorials/proxying-essentials/client-ip-preservation/enable-proxy-protocol/
  • Если перед HAProxy стоит ещё один прокси, и он уже шлёт PROXY, HAProxy должен быть настроен на его приём (bind ... accept-proxy) или наоборот — цепочка PROXY должна быть согласована.
  • После изменения конфигурации HAProxy перезапустите сервис.

Настройка Xray и 3x‑UI: access.log, inbound proxyProtocol и права

  1. Включите access.log в config.json Xray и укажите путь:
json
"log": {
 "access": "/var/log/xray/access.log",
 "error": "/var/log/xray/error.log",
 "loglevel": "warning"
}

3x‑UI читает этот файл для подсчёта трафика и статуса — проверьте это в документации 3x-UI: https://github.com/MHSanaei/3x-ui/wiki/Configuration.

  1. В inbound (порт/протокол, который обрабатывает Xray) включите приём PROXY, если вы посылаете PROXY с фронта. В GUI 3x-UI это обычно опция Inbound → Settings → Enable Proxy Protocol; в raw config можно увидеть ключ вроде "proxyProtocol": true — убедитесь, что опция применена и Xray перезапущен.

  2. Права на файл access.log: 3x‑UI должен иметь доступ на чтение. Варианты:

  • Дать общий доступ: sudo chmod 644 /var/log/xray/access.log (быстро, но менее безопасно).
  • Лучше: создать группу, дать файлу группу и добавить в неё пользователя процесса 3x-UI; либо использовать ACL:
  • sudo chgrp xraylogs /var/log/xray
  • sudo usermod -aG xraylogs <пользователь_3xui>
  • sudo chmod 750 /var/log/xray && sudo chmod 640 /var/log/xray/access.log
  • или sudo setfacl -m u:<пользователь_3xui>:r /var/log/xray/access.log
  1. SELinux/AppArmor: если включены, проверьте, не блокируют ли они доступ 3x‑UI к логу. Логи audit помогут выяснить это.

  2. Перезапустите сервисы: systemctl restart xray и systemctl restart 3x-ui (или docker restart, если в контейнере).

Если после этого трафик по‑прежнему не отображается, проверьте 3x-UI логи на предмет ошибок обращения к access.log или RPC ошибок — обсуждение похожих ошибок здесь: https://qna.habr.com/q/1404630.


Отладка: команды и признаки ошибок

  • Просмотр access.log в реальном времени:
    sudo tail -F /var/log/xray/access.log
    — при подключении вы должны увидеть запись с количеством байтов.

  • Снятие пакетов для проверки PROXY:
    sudo tcpdump -s0 -A -i any ‘tcp port 443 and host <IP_клиента или IP_сервера_2>’
    — ищите ASCII “PROXY” в начале (v1) или бинарный заголовок (v2).

  • Логи 3x-UI:

  • systemctl status 3x-ui; journalctl -u 3x-ui -n 200

  • или docker logs если панель в контейнере.

  • Проверка прав файла:
    ls -l /var/log/xray/access.log
    getfacl /var/log/xray/access.log

  • Тест прямого подключения к серверу 2 (обходя прокси). Если трафик появляется — дело в прокси; если нет — дело в Xray/3x-UI (логах/прав).


Короткий чеклист для быстрого исправления

  • [ ] Обновить 3x-UI до версии ≥ v1.7.0.
  • [ ] На фронт‑прокси (NGINX/HAProxy) включить отправку PROXY-заголовка; для TLS — использовать send-proxy-v2 / эквивалент.
  • [ ] В Xray config.json включить access.log и установить понятный путь (/var/log/xray/access.log).
  • [ ] В 3x-UI включить Inbound → Enable Proxy Protocol и указать путь к access.log (или убедиться, что панель видит файл).
  • [ ] Дать 3x-UI права читать access.log (группа/ACL).
  • [ ] Перезапустить Xray и 3x-UI; выполнить тест и смотреть tail / tcpdump.
  • [ ] Проверить логи 3x-UI на ошибки RPC/IO.

Источники

  1. https://github.com/MHSanaei/3x-ui/wiki/Configuration
  2. https://www.haproxy.com/documentation/haproxy-configuration-tutorials/proxying-essentials/client-ip-preservation/enable-proxy-protocol/
  3. https://ivanbayan.com/index.php/2024/12/31/how-to-proxy-a-3x-ui-subscription-service-via-nginx-on-a-different-host/
  4. https://qna.habr.com/q/1404630
  5. https://github.com/MHSanaei/3x-ui/wiki/Common-questions-and-problems
  6. https://www.vdsina.com/ru/qa/q/nastroyka-proksi-s-pomoshchyu-predustanovlennogo-3x-ui

Заключение

Ключ к решению — обеспечить 3x-UI два элемента: корректную передачу PROXY‑протокола от промежуточного сервера (для TLS — предпочтительна v2) и работающий, читаемый Xray access.log, из которого панель считает байты и состояние клиентов. Проверьте конфиги фронт‑прокси (NGINX stream proxy_protocol / HAProxy send-proxy-v2), включите access.log в Xray, дайте 3x-UI права на чтение и перезапустите сервисы — после этого трафик и онлайн/офлайн статусы должны заработать. Если хотите, пришлите конфиги NGINX/HAProxy и путь к access.log — помогу проверить конкретно.

Авторы
Проверено модерацией
Модерация
3x-UI не показывает трафик и статус с NGINX прокси