# Xray: что актуально и почему именно так

Сверено с `xtls.github.io` (актуальная схема конфигурации), документацией
Remnawave и поведением backend 3.4.x. Шаблоны лежат в `templates/xray/`,
пути к сертификатам совпадают с контрактом из README.

## 1. `network`, а не `method`

В новом синтаксисе Xray поле `streamSettings.network` переименовано в
`method`. Ядро принимает оба имени, но **панель Remnawave 3.4.x читает
именно `network`**: она разбирает профиль, чтобы сгенерировать хост и
подписку. Если оставить только `method`, панель не увидит транспорт.
Поэтому в наших шаблонах везде `network`, хотя документация XTLS пишет
`method`.

По той же причине транспорт TCP теперь называется `raw` (старое имя
`tcp` ядро ещё принимает). Панель 3.4.x понимает `raw`; на более старой
панели оставьте `tcp`.

## 2. REALITY

- `dest` переименован в `target`. Оба имени работают, но `target` —
  актуальное; `dest` остаётся алиасом.
- `spiderX` — клиентская настройка. В серверном инбаунде её нет, она
  попадает в ссылку/подписку. В старых конфигах она лежала на сервере и
  ничего не делала.
- `target` указывает на unix-сокет nginx (`/var/run/xray/nginx.sock`,
  `xver: 1`). Это даёт настоящий TLS-fallback: клиент без правильного
  REALITY-рукопожатия видит обычный сайт с валидным сертификатом ноды.
- RAW+REALITY должен работать с `flow: xtls-rprx-vision`, иначе внутренний
  TLS виден как TLS-in-TLS. Flow задаётся у клиента (панель или шаблон
  подписки); для XHTTP он не используется.
- `mldsa65Seed`/`mldsa65Verify` — пост-квантовая часть REALITY. Если
  панель их генерирует, оставьте как есть; вручную добавлять не нужно.

## 3. XHTTP

- Актуальный профиль — только `path`. Поле `mode` не задаём: ядро само
  выбирает режим. `packet-up`/`stream-up` включают только при известной
  необходимости (например, специфичный CDN).
- XHTTP пришёл на замену gRPC: меньше зависимостей, лучше работает через
  CDN и HTTP/2-прокси.
- Оба инбаунда на одном 443/tcp: nginx stream слушает `0.0.0.0:443`,
  RAW+REALITY — `127.0.0.1:8444`, XHTTP — `127.0.0.1:10444`. nginx на unix-сокете
  терминирует TLS и по пути `/media/stream` проксирует в XHTTP.
- Клиент XHTTP ходит на 443/tcp с `security: tls`, ALPN h2 и тем же SNI;
  REALITY не распознаёт его как VLESS и отдаёт nginx, который разводит
  трафик по пути. Отдельный порт 2053 больше не открывается.

## 4. gRPC и Hysteria2 убраны

В новых профилях нет ни gRPC (8443/tcp), ни Hysteria2 (443/udp). Причины:

- gRPC вытеснен XHTTP; тех же задач он решает лучше и без отдельного порта;
- Hysteria2 на слабом VPS даёт заметную UDP-нагрузку, а если провайдер
  режет UDP/443, инбаунд просто не поднимется. Меньше портов — меньше
  причин для разбора в логах.

Старые клиенты на gRPC/hysteria2 продолжат работать, пока соответствующий
инбаунд остаётся в профиле панели. Для новых подключений его не добавляйте.

### Как вернуть Hysteria2 позже

Если понадобится, добавьте в профиль отдельный инбаунд (порт 443/udp):

```json
{
  "tag": "HYSTERIA2",
  "listen": "0.0.0.0",
  "port": 443,
  "protocol": "hysteria",
  "settings": {
    "version": 2,
    "clients": []
  },
  "streamSettings": {
    "network": "hysteria",
    "security": "tls",
    "tlsSettings": {
      "alpn": ["h3"],
      "certificates": [{
        "certificateFile": "/opt/remnawave/tls/<node-domain>/live/fullchain.pem",
        "keyFile": "/opt/remnawave/tls/<node-domain>/live/privkey.pem"
      }]
    },
    "hysteriaSettings": { "version": 2 }
  },
  "sniffing": {
    "enabled": true,
    "destOverride": ["http", "tls", "quic"]
  }
}
```

Пустой `clients` панель заполнит сама (`auth` + `email`) и сгенерирует
hysteria2-ссылки. Сверьте имена полей со своей версией панели: в одних
сборках это `clients`, в других `users`. Затем откройте 443/udp в
nftables (`allow udp 443` в `/etc/remnawave/firewall.rules`) и
перезапустите ноду. Ничего, кроме этого инбаунда и правила firewall,
менять не нужно.

## 5. Sniffing

Во всех инбаундах включён `destOverride: ["http", "tls", "quic"]`. Это
нужно для доменной маршрутизации и для встроенного Torrent Blocker
(плагин смотрит на sniffing-результат). Без `quic` не будет виден
QUIC-трафик.

## 6. Torrent Blocker

Встроенный плагин ноды (Remnawave Node ≥ 2.7, Xray ≥ 26.3.27) блокирует
торренты через nftables:

