From 970313edcbbeaf36444e34cdd7e1dff585b8c734 Mon Sep 17 00:00:00 2001 From: miniusercoder Date: Wed, 8 Apr 2026 19:17:09 +0300 Subject: [PATCH 1/5] add documentation for Xray double hop setup --- docs/Setup_examples/XRAY_DOUBLE_HOP.en.md | 298 ++++++++++++++++++++++ docs/Setup_examples/XRAY_DOUBLE_HOP.ru.md | 296 +++++++++++++++++++++ 2 files changed, 594 insertions(+) create mode 100644 docs/Setup_examples/XRAY_DOUBLE_HOP.en.md create mode 100644 docs/Setup_examples/XRAY_DOUBLE_HOP.ru.md diff --git a/docs/Setup_examples/XRAY_DOUBLE_HOP.en.md b/docs/Setup_examples/XRAY_DOUBLE_HOP.en.md new file mode 100644 index 0000000..44c22ff --- /dev/null +++ b/docs/Setup_examples/XRAY_DOUBLE_HOP.en.md @@ -0,0 +1,298 @@ + + +## Concept +- **Server A** (_e.g., RU_):\ + Entry point, accepts Telegram proxy user traffic via **HAProxy** (port `443\tcp`)\ + and sends it through the local **Xray** client (port `10443\tcp`) to Server **B**.\ + Public port for HAProxy clients — `443\tcp` +- **Server B** (_e.g., NL_):\ + Exit point, runs the **Xray server** (to terminate the tunnel entry point) and **telemt**.\ + The server must have unrestricted access to Telegram Data Centers.\ + Public port for VLESS/REALITY (incoming) — `443\tcp`\ + Internal telemt port (where decrypted Xray traffic ends up) — `8443\tcp` + +The tunnel works over the `VLESS-XTLS-Reality` (or `VLESS/xhttp/reality`) protocol. The original client IP address is preserved thanks to the PROXYv2 protocol, which HAProxy prepends before passing to Xray, and which transparently reaches telemt. + +--- + +## Step 1. Setup Xray Tunnel (A <-> B) + +You must install **Xray-core** (version 1.8.4 or newer recommended) on both servers. +Official installation script (run on both servers): +```bash +bash -c "$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)" @ install +``` + +### Key and Parameter Generation (Run Once) +For configuration, you need a unique UUID and Xray Reality keys. Run on any server with Xray installed: +1. **Client UUID:** +```bash +xray uuid +# Save the output (e.g.: 12345678-abcd-1234-abcd-1234567890ab) — this is +``` +2. **X25519 Keypair (Private & Public) for Reality:** +```bash +xray x25519 +# Save the Private key () and Public key () +``` +3. **Short ID (Reality identifier):** +```bash +openssl rand -hex 16 +# Save the output (e.g.: 0123456789abcdef0123456789abcdef) — this is +``` + +--- + +### Configuration for Server B (_EU_): + +Create or edit the file `/usr/local/etc/xray/config.json`. +This Xray instance will listen on the public `443` port and proxy valid Reality traffic, while routing "disguised" traffic (e.g., direct web browser scans) to `yahoo.com`. + +```bash +nano /usr/local/etc/xray/config.json +``` + +File content: +```json +{ + "log": { + "loglevel": "error", + "access": "none" + }, + "inbounds": [ + { + "port": 443, + "protocol": "vless", + "settings": { + "clients": [ + { + "id": "" + } + ], + "decryption": "none" + }, + "streamSettings": { + "network": "xhttp", + "security": "reality", + "realitySettings": { + "dest": "yahoo.com:443", + "serverNames": [ + "yahoo.com" + ], + "privateKey": "", + "shortIds": [ + "" + ] + }, + "xhttpSettings": { + "mode": "auto", + "path": "/api/v3/sync" + } + } + } + ], + "outbounds": [ + { + "protocol": "freedom", + "tag": "direct" + } + ] +} +``` + +Open the firewall port (if enabled): +```bash +sudo ufw allow 443/tcp +``` +Restart and setup Xray to run at boot: +```bash +sudo systemctl restart xray +sudo systemctl enable xray +``` + +--- + +### Configuration for Server A (_RU_): + +Similarly, edit `/usr/local/etc/xray/config.json`. +Here Xray acts as a local client: it listens on `10443\tcp` (for traffic from HAProxy), encapsulates it via Reality to Server B, and instructs Server B to deliver it to its *local* `127.0.0.1:8443` port (where telemt will listen). + +```bash +nano /usr/local/etc/xray/config.json +``` + +File content: +```json +{ + "log": { + "loglevel": "error", + "access": "none" + }, + "inbounds": [ + { + "port": 10443, + "listen": "127.0.0.1", + "protocol": "dokodemo-door", + "settings": { + "address": "127.0.0.1", + "port": 8443, + "network": "tcp" + } + } + ], + "outbounds": [ + { + "protocol": "vless", + "settings": { + "vnext": [ + { + "address": "", + "port": 443, + "users": [ + { + "id": "", + "encryption": "none" + } + ] + } + ] + }, + "streamSettings": { + "network": "xhttp", + "security": "reality", + "realitySettings": { + "serverName": "yahoo.com", + "publicKey": "", + "shortId": "", + "spiderX": "", + "fingerprint": "chrome" + }, + "xhttpSettings": { + "mode": "auto", + "path": "/api/v3/sync", + "xmux": { + "maxConcurrency": 256 + } + } + } + } + ] +} +``` +*Replace `` with the public IP address of Server B.* + +Restart and setup Xray to run at boot: +```bash +sudo systemctl restart xray +sudo systemctl enable xray +``` + +--- + +## Step 2. Setup HAProxy on Server A (_RU_) + +HAProxy will run on the public port `443` of Server A, receive incoming connections from Telegram users, attach a `PROXYv2` header (to forward the true user IP) and send the stream to the local Xray client. +Docker installation is like the [AmneziaWG instructions](./VPS_DOUBLE_HOP.en.md). + +> [!WARNING] +> If you don't run as `root` or have issues with binding to port `443` (`cannot bind socket`), allow unprivileged usage: +> ```bash +> echo "net.ipv4.ip_unprivileged_port_start = 0" | sudo tee -a /etc/sysctl.conf && sudo sysctl -p +> ``` + +#### Create HAProxy Directory: +```bash +mkdir -p /opt/docker-compose/haproxy && cd $_ +``` + +#### Create `docker-compose.yaml` +```yaml +services: + haproxy: + image: haproxy:latest + container_name: haproxy + restart: unless-stopped + # user: "root" + network_mode: "host" + volumes: + - ./haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro + logging: + driver: "json-file" + options: + max-size: "1m" + max-file: "1" +``` + +#### Create HAProxy Config `haproxy.cfg` +```haproxy +global + # Disable connection logs under high load + log stdout format raw local0 err + maxconn 250000 + # Use all CPU threads + nbthread 2 + # Tune buffers and socket limits + tune.bufsize 16384 + tune.maxaccept 64 + +defaults + log global + mode tcp + option clitcpka + option srvtcpka + timeout connect 5s + timeout client 1h + timeout server 1h + # Fast drop dead peers + timeout client-fin 10s + timeout server-fin 10s + +frontend proxy_in + bind *:443 + maxconn 250000 + option tcp-smart-accept + default_backend telemt_backend + +backend telemt_backend + option tcp-smart-connect + # Send-Proxy-V2 is strictly required for telemt IP masking to function over Xray correctly! + server telemt_core 127.0.0.1:10443 maxconn 250000 send-proxy-v2 check inter 5s + +``` +>[!WARNING] +>**The configuration file must end with an empty newline, otherwise HAProxy fails to start!** + +#### Start the HAProxy Container +Allow port `443\tcp` in your firewall and launch Docker compose: +```bash +sudo ufw allow 443/tcp +docker compose up -d +``` + +--- + +## Step 3. Install telemt on Server B (_EU_) + +telemt installation is heavily covered in the [Quick Start Guide](../QUICK_START_GUIDE.en.md). +By contrast to standard setups, telemt must listen strictly _locally_ (since Xray occupies the public `443` interface) and must expect `PROXYv2` packets. + +Edit the configuration file (`config.toml`) on Server B accordingly: + +```toml +[server] +port = 8443 +listen_addr_ipv4 = "127.0.0.1" +proxy_protocol = true + +[general.links] +show = "*" +public_host = "" +public_port = 443 +``` + +- Address `127.0.0.1` and `port = 8443` instructs the core proxy router to process connections unpacked locally via Xray-server. +- `proxy_protocol = true` commands telemt to parse the injected PROXY header (from Server A's HAProxy) and log genuine end-user IPs. +- Under `public_host`, place Server A's public IP address or FQDN to ensure working links are generated for Telegram users. + +Restart `telemt`. Your server is now robust against DPI scanners, passing traffic optimally. + diff --git a/docs/Setup_examples/XRAY_DOUBLE_HOP.ru.md b/docs/Setup_examples/XRAY_DOUBLE_HOP.ru.md new file mode 100644 index 0000000..73bb0bf --- /dev/null +++ b/docs/Setup_examples/XRAY_DOUBLE_HOP.ru.md @@ -0,0 +1,296 @@ + + +## Концепция +- **Сервер A** (_РФ_):\ + Точка входа, принимает трафик пользователей Telegram-прокси через **HAProxy** (порт `443\tcp`)\ + и отправляет его через локальный клиент **Xray** (порт `10443\tcp`) на Сервер **B**.\ + Порт для клиентов HAProxy — `443\tcp` +- **Сервер B** (_условно Нидерланды_):\ + Точка выхода, на нем работает **Xray-сервер** (принимает подключения точки входа) и **telemt**.\ + На сервере должен быть неограниченный доступ до серверов Telegram.\ + Порт для VLESS/REALITY (вход) — `443\tcp`\ + Внутренний порт telemt (куда пробрасывается трафик) — `8443\tcp` + +Туннель работает по протоколу VLESS-XTLS-Reality (или VLESS/xhttp/reality). Оригинальный IP-адрес клиента сохраняется благодаря протоколу PROXYv2, который HAProxy добавляет перед отправкой в Xray, и который прозрачно доходит до telemt. + +--- + +## Шаг 1. Настройка туннеля Xray (A <-> B) + +На обоих серверах необходимо установить **Xray-core** (рекомендуется версия 1.8.4 или новее). +Официальный скрипт установки (выполнить на обоих серверах): +```bash +bash -c "$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)" @ install +``` + +### Генерация ключей и параметров (выполнить один раз) +Для конфигурации потребуются уникальные ID и ключи Xray Reality. Выполните на любом сервере с установленным Xray: +1. **UUID клиента:** +```bash +xray uuid +# Сохраните вывод (например: 12345678-abcd-1234-abcd-1234567890ab) — это +``` +2. **Пара ключей X25519 (Private & Public) для Reality:** +```bash +xray x25519 +# Сохраните Private key () и Public key () +``` +3. **Short ID (идентификатор Reality):** +```bash +openssl rand -hex 16 +# Сохраните вывод (например: 0123456789abcdef0123456789abcdef) — это +``` + +--- + +### Конфигурация Сервера B (_Нидерланды_): + +Создаем или редактируем файл `/usr/local/etc/xray/config.json`. +Этот Xray-сервер будет слушать порт `443` и прозрачно пропускать валидный Reality трафик дальше, а "замаскированный" трафик (например, если кто-то стучится в лоб веб-браузером) пойдет на `yahoo.com`. + +```bash +nano /usr/local/etc/xray/config.json +``` + +Содержимое файла: +```json +{ + "log": { + "loglevel": "error", + "access": "none" + }, + "inbounds": [ + { + "port": 443, + "protocol": "vless", + "settings": { + "clients": [ + { + "id": "" + } + ], + "decryption": "none" + }, + "streamSettings": { + "network": "xhttp", + "security": "reality", + "realitySettings": { + "dest": "yahoo.com:443", + "serverNames": [ + "yahoo.com" + ], + "privateKey": "", + "shortIds": [ + "" + ] + }, + "xhttpSettings": { + "mode": "auto", + "path": "/api/v3/sync" + } + } + } + ], + "outbounds": [ + { + "protocol": "freedom", + "tag": "direct" + } + ] +} +``` + +Открываем порт на фаерволе (если включен): +```bash +sudo ufw allow 443/tcp +``` +Перезапускаем Xray: +```bash +sudo systemctl restart xray +sudo systemctl enable xray +``` + +--- + +### Конфигурация Сервера A (_РФ_): + +Аналогично, редактируем `/usr/local/etc/xray/config.json`. +Здесь Xray выступает клиентом: он локально принимает трафик на порту `10443\tcp` (от HAProxy) и упаковывает его в Reality до Сервера B, прося тот доставить данные на *свой локальный* порт `127.0.0.1:8443` (именно там будет слушать telemt). + +```bash +nano /usr/local/etc/xray/config.json +``` + +Содержимое файла: +```json +{ + "log": { + "loglevel": "error", + "access": "none" + }, + "inbounds": [ + { + "port": 10443, + "listen": "127.0.0.1", + "protocol": "dokodemo-door", + "settings": { + "address": "127.0.0.1", + "port": 8443, + "network": "tcp" + } + } + ], + "outbounds": [ + { + "protocol": "vless", + "settings": { + "vnext": [ + { + "address": "", + "port": 443, + "users": [ + { + "id": "", + "encryption": "none" + } + ] + } + ] + }, + "streamSettings": { + "network": "xhttp", + "security": "reality", + "realitySettings": { + "serverName": "yahoo.com", + "publicKey": "", + "shortId": "", + "spiderX": "", + "fingerprint": "chrome" + }, + "xhttpSettings": { + "mode": "auto", + "path": "/api/v3/sync", + "xmux": { + "maxConcurrency": 256 + } + } + } + } + ] +} +``` +*Замените `` на внешний IP-адрес Сервера B.* + +Перезапускаем Xray: +```bash +sudo systemctl restart xray +sudo systemctl enable xray +``` + +--- + +## Шаг 2. Настройка HAProxy на Сервере A (_РФ_) + +HAProxy будет висеть на публичном порту `443` Сервера A, принимать подключения от Telegram-клиентов, добавлять заголовок `PROXYv2` (чтобы пробросить реальный IP пользователя) и отправлять в локальный клиент Xray. +Установка Docker аналогична [инструкции AmneziaWG варианта](./VPS_DOUBLE_HOP.ru.md). + +> [!WARNING] +> Если запускаете не под `root` или возникают проблемы с правами на `443` порт: +> ```bash +> echo "net.ipv4.ip_unprivileged_port_start = 0" | sudo tee -a /etc/sysctl.conf && sudo sysctl -p +> ``` + +#### Создаем папку для HAProxy: +```bash +mkdir -p /opt/docker-compose/haproxy && cd $_ +``` + +#### Создаем файл `docker-compose.yaml` +```yaml +services: + haproxy: + image: haproxy:latest + container_name: haproxy + restart: unless-stopped + # user: "root" + network_mode: "host" + volumes: + - ./haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro + logging: + driver: "json-file" + options: + max-size: "1m" + max-file: "1" +``` + +#### Создаем файл конфигурации `haproxy.cfg` +```haproxy +global + # Отключить детальные логи соединений под нагрузкой + log stdout format raw local0 err + maxconn 250000 + # Использовать все ядра CPU + nbthread 2 + # Тюнинг буферов и приема сокетов + tune.bufsize 16384 + tune.maxaccept 64 + +defaults + log global + mode tcp + option clitcpka + option srvtcpka + timeout connect 5s + timeout client 1h + timeout server 1h + # Быстрая очистка мертвых пиров + timeout client-fin 10s + timeout server-fin 10s + +frontend proxy_in + bind *:443 + maxconn 250000 + option tcp-smart-accept + default_backend telemt_backend + +backend telemt_backend + option tcp-smart-connect + # Send-Proxy-V2 обязателен для сохранения IP клиента внутри внутренней логики Telemt + server telemt_core 127.0.0.1:10443 maxconn 250000 send-proxy-v2 check inter 5s + +``` +>[!WARNING] +>**Файл должен заканчиваться пустой строкой, иначе HAProxy не запустится!** + +#### Разрешаем порт `443\tcp` в фаерволе и запускаем контейнер +```bash +sudo ufw allow 443/tcp +docker compose up -d +``` + +--- + +## Шаг 3. Установка и настройка telemt на Сервере B (_Нидерланды_) + +Установка telemt описана [в основной инструкции](../QUICK_START_GUIDE.ru.md). +Отличие в том, что telemt должен слушать *внутренний* порт (так как 443 занят Xray-сервером), а также ожидать `PROXY` протокол из Xray туннеля. + +В конфиге `config.toml` прокси (на Сервере B) укажите: +```toml +[server] +port = 8443 +listen_addr_ipv4 = "127.0.0.1" +proxy_protocol = true + +[general.links] +show = "*" +public_host = "" +public_port = 443 +``` + +- `port = 8443` и `listen_addr_ipv4 = "127.0.0.1"` означают, что telemt принимает подключения только изнутри (приходящие от локального Xray-процесса). +- `proxy_protocol = true` заставляет telemt парсить PROXYv2-заголовок (который добавил HAProxy на Сервере A и протащил Xray), восстанавливая IP-адрес конечного пользователя (РФ). +- В `public_host` укажите публичный IP-адрес или домен Сервера A, чтобы ссылки на подключение генерировались корректно. + +Перезапустите `telemt`, и клиенты смогут подключаться по выданным ссылкам. + From a526fee72861b390345bc57d517419758fbf04f2 Mon Sep 17 00:00:00 2001 From: miniusercoder Date: Wed, 8 Apr 2026 22:24:51 +0300 Subject: [PATCH 2/5] fix documentation for Xray double hop setup --- docs/Setup_examples/XRAY_DOUBLE_HOP.en.md | 77 +++++++++++++---------- docs/Setup_examples/XRAY_DOUBLE_HOP.ru.md | 77 +++++++++++++---------- 2 files changed, 88 insertions(+), 66 deletions(-) diff --git a/docs/Setup_examples/XRAY_DOUBLE_HOP.en.md b/docs/Setup_examples/XRAY_DOUBLE_HOP.en.md index 44c22ff..a855ec0 100644 --- a/docs/Setup_examples/XRAY_DOUBLE_HOP.en.md +++ b/docs/Setup_examples/XRAY_DOUBLE_HOP.en.md @@ -72,7 +72,7 @@ File content: "decryption": "none" }, "streamSettings": { - "network": "xhttp", + "network": "tcp", "security": "reality", "realitySettings": { "dest": "yahoo.com:443", @@ -83,20 +83,34 @@ File content: "shortIds": [ "" ] - }, - "xhttpSettings": { - "mode": "auto", - "path": "/api/v3/sync" } + }, + "sockopt": { + "tcpFastOpen": true, + "tcpNoDelay": true, + "tcpKeepAliveIdle": 60, + "tcpKeepAliveInterval": 15 } } ], "outbounds": [ { "protocol": "freedom", - "tag": "direct" + "tag": "direct", + "settings": { + "destination": "127.0.0.1:8443" + } } - ] + ], + "routing": { + "rules": [ + { + "type": "field", + "inboundTag": ["all-in"], + "outboundTag": "direct" + } + ] + } } ``` @@ -158,7 +172,7 @@ File content: ] }, "streamSettings": { - "network": "xhttp", + "network": "tcp", "security": "reality", "realitySettings": { "serverName": "yahoo.com", @@ -167,13 +181,18 @@ File content: "spiderX": "", "fingerprint": "chrome" }, - "xhttpSettings": { - "mode": "auto", - "path": "/api/v3/sync", - "xmux": { - "maxConcurrency": 256 - } + "sockopt": { + "tcpFastOpen": true, + "tcpNoDelay": true, + "tcpKeepAliveIdle": 60, + "tcpKeepAliveInterval": 15 } + }, + "mux": { + "enabled": true, + "concurrency": 256, + "xudpConcurrency": 16, + "xudpProxyUDP443": "reject" } } ] @@ -226,37 +245,29 @@ services: #### Create HAProxy Config `haproxy.cfg` ```haproxy global - # Disable connection logs under high load - log stdout format raw local0 err - maxconn 250000 - # Use all CPU threads - nbthread 2 - # Tune buffers and socket limits - tune.bufsize 16384 - tune.maxaccept 64 + log stdout format raw local0 + maxconn 10000 defaults log global mode tcp + option tcplog option clitcpka option srvtcpka timeout connect 5s - timeout client 1h - timeout server 1h - # Fast drop dead peers - timeout client-fin 10s - timeout server-fin 10s + timeout client 2h + timeout server 2h + timeout check 5s -frontend proxy_in +frontend tcp_in_443 bind *:443 - maxconn 250000 + maxconn 8000 option tcp-smart-accept - default_backend telemt_backend + default_backend telemt_nodes -backend telemt_backend +backend telemt_nodes option tcp-smart-connect - # Send-Proxy-V2 is strictly required for telemt IP masking to function over Xray correctly! - server telemt_core 127.0.0.1:10443 maxconn 250000 send-proxy-v2 check inter 5s + server telemt_core 127.0.0.1:10443 check inter 5s rise 2 fall 3 maxconn 250000 send-proxy-v2 ``` >[!WARNING] diff --git a/docs/Setup_examples/XRAY_DOUBLE_HOP.ru.md b/docs/Setup_examples/XRAY_DOUBLE_HOP.ru.md index 73bb0bf..757987b 100644 --- a/docs/Setup_examples/XRAY_DOUBLE_HOP.ru.md +++ b/docs/Setup_examples/XRAY_DOUBLE_HOP.ru.md @@ -72,7 +72,7 @@ nano /usr/local/etc/xray/config.json "decryption": "none" }, "streamSettings": { - "network": "xhttp", + "network": "tcp", "security": "reality", "realitySettings": { "dest": "yahoo.com:443", @@ -83,20 +83,34 @@ nano /usr/local/etc/xray/config.json "shortIds": [ "" ] - }, - "xhttpSettings": { - "mode": "auto", - "path": "/api/v3/sync" } + }, + "sockopt": { + "tcpFastOpen": true, + "tcpNoDelay": true, + "tcpKeepAliveIdle": 60, + "tcpKeepAliveInterval": 15 } } ], "outbounds": [ { "protocol": "freedom", - "tag": "direct" + "tag": "direct", + "settings": { + "destination": "127.0.0.1:8443" + } } - ] + ], + "routing": { + "rules": [ + { + "type": "field", + "inboundTag": ["all-in"], + "outboundTag": "direct" + } + ] + } } ``` @@ -158,7 +172,7 @@ nano /usr/local/etc/xray/config.json ] }, "streamSettings": { - "network": "xhttp", + "network": "tcp", "security": "reality", "realitySettings": { "serverName": "yahoo.com", @@ -167,13 +181,18 @@ nano /usr/local/etc/xray/config.json "spiderX": "", "fingerprint": "chrome" }, - "xhttpSettings": { - "mode": "auto", - "path": "/api/v3/sync", - "xmux": { - "maxConcurrency": 256 - } + "sockopt": { + "tcpFastOpen": true, + "tcpNoDelay": true, + "tcpKeepAliveIdle": 60, + "tcpKeepAliveInterval": 15 } + }, + "mux": { + "enabled": true, + "concurrency": 256, + "xudpConcurrency": 16, + "xudpProxyUDP443": "reject" } } ] @@ -226,37 +245,29 @@ services: #### Создаем файл конфигурации `haproxy.cfg` ```haproxy global - # Отключить детальные логи соединений под нагрузкой - log stdout format raw local0 err - maxconn 250000 - # Использовать все ядра CPU - nbthread 2 - # Тюнинг буферов и приема сокетов - tune.bufsize 16384 - tune.maxaccept 64 + log stdout format raw local0 + maxconn 10000 defaults log global mode tcp + option tcplog option clitcpka option srvtcpka timeout connect 5s - timeout client 1h - timeout server 1h - # Быстрая очистка мертвых пиров - timeout client-fin 10s - timeout server-fin 10s + timeout client 2h + timeout server 2h + timeout check 5s -frontend proxy_in +frontend tcp_in_443 bind *:443 - maxconn 250000 + maxconn 8000 option tcp-smart-accept - default_backend telemt_backend + default_backend telemt_nodes -backend telemt_backend +backend telemt_nodes option tcp-smart-connect - # Send-Proxy-V2 обязателен для сохранения IP клиента внутри внутренней логики Telemt - server telemt_core 127.0.0.1:10443 maxconn 250000 send-proxy-v2 check inter 5s + server telemt_core 127.0.0.1:10443 check inter 5s rise 2 fall 3 maxconn 250000 send-proxy-v2 ``` >[!WARNING] From 126523449103296193d32255c2bba54af4d614d4 Mon Sep 17 00:00:00 2001 From: miniusercoder Date: Thu, 9 Apr 2026 18:48:37 +0300 Subject: [PATCH 3/5] xray with xhttp configuration --- docs/Setup_examples/XRAY_DOUBLE_HOP.en.md | 45 +++++++++++------------ docs/Setup_examples/XRAY_DOUBLE_HOP.ru.md | 45 +++++++++++------------ 2 files changed, 44 insertions(+), 46 deletions(-) diff --git a/docs/Setup_examples/XRAY_DOUBLE_HOP.en.md b/docs/Setup_examples/XRAY_DOUBLE_HOP.en.md index a855ec0..59156e2 100644 --- a/docs/Setup_examples/XRAY_DOUBLE_HOP.en.md +++ b/docs/Setup_examples/XRAY_DOUBLE_HOP.en.md @@ -40,6 +40,11 @@ xray x25519 openssl rand -hex 16 # Save the output (e.g.: 0123456789abcdef0123456789abcdef) — this is ``` +4. **Random Path (for xhttp):** +```bash +openssl rand -hex 8 +# Save the output (e.g., abc123def456) to replace in configs +``` --- @@ -61,6 +66,7 @@ File content: }, "inbounds": [ { + "tag": "vless-in", "port": 443, "protocol": "vless", "settings": { @@ -72,7 +78,7 @@ File content: "decryption": "none" }, "streamSettings": { - "network": "tcp", + "network": "xhttp", "security": "reality", "realitySettings": { "dest": "yahoo.com:443", @@ -83,31 +89,32 @@ File content: "shortIds": [ "" ] + }, + "xhttpSettings": { + "path": "/", + "mode": "auto" } - }, - "sockopt": { - "tcpFastOpen": true, - "tcpNoDelay": true, - "tcpKeepAliveIdle": 60, - "tcpKeepAliveInterval": 15 } } ], "outbounds": [ { + "tag": "tunnel-to-telemt", "protocol": "freedom", - "tag": "direct", "settings": { "destination": "127.0.0.1:8443" } } ], "routing": { + "domainStrategy": "AsIs", "rules": [ { "type": "field", - "inboundTag": ["all-in"], - "outboundTag": "direct" + "inboundTag": [ + "vless-in" + ], + "outboundTag": "tunnel-to-telemt" } ] } @@ -156,6 +163,7 @@ File content: ], "outbounds": [ { + "tag": "vless-out", "protocol": "vless", "settings": { "vnext": [ @@ -172,27 +180,18 @@ File content: ] }, "streamSettings": { - "network": "tcp", + "network": "xhttp", "security": "reality", "realitySettings": { "serverName": "yahoo.com", "publicKey": "", "shortId": "", - "spiderX": "", + "spiderX": "/", "fingerprint": "chrome" }, - "sockopt": { - "tcpFastOpen": true, - "tcpNoDelay": true, - "tcpKeepAliveIdle": 60, - "tcpKeepAliveInterval": 15 + "xhttpSettings": { + "path": "/" } - }, - "mux": { - "enabled": true, - "concurrency": 256, - "xudpConcurrency": 16, - "xudpProxyUDP443": "reject" } } ] diff --git a/docs/Setup_examples/XRAY_DOUBLE_HOP.ru.md b/docs/Setup_examples/XRAY_DOUBLE_HOP.ru.md index 757987b..e9d0628 100644 --- a/docs/Setup_examples/XRAY_DOUBLE_HOP.ru.md +++ b/docs/Setup_examples/XRAY_DOUBLE_HOP.ru.md @@ -40,6 +40,11 @@ xray x25519 openssl rand -hex 16 # Сохраните вывод (например: 0123456789abcdef0123456789abcdef) — это ``` +4. **Random Path (путь для xhttp):** +```bash +openssl rand -hex 8 +# Сохраните вывод (например, abc123def456), чтобы заменить в конфигах +``` --- @@ -61,6 +66,7 @@ nano /usr/local/etc/xray/config.json }, "inbounds": [ { + "tag": "vless-in", "port": 443, "protocol": "vless", "settings": { @@ -72,7 +78,7 @@ nano /usr/local/etc/xray/config.json "decryption": "none" }, "streamSettings": { - "network": "tcp", + "network": "xhttp", "security": "reality", "realitySettings": { "dest": "yahoo.com:443", @@ -83,31 +89,32 @@ nano /usr/local/etc/xray/config.json "shortIds": [ "" ] + }, + "xhttpSettings": { + "path": "/", + "mode": "auto" } - }, - "sockopt": { - "tcpFastOpen": true, - "tcpNoDelay": true, - "tcpKeepAliveIdle": 60, - "tcpKeepAliveInterval": 15 } } ], "outbounds": [ { + "tag": "tunnel-to-telemt", "protocol": "freedom", - "tag": "direct", "settings": { "destination": "127.0.0.1:8443" } } ], "routing": { + "domainStrategy": "AsIs", "rules": [ { "type": "field", - "inboundTag": ["all-in"], - "outboundTag": "direct" + "inboundTag": [ + "vless-in" + ], + "outboundTag": "tunnel-to-telemt" } ] } @@ -156,6 +163,7 @@ nano /usr/local/etc/xray/config.json ], "outbounds": [ { + "tag": "vless-out", "protocol": "vless", "settings": { "vnext": [ @@ -172,27 +180,18 @@ nano /usr/local/etc/xray/config.json ] }, "streamSettings": { - "network": "tcp", + "network": "xhttp", "security": "reality", "realitySettings": { "serverName": "yahoo.com", "publicKey": "", "shortId": "", - "spiderX": "", + "spiderX": "/", "fingerprint": "chrome" }, - "sockopt": { - "tcpFastOpen": true, - "tcpNoDelay": true, - "tcpKeepAliveIdle": 60, - "tcpKeepAliveInterval": 15 + "xhttpSettings": { + "path": "/" } - }, - "mux": { - "enabled": true, - "concurrency": 256, - "xudpConcurrency": 16, - "xudpProxyUDP443": "reject" } } ] From b246f0ed9914dd04d466fc3bdcd28fa0be248302 Mon Sep 17 00:00:00 2001 From: miniusercoder Date: Thu, 9 Apr 2026 19:51:35 +0300 Subject: [PATCH 4/5] do not use haproxy in xray double hop configuration --- docs/Setup_examples/XRAY_DOUBLE_HOP.en.md | 131 ++++++++-------------- docs/Setup_examples/XRAY_DOUBLE_HOP.ru.md | 130 ++++++++------------- 2 files changed, 96 insertions(+), 165 deletions(-) diff --git a/docs/Setup_examples/XRAY_DOUBLE_HOP.en.md b/docs/Setup_examples/XRAY_DOUBLE_HOP.en.md index 59156e2..c5821f0 100644 --- a/docs/Setup_examples/XRAY_DOUBLE_HOP.en.md +++ b/docs/Setup_examples/XRAY_DOUBLE_HOP.en.md @@ -2,16 +2,16 @@ ## Concept - **Server A** (_e.g., RU_):\ - Entry point, accepts Telegram proxy user traffic via **HAProxy** (port `443\tcp`)\ - and sends it through the local **Xray** client (port `10443\tcp`) to Server **B**.\ - Public port for HAProxy clients — `443\tcp` + Entry point, accepts Telegram proxy user traffic via **Xray** (port `443\tcp`)\ + and sends it through the tunnel to Server **B**.\ + Public port for Telegram clients — `443\tcp` - **Server B** (_e.g., NL_):\ Exit point, runs the **Xray server** (to terminate the tunnel entry point) and **telemt**.\ The server must have unrestricted access to Telegram Data Centers.\ Public port for VLESS/REALITY (incoming) — `443\tcp`\ Internal telemt port (where decrypted Xray traffic ends up) — `8443\tcp` -The tunnel works over the `VLESS-XTLS-Reality` (or `VLESS/xhttp/reality`) protocol. The original client IP address is preserved thanks to the PROXYv2 protocol, which HAProxy prepends before passing to Xray, and which transparently reaches telemt. +The tunnel works over the `VLESS-XTLS-Reality` (or `VLESS/xhttp/reality`) protocol. The original client IP address is preserved thanks to the PROXYv2 protocol, which Xray on Server A dynamically injects via a local loopback before wrapping the traffic into Reality, transparently delivering the real IPs to telemt on Server B. --- @@ -136,7 +136,7 @@ sudo systemctl enable xray ### Configuration for Server A (_RU_): Similarly, edit `/usr/local/etc/xray/config.json`. -Here Xray acts as a local client: it listens on `10443\tcp` (for traffic from HAProxy), encapsulates it via Reality to Server B, and instructs Server B to deliver it to its *local* `127.0.0.1:8443` port (where telemt will listen). +Here Xray acts as the public entry point: it listens on `443\tcp`, uses a local loopback (via internal port `10444`) to prepend the `PROXYv2` header, and encapsulates the payload via Reality to Server B, instructing Server B to deliver it to its *local* `127.0.0.1:8443` port (where telemt will listen). ```bash nano /usr/local/etc/xray/config.json @@ -151,7 +151,19 @@ File content: }, "inbounds": [ { - "port": 10443, + "tag": "public-in", + "port": 443, + "listen": "0.0.0.0", + "protocol": "dokodemo-door", + "settings": { + "address": "127.0.0.1", + "port": 10444, + "network": "tcp" + } + }, + { + "tag": "tunnel-in", + "port": 10444, "listen": "127.0.0.1", "protocol": "dokodemo-door", "settings": { @@ -162,6 +174,13 @@ File content: } ], "outbounds": [ + { + "tag": "local-injector", + "protocol": "freedom", + "settings": { + "proxyProtocol": 2 + } + }, { "tag": "vless-out", "protocol": "vless", @@ -194,11 +213,31 @@ File content: } } } - ] + ], + "routing": { + "domainStrategy": "AsIs", + "rules": [ + { + "type": "field", + "inboundTag": ["public-in"], + "outboundTag": "local-injector" + }, + { + "type": "field", + "inboundTag": ["tunnel-in"], + "outboundTag": "vless-out" + } + ] + } } ``` *Replace `` with the public IP address of Server B.* +Open the firewall port for clients (if enabled): +```bash +sudo ufw allow 443/tcp +``` + Restart and setup Xray to run at boot: ```bash sudo systemctl restart xray @@ -207,81 +246,7 @@ sudo systemctl enable xray --- -## Step 2. Setup HAProxy on Server A (_RU_) - -HAProxy will run on the public port `443` of Server A, receive incoming connections from Telegram users, attach a `PROXYv2` header (to forward the true user IP) and send the stream to the local Xray client. -Docker installation is like the [AmneziaWG instructions](./VPS_DOUBLE_HOP.en.md). - -> [!WARNING] -> If you don't run as `root` or have issues with binding to port `443` (`cannot bind socket`), allow unprivileged usage: -> ```bash -> echo "net.ipv4.ip_unprivileged_port_start = 0" | sudo tee -a /etc/sysctl.conf && sudo sysctl -p -> ``` - -#### Create HAProxy Directory: -```bash -mkdir -p /opt/docker-compose/haproxy && cd $_ -``` - -#### Create `docker-compose.yaml` -```yaml -services: - haproxy: - image: haproxy:latest - container_name: haproxy - restart: unless-stopped - # user: "root" - network_mode: "host" - volumes: - - ./haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro - logging: - driver: "json-file" - options: - max-size: "1m" - max-file: "1" -``` - -#### Create HAProxy Config `haproxy.cfg` -```haproxy -global - log stdout format raw local0 - maxconn 10000 - -defaults - log global - mode tcp - option tcplog - option clitcpka - option srvtcpka - timeout connect 5s - timeout client 2h - timeout server 2h - timeout check 5s - -frontend tcp_in_443 - bind *:443 - maxconn 8000 - option tcp-smart-accept - default_backend telemt_nodes - -backend telemt_nodes - option tcp-smart-connect - server telemt_core 127.0.0.1:10443 check inter 5s rise 2 fall 3 maxconn 250000 send-proxy-v2 - -``` ->[!WARNING] ->**The configuration file must end with an empty newline, otherwise HAProxy fails to start!** - -#### Start the HAProxy Container -Allow port `443\tcp` in your firewall and launch Docker compose: -```bash -sudo ufw allow 443/tcp -docker compose up -d -``` - ---- - -## Step 3. Install telemt on Server B (_EU_) +## Step 2. Install telemt on Server B (_EU_) telemt installation is heavily covered in the [Quick Start Guide](../QUICK_START_GUIDE.en.md). By contrast to standard setups, telemt must listen strictly _locally_ (since Xray occupies the public `443` interface) and must expect `PROXYv2` packets. @@ -301,7 +266,7 @@ public_port = 443 ``` - Address `127.0.0.1` and `port = 8443` instructs the core proxy router to process connections unpacked locally via Xray-server. -- `proxy_protocol = true` commands telemt to parse the injected PROXY header (from Server A's HAProxy) and log genuine end-user IPs. +- `proxy_protocol = true` commands telemt to parse the injected PROXY header (from Server A's Xray local loopback) and log genuine end-user IPs. - Under `public_host`, place Server A's public IP address or FQDN to ensure working links are generated for Telegram users. Restart `telemt`. Your server is now robust against DPI scanners, passing traffic optimally. diff --git a/docs/Setup_examples/XRAY_DOUBLE_HOP.ru.md b/docs/Setup_examples/XRAY_DOUBLE_HOP.ru.md index e9d0628..3e8d705 100644 --- a/docs/Setup_examples/XRAY_DOUBLE_HOP.ru.md +++ b/docs/Setup_examples/XRAY_DOUBLE_HOP.ru.md @@ -2,16 +2,16 @@ ## Концепция - **Сервер A** (_РФ_):\ - Точка входа, принимает трафик пользователей Telegram-прокси через **HAProxy** (порт `443\tcp`)\ - и отправляет его через локальный клиент **Xray** (порт `10443\tcp`) на Сервер **B**.\ - Порт для клиентов HAProxy — `443\tcp` + Точка входа, принимает трафик пользователей Telegram-прокси напрямую через **Xray** (порт `443\tcp`)\ + и отправляет его в туннель на Сервер **B**.\ + Порт для клиентов Telegram — `443\tcp` - **Сервер B** (_условно Нидерланды_):\ Точка выхода, на нем работает **Xray-сервер** (принимает подключения точки входа) и **telemt**.\ На сервере должен быть неограниченный доступ до серверов Telegram.\ Порт для VLESS/REALITY (вход) — `443\tcp`\ Внутренний порт telemt (куда пробрасывается трафик) — `8443\tcp` -Туннель работает по протоколу VLESS-XTLS-Reality (или VLESS/xhttp/reality). Оригинальный IP-адрес клиента сохраняется благодаря протоколу PROXYv2, который HAProxy добавляет перед отправкой в Xray, и который прозрачно доходит до telemt. +Туннель работает по протоколу VLESS-XTLS-Reality (или VLESS/xhttp/reality). Оригинальный IP-адрес клиента сохраняется благодаря протоколу PROXYv2, который Xray на Сервере А добавляет через локальный loopback перед упаковкой в туннель, благодаря чему прозрачно доходит до telemt. --- @@ -136,7 +136,7 @@ sudo systemctl enable xray ### Конфигурация Сервера A (_РФ_): Аналогично, редактируем `/usr/local/etc/xray/config.json`. -Здесь Xray выступает клиентом: он локально принимает трафик на порту `10443\tcp` (от HAProxy) и упаковывает его в Reality до Сервера B, прося тот доставить данные на *свой локальный* порт `127.0.0.1:8443` (именно там будет слушать telemt). +Здесь Xray выступает публичной точкой: он принимает трафик на внешний порт `443\tcp`, пропускает через локальный loopback (порт `10444`) для добавления PROXYv2-заголовка, и упаковывает в Reality до Сервера B, прося тот доставить данные на *свой локальный* порт `127.0.0.1:8443` (именно там будет слушать telemt). ```bash nano /usr/local/etc/xray/config.json @@ -151,7 +151,19 @@ nano /usr/local/etc/xray/config.json }, "inbounds": [ { - "port": 10443, + "tag": "public-in", + "port": 443, + "listen": "0.0.0.0", + "protocol": "dokodemo-door", + "settings": { + "address": "127.0.0.1", + "port": 10444, + "network": "tcp" + } + }, + { + "tag": "tunnel-in", + "port": 10444, "listen": "127.0.0.1", "protocol": "dokodemo-door", "settings": { @@ -162,6 +174,13 @@ nano /usr/local/etc/xray/config.json } ], "outbounds": [ + { + "tag": "local-injector", + "protocol": "freedom", + "settings": { + "proxyProtocol": 2 + } + }, { "tag": "vless-out", "protocol": "vless", @@ -194,11 +213,31 @@ nano /usr/local/etc/xray/config.json } } } - ] + ], + "routing": { + "domainStrategy": "AsIs", + "rules": [ + { + "type": "field", + "inboundTag": ["public-in"], + "outboundTag": "local-injector" + }, + { + "type": "field", + "inboundTag": ["tunnel-in"], + "outboundTag": "vless-out" + } + ] + } } ``` *Замените `` на внешний IP-адрес Сервера B.* +Открываем порт на фаерволе для клиентов: +```bash +sudo ufw allow 443/tcp +``` + Перезапускаем Xray: ```bash sudo systemctl restart xray @@ -207,80 +246,7 @@ sudo systemctl enable xray --- -## Шаг 2. Настройка HAProxy на Сервере A (_РФ_) - -HAProxy будет висеть на публичном порту `443` Сервера A, принимать подключения от Telegram-клиентов, добавлять заголовок `PROXYv2` (чтобы пробросить реальный IP пользователя) и отправлять в локальный клиент Xray. -Установка Docker аналогична [инструкции AmneziaWG варианта](./VPS_DOUBLE_HOP.ru.md). - -> [!WARNING] -> Если запускаете не под `root` или возникают проблемы с правами на `443` порт: -> ```bash -> echo "net.ipv4.ip_unprivileged_port_start = 0" | sudo tee -a /etc/sysctl.conf && sudo sysctl -p -> ``` - -#### Создаем папку для HAProxy: -```bash -mkdir -p /opt/docker-compose/haproxy && cd $_ -``` - -#### Создаем файл `docker-compose.yaml` -```yaml -services: - haproxy: - image: haproxy:latest - container_name: haproxy - restart: unless-stopped - # user: "root" - network_mode: "host" - volumes: - - ./haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro - logging: - driver: "json-file" - options: - max-size: "1m" - max-file: "1" -``` - -#### Создаем файл конфигурации `haproxy.cfg` -```haproxy -global - log stdout format raw local0 - maxconn 10000 - -defaults - log global - mode tcp - option tcplog - option clitcpka - option srvtcpka - timeout connect 5s - timeout client 2h - timeout server 2h - timeout check 5s - -frontend tcp_in_443 - bind *:443 - maxconn 8000 - option tcp-smart-accept - default_backend telemt_nodes - -backend telemt_nodes - option tcp-smart-connect - server telemt_core 127.0.0.1:10443 check inter 5s rise 2 fall 3 maxconn 250000 send-proxy-v2 - -``` ->[!WARNING] ->**Файл должен заканчиваться пустой строкой, иначе HAProxy не запустится!** - -#### Разрешаем порт `443\tcp` в фаерволе и запускаем контейнер -```bash -sudo ufw allow 443/tcp -docker compose up -d -``` - ---- - -## Шаг 3. Установка и настройка telemt на Сервере B (_Нидерланды_) +## Шаг 2. Установка и настройка telemt на Сервере B (_Нидерланды_) Установка telemt описана [в основной инструкции](../QUICK_START_GUIDE.ru.md). Отличие в том, что telemt должен слушать *внутренний* порт (так как 443 занят Xray-сервером), а также ожидать `PROXY` протокол из Xray туннеля. @@ -299,7 +265,7 @@ public_port = 443 ``` - `port = 8443` и `listen_addr_ipv4 = "127.0.0.1"` означают, что telemt принимает подключения только изнутри (приходящие от локального Xray-процесса). -- `proxy_protocol = true` заставляет telemt парсить PROXYv2-заголовок (который добавил HAProxy на Сервере A и протащил Xray), восстанавливая IP-адрес конечного пользователя (РФ). +- `proxy_protocol = true` заставляет telemt парсить PROXYv2-заголовок (который добавил Xray на Сервере A через loopback), восстанавливая IP-адрес конечного пользователя (РФ). - В `public_host` укажите публичный IP-адрес или домен Сервера A, чтобы ссылки на подключение генерировались корректно. Перезапустите `telemt`, и клиенты смогут подключаться по выданным ссылкам. From 7acc76b42213a64bee174bf32fdcbad6c496b473 Mon Sep 17 00:00:00 2001 From: miniusercoder Date: Fri, 10 Apr 2026 13:45:53 +0300 Subject: [PATCH 5/5] fix quick start link in xray double hop --- docs/Setup_examples/XRAY_DOUBLE_HOP.en.md | 2 +- docs/Setup_examples/XRAY_DOUBLE_HOP.ru.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/Setup_examples/XRAY_DOUBLE_HOP.en.md b/docs/Setup_examples/XRAY_DOUBLE_HOP.en.md index c5821f0..6cde329 100644 --- a/docs/Setup_examples/XRAY_DOUBLE_HOP.en.md +++ b/docs/Setup_examples/XRAY_DOUBLE_HOP.en.md @@ -248,7 +248,7 @@ sudo systemctl enable xray ## Step 2. Install telemt on Server B (_EU_) -telemt installation is heavily covered in the [Quick Start Guide](../QUICK_START_GUIDE.en.md). +telemt installation is heavily covered in the [Quick Start Guide](../Quick_start/QUICK_START_GUIDE.en.md). By contrast to standard setups, telemt must listen strictly _locally_ (since Xray occupies the public `443` interface) and must expect `PROXYv2` packets. Edit the configuration file (`config.toml`) on Server B accordingly: diff --git a/docs/Setup_examples/XRAY_DOUBLE_HOP.ru.md b/docs/Setup_examples/XRAY_DOUBLE_HOP.ru.md index 3e8d705..8cbdf3a 100644 --- a/docs/Setup_examples/XRAY_DOUBLE_HOP.ru.md +++ b/docs/Setup_examples/XRAY_DOUBLE_HOP.ru.md @@ -248,7 +248,7 @@ sudo systemctl enable xray ## Шаг 2. Установка и настройка telemt на Сервере B (_Нидерланды_) -Установка telemt описана [в основной инструкции](../QUICK_START_GUIDE.ru.md). +Установка telemt описана [в основной инструкции](../Quick_start/QUICK_START_GUIDE.ru.md). Отличие в том, что telemt должен слушать *внутренний* порт (так как 443 занят Xray-сервером), а также ожидать `PROXY` протокол из Xray туннеля. В конфиге `config.toml` прокси (на Сервере B) укажите: