Files
networking-proxy/references/xray-reality-setup-2026-07.md
T
2026-09-06 13:51:04 +00:00

251 lines
9.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Session reference — XRay Reality настройка 2026-07-14
## Окружение
- **US VPS:** vps03.nixg.ru (80.209.240.167), Debian 13 (trixie), root доступ
- **RU VPS:** cloud.ru (vps02, 87.242.100.206), пользователь estorozhenko
- **Клиент:** Android, v2rayNG (v2.2.6)
- **SSH ключи:** /mnt/yandex-disk/.ssh_box/hostkeyVPS
- **Маскировка:** reddit.com (SNI), fingerprint chrome
- **Пинг US→RU:** ~130ms
## Баг heredoc — подробности
**Проблема:** При записи JSON-конфига через SSH с heredoc:
```bash
ssh root@host "cat > /path/config.json << 'EOF'
{ \"key\": \"value\" }
EOF\"
```
Все кавычки в JSON теряются — на сервере оказывается:
```json
{
key: value
}
```
XRay выдаёт ошибку: `invalid character 'l' looking for beginning of object key string` (ожидал кавычку, получил 'l' от `log`).
**Причина:** Двойная обработка shell'ом: сначала локальный shell разбирает кавычки, потом передаёт через SSH, и quoted heredoc (`'EOF'`) не спасает — кавычки съедаются на одном из уровней.
**Проверенное решение — scp:**
```bash
# 1. Напиши локально
write_file(path="/tmp/xray_config.json", content="...")
# 2. Скопируй через SCP
scp -i /path/key -o StrictHostKeyChecking=no /tmp/xray_config.json root@host:/usr/local/etc/xray/config.json
# 3. Перезапусти
ssh -i /path/key root@host "systemctl restart xray"
```
**Альтернатива — Python json.dump() over SSH:**
```bash
ssh root@host "python3 -c '
import json
config = { ... }
with open(\"/usr/local/etc/xray/config.json\", \"w\") as f:
json.dump(config, f, indent=2)
'"
```
Но с этим тоже были проблемы экранирования — scp надёжнее.
## Полный конфиг сервера (рабочий)
```json
{
"log": {
"loglevel": "warning"
},
"inbounds": [
{
"port": 443,
"protocol": "vless",
"settings": {
"clients": [
{
"id": "<uuid>",
"flow": "xtls-rprx-vision"
}
],
"decryption": "none"
},
"streamSettings": {
"network": "tcp",
"security": "reality",
"realitySettings": {
"show": false,
"dest": "reddit.com:443",
"xver": 0,
"serverNames": [
"reddit.com",
"www.reddit.com"
],
"privateKey": "<privateKey>",
"shortIds": [
"<shortId>"
]
}
},
"sniffing": {
"enabled": true,
"destOverride": ["http", "tls", "quic"]
}
}
],
"outbounds": [
{
"protocol": "freedom",
"tag": "direct"
},
{
"protocol": "blackhole",
"tag": "block"
}
]
}
```
## Рабочая ссылка для импорта в v2rayNG
Порт 443 (основной):
```
vless://cf4d32e5-9c19-460e-a5de-f881b01dcfe1@80.209.240.167:443?encryption=none&flow=xtls-rprx-vision&security=reality&sni=reddit.com&fp=chrome&pbk=_ZuQgpScINJVuTRhifNX7cy9MikcNxQNq1vLOZa9ZBE&sid=f8701c8463b82974&type=tcp&headerType=none#XRay-Reality-US
```
Порт 8443 (если 443 блокируется оператором):
```
vless://cf4d32e5-9c19-460e-a5de-f881b01dcfe1@80.209.240.167:8443?encryption=none&flow=xtls-rprx-vision&security=reality&sni=reddit.com&fp=chrome&pbk=_ZuQgpScINJVuTRhifNX7cy9MikcNxQNq1vLOZa9ZBE&sid=f8701c8463b82974&type=tcp&headerType=none#XRay-Reality-US-8443
```
## Диагностика "не подключается"
Когда клиент пишет "connect deadline exceeded" / "Сбой проверки интернет-соединения":
```bash
# 1. Сервер жив?
systemctl status xray
ss -tlnp | grep -E '443|8443'
# 2. Конфиг валиден?
xray run -test -config /usr/local/etc/xray/config.json
# 3. Публичный ключ совпадает?
xray x25519 -i <privateKey> # сравни с тем, что в клиенте
# 4. Сервер выходит в интернет?
curl -s -o /dev/null -w '%{http_code}' https://reddit.com
# 5. Внешняя доступность порта?
# с другого хоста:
nc -w 5 80.209.240.167 443 && echo "OK" || echo "BLOCKED"
# 6. Логи xray — есть ли accepted?
journalctl -u xray --since '30 min ago' --no-pager | grep 'accepted'
```
Если всё выше ок — проблема **на стороне мобильного оператора** (блокировка порта, а не IP).
## Multi-port стратегия
При блокировке 443 порта мобильным оператором — добавить второй inbound на другой порт. Просто скопировать блок `inbounds[0]`, заменив `port`. Перезапустить xray.
Дополнить ссылку для клиента: заменить `@IP:443` на `@IP:8443`.
## ICMP не работает через VLESS+Reality (важно для диагностки)
XRay VLESS с flow=`xtls-rprx-vision` не проксирует **ICMP** (ping/traceroute).
Проксируется только **TCP** и **UDP**.
Когда пользователь пишет "VPN подключился, но пинг не идёт / сайты не грузятся":
- **ping 8.8.8.8** → ❌ не работает через XRay (ICMP)
- **curl https://google.com** → ✅ должно работать (TCP)
- **curl -s ifconfig.me** → ✅ покажет внешний IP сервера
- **nslookup google.com** → ✅ работает (UDP:53)
- **Открыть сайт в браузере** → ✅ должно работать
**Сценарии:**
1. ping не идёт, но curl работает → **VPN в порядке**, это норма
2. ping не идёт и curl не работает → проблема с TCP-маршрутизацией (см. "Диагностика" ниже)
3. tcpdump показывает трёхстороннее рукопожатие (SYN→SYN-ACK→ACK) → соединение с сервером есть, проблему искать в DNS или outbound-маршрутизации
**Live-диагностика через tcpdump (новые соединения):**
```bash
# На сервере — мониторинг порта 443
tcpdump -i any -n port 443 -c 10 -t
# Пользователь в это время пробует открыть сайт
# SYNs не видно → телефон не шлёт трафик (проблема с настройкой клиента)
# Видно SYN→SYN-ACK→ACK → рукопожатие есть, проблема в XRay routing
# Только FIN от старых сессий → старые сессии закрываются, новых нет
```
## Ротация ключей Reality (при смене конфига или утечке)
Периодическая смена ключей Reality повышает безопасность. Полный цикл:
```bash
# 1. Сгенерировать новую пару
xray x25519
# Вывод:
# PrivateKey: SEnziJbX3vDlWEQeGHHYXWa5DP3WXJrydkUJbUCh2FQ
# Password (PublicKey): 7PS-NrEqmF9_AcXrxjladd9zEAIxeE2LpfCAMsEQ_As
# 2. Сгенерировать новый shortId (8 байт hex)
openssl rand -hex 8
# Вывод: b11c31731d6d43d8
# 3. Обновить privateKey в serverNames и shortId в конфиге сервера
# 4. Перезапустить xray
systemctl restart xray
# 5. Передать клиенту:
# - PublicKey из шага 1
# - shortId из шага 2
# (UUID и адрес не меняются)
```
## Режим debug в логах XRay
При проблемах с соединением временно включить debug:
```json
"log": {
"loglevel": "debug"
}
```
После отладки вернуть `"warning"` — debug пишет очень много.
В debug видны:
- `accepted tcp:...` — входящие соединения
- `accepted udp:...:53 [direct]` — DNS-запросы (если есть → клиент умеет резолвить)
- `drain...` — завершение сессий
- Ошибки рукопожатия и таймауты
## Полезные команды
```bash
# Сгенерировать UUID
python3 -c 'import uuid; print(uuid.uuid4())'
# Сгенерировать ключевую пару Reality
xray x25519
# Получить public key из private key
xray x25519 -i <privateKey>
# Прослушиваемые порты
ss -tlnp | grep xray
# Логи xray
journalctl -u xray --since '1 hour ago' --no-pager
```
## Возможные проблемы
1. **XRay запущен, но порт 443 не отображается** — сначала проверь ss. Если там только SSH (22) и exim (25), проверь, что XRay стартовал без ошибок. Причина часто — битый JSON (см. баг heredoc).
2. **Connection refused при curl** — это нормально с локальной машины, если нет маршрута до сервера (там порт 443 открыт только на интерфейсе *:443). Проверять через `nc`.
3. **uuidgen: command not found** — на минимальных Debian-образах uuidgen отсутствует. Использовать `python3 -c 'import uuid; print(uuid.uuid4())'`.
4. **Client "connect deadline exceeded" при работающем сервере** — почти всегда блокировка порта оператором. Сменить порт или попробовать с Wi-Fi.