- контейнеру ноды нужен `cap_add: NET_ADMIN` (в нашем compose он есть);
- плагин сам добавляет routing-правило на bittorrent и webhook-outbound,
  поэтому **вручную правило `protocol: bittorrent` добавлять нельзя** —
  мы убрали его из старых шаблонов;
- на официальном ядре обнаруживается не весь трафик: по документации
  плагина — порядка 10–30%, на практике 30–40%. Блокируется IP пира,
  панель получает уведомление;
- на 2 ГБ RAM это дешевле отдельного Suricata/nDPI (ezhik guard),
  который для слабой ноды тяжёл.

Форк Jolymmiles/Xray-core расширяет именно слой sniffing, а не только
добавляет smux. С v26.8.21 в нём есть детект BitTorrent TCP handshake,
uTP, DHT и UDP-трекеров (BEP 15), а v26.8.25 ужесточил UDP-правила и
убрал ложные срабатывания на DNS, STUN, TURN и игровом трафике. Поэтому
`remnanode-smux` с фиксированным тегом — не «то же самое плюс mux», а
заметно более широкое покрытие на уровне Xray.

Границы остаются: MSE/зашифрованный handshake и HTTPS-трекеры по
открытым байтам не видны. Хостовый DPI (`vibehost-guard`/nDPI) может
добавить слой, но это отдельные iptables-правила, ложные срабатывания и
проверка совместимости с nftables/Docker; включать его имеет смысл только
после живого замера, сколько именно ловит форк.

## 6.1 Журнал подключений

Структурированный `log.outputs` есть только в форке Jolymmiles. В
`templates/xray/node-reality-all.json` уже включён файл
`/var/log/remnanode/xray.jsonl`:

- `events: ["general", "access", "dns", "internal"]`, `format: "json"`,
  `level: "info"` — иначе access-события отфильтруются;
- `backpressure: "drop_new"` — диск не тормозит трафик, но при
  переполнении очереди записи теряются;
- compose монтирует `/var/log/remnanode` внутрь контейнера, logrotate
  ротирует `*.jsonl` ежедневно;
- nginx stream отправляет PROXY v1 (`proxy_protocol on`), а REALITY
  inbound принимает его (`sockopt.acceptProxyProtocol`). Без этой пары
  в `source` будет `127.0.0.1`, а не IP клиента. Менять их нужно вместе:
  если nginx уже шлёт PROXY, а профиль его не принимает, REALITY
  перестанет пускать клиентов.

Запись содержит `timestamp`, `source` (IP клиента), `destination`,
`network`, `status`, `inbound`, `outbound`, `email` (ID пользователя).
Байт и длительности сессии в ней нет — это факт соединения, а трафик
по пользователю и ноде берётся из БД панели. Ежедневный шифрованный
экспорт обоих источников: [backup.md](backup.md).

Ограничение: XHTTP-инбаунд (`VLESS-XHTTP`) nginx проксирует по HTTP,
поэтому Xray видит источник как `127.0.0.1`. Реальный IP в логе даёт
REALITY-путь; если журнал нужен по всем подключениям, XHTTP лучше не
использовать или считать его вспомогательным.

## 7. nginx впереди, Xray за ним

```
nginx stream (443/tcp) --> 127.0.0.1:8444 Xray REALITY
                              |-- auth --> VLESS RAW
                              `-- no auth --target--> /var/run/xray/nginx.sock
                                                        |
                                                        v
                                              nginx TLS на unix-сокете
                                              сертификат, decoy, /media/stream
```

nginx первым принимает TCP на 443. Для сканера TLS-рукопожатие всё равно
обслуживает nginx: REALITY без валидного auth просто проксирует ClientHello
в nginx, поэтому сертификат, ALPN и поведение — nginx. Xray на loopback
виден только клиенту с правильным REALITY-ключом.

`templates/node/selfsteal.conf` содержит ровно два сервера: 80 для ACME
и редиректа, и unix-socket TLS для fallback. В TLS-сервере два location:
`/media/stream` уходит на `127.0.0.1:10444`, всё остальное — в decoy.
Наружу открыт только 443/tcp; Xray слушает `127.0.0.1:8444` и
`127.0.0.1:10444`.

Один сокет обслуживает оба имени: nginx выбирает `selfsteal` или `docs`
по SNI. Заглушка отвечает TLS 1.2/1.3, отдаёт HSTS, а 80 закрыт
301-редиректом кроме ACME.

## 8. Подмена ядра образом

По умолчанию `node_setup.sh` ставит `ghcr.io/legiz-ru/remnanode-smux` с
фиксированным тегом (`v3.4.4-26.11.1-1424`). Это форк ядра
Jolymmiles/Xray-core: расширенный sniffing BitTorrent и smux. Официальный
`remnawave/node` можно вернуть через `--node-image` (или `NODE_IMAGE`).

- Указывайте **фиксированный тег**, не `latest`: обновление ядра должно
  быть осознанным, откат — сменой одной строки.
- В панели поле `core` оставьте пустым, иначе панель сама подменит ядро
  внутри контейнера и `log.outputs` перестанет работать.
- Форк отстаёт от upstream. Перед обновлением проверьте, что в нём есть
  свежие исправления безопасности.
