Add all project files, configs, scripts and results
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
383
xray_config.md
Normal file
383
xray_config.md
Normal file
@@ -0,0 +1,383 @@
|
||||
# Xray Infrastructure Configuration
|
||||
|
||||
## Servers
|
||||
|
||||
| Role | IP | Domain | OS | Xray | x-ui |
|
||||
|------|-----|--------|-----|------|------|
|
||||
| Local (client) | 95.165.85.65 | — | Ubuntu, kernel 6.8.0-94 | 25.10.15 | 2.8.10 |
|
||||
| Remote (server) | 83.99.190.32 | share.alogins.net | Ubuntu 24.04.3 (LXD container) | 26.2.6 | 2.8.10 |
|
||||
|
||||
---
|
||||
|
||||
## Access Credentials
|
||||
|
||||
### Remote server SSH
|
||||
- Host: `83.99.190.32`
|
||||
- User: `juris`
|
||||
- LXD container access: `lxc exec xray -- <command>`
|
||||
|
||||
### Remote 3x-ui panel
|
||||
- URL: `https://share.alogins.net:16627/gBdsRLtVZdgZ63wmVR/`
|
||||
- Username: `xrayadmin`
|
||||
- Password: `Admin2026!`
|
||||
|
||||
### Local x-ui panel
|
||||
- URL: `http://127.0.0.1:58959/gnYCNq4EbYukS5qtOe/`
|
||||
- Username: `3ZHPoQdd89`
|
||||
- Password: `1c1QUbKhQP`
|
||||
|
||||
### Local server sudo
|
||||
- User: `alvis`
|
||||
|
||||
---
|
||||
|
||||
## Reality Keys (shared keypair)
|
||||
|
||||
| Key | Value |
|
||||
|-----|-------|
|
||||
| Private key (server) | `KJfhenZvJV1kXwv4kDC8NPBtMUY0RR8lFrxsxfXfFmY` |
|
||||
| Public key (client) | `58Iqd6LuWXgvjAgo92-7KURhTp0Vj79yGF81l_iuvTw` |
|
||||
|
||||
### juris-xhttp (ACTIVE — XHTTP+Reality)
|
||||
| Field | Value |
|
||||
|-------|-------|
|
||||
| UUID | `6e422ab5-070a-43f6-8241-38cd56d23d24` |
|
||||
| Short ID | `6036d37d12c443c4` |
|
||||
| XHTTP path | `/xt-6036d37d` |
|
||||
|
||||
### juris-reality (FALLBACK — TCP+Reality+Vision)
|
||||
| Field | Value |
|
||||
|-------|-------|
|
||||
| UUID | `64522a14-54aa-4b3c-8071-8c8b17aa1f08` |
|
||||
| Short ID | `48b4c16249ad44ff` |
|
||||
|
||||
---
|
||||
|
||||
## SNI Test Results
|
||||
|
||||
Reality dest on remote server: `www.delfi.lv:443`
|
||||
|
||||
| SNI | Status | Avg Latency | Download | Upload |
|
||||
|-----|--------|-------------|----------|--------|
|
||||
| `www.delfi.lv` | **ACTIVE** | 121ms | 44.79 Mbps | 33.90 Mbps |
|
||||
| `www.lmt.lv` | OK | 133ms | 50.58 Mbps | 37.33 Mbps |
|
||||
| `www.inbox.lv` | OK | 121ms | 45.48 Mbps | 32.98 Mbps |
|
||||
| `e-klase.lv` | OK | 121ms | 54.84 Mbps | 29.58 Mbps |
|
||||
| `www.tele2.lv` | FAIL (dest mismatch) | — | — | — |
|
||||
| `www.lsm.lv` | FAIL (dest mismatch) | — | — | — |
|
||||
| `share.alogins.net` | FAIL (dest mismatch) | — | — | — |
|
||||
| `www.microsoft.com` | FAIL (dest mismatch) | — | — | — |
|
||||
|
||||
Full benchmark results: `sni_test_results.md`
|
||||
|
||||
---
|
||||
|
||||
## LXD Port Forwarding (remote host → container)
|
||||
|
||||
```
|
||||
proxy-443: tcp:0.0.0.0:443 → tcp:127.0.0.1:443
|
||||
proxy-16627: tcp:0.0.0.0:16627 → tcp:127.0.0.1:16627
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Remote Server Config (VLESS+XHTTP+Reality inbound) — ACTIVE
|
||||
|
||||
Server: `share.alogins.net` / LXD container `xray` (10.187.159.41)
|
||||
**Winner of comparative test**: lowest latency (142ms avg, 225ms P95), best upload.
|
||||
|
||||
```json
|
||||
{
|
||||
"listen": "0.0.0.0",
|
||||
"port": 443,
|
||||
"protocol": "vless",
|
||||
"tag": "inbound-443",
|
||||
"settings": {
|
||||
"clients": [
|
||||
{
|
||||
"id": "6e422ab5-070a-43f6-8241-38cd56d23d24",
|
||||
"email": "juris-xhttp",
|
||||
"flow": ""
|
||||
},
|
||||
{
|
||||
"id": "64522a14-54aa-4b3c-8071-8c8b17aa1f08",
|
||||
"email": "juris-reality-legacy",
|
||||
"flow": ""
|
||||
}
|
||||
],
|
||||
"decryption": "none"
|
||||
},
|
||||
"streamSettings": {
|
||||
"network": "xhttp",
|
||||
"security": "reality",
|
||||
"realitySettings": {
|
||||
"dest": "www.delfi.lv:443",
|
||||
"serverNames": ["www.delfi.lv", "www.lmt.lv", "www.inbox.lv", "e-klase.lv"],
|
||||
"privateKey": "KJfhenZvJV1kXwv4kDC8NPBtMUY0RR8lFrxsxfXfFmY",
|
||||
"shortIds": ["48b4c16249ad44ff", "6036d37d12c443c4", ""],
|
||||
"show": false
|
||||
},
|
||||
"xhttpSettings": {
|
||||
"path": "/xt-6036d37d",
|
||||
"host": "",
|
||||
"mode": "auto",
|
||||
"extra": {
|
||||
"xPaddingBytes": "100-1000",
|
||||
"xmux": {
|
||||
"maxConcurrency": "16-32",
|
||||
"maxConnections": 0,
|
||||
"cMaxReuseTimes": "64-128",
|
||||
"cMaxLifetimeMs": 0,
|
||||
"hMaxRequestTimes": "600-900",
|
||||
"hMaxReusableSecs": "1800-3000"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Local Server Config (full live xray configuration)
|
||||
|
||||
Config path: `/usr/local/x-ui/bin/config.json`
|
||||
DB path: `/etc/x-ui/x-ui.db` (template stored in `xrayTemplateConfig` setting)
|
||||
|
||||
### Outbounds
|
||||
|
||||
| Tag | Protocol | Destination | Security | Fingerprint | Status |
|
||||
|-----|----------|-------------|----------|-------------|--------|
|
||||
| `direct` | freedom | — | — | — | Default |
|
||||
| `blocked` | blackhole | — | — | — | Block |
|
||||
| `socks` | socks | 127.0.0.1:1081 | — | — | Local proxy |
|
||||
| `AMS-Server` | trojan | 45.32.235.202:443 | reality (SNI: www.nvidia.com) | chrome | Active |
|
||||
| `juris-reality` | vless | share.alogins.net:443 | TCP+reality (SNI: www.delfi.lv) | chrome | Fallback, no routing rules |
|
||||
| `juris-xhttp` | vless | share.alogins.net:443 | XHTTP+reality (SNI: www.delfi.lv, Host: www.delfi.lv) | chrome | **PRIMARY**, no routing rules |
|
||||
| `juris-xhttp-firefox` | vless | share.alogins.net:443 | XHTTP+reality (SNI: www.delfi.lv, Host: www.delfi.lv) | firefox | Alternate fingerprint, no routing rules |
|
||||
| `juris-xhttp-safari` | vless | share.alogins.net:443 | XHTTP+reality (SNI: www.delfi.lv, Host: www.delfi.lv) | safari | Alternate fingerprint, no routing rules |
|
||||
|
||||
### Inbounds
|
||||
|
||||
| Tag | Protocol | Listen | Port | Notes |
|
||||
|-----|----------|--------|------|-------|
|
||||
| `api` | tunnel | 127.0.0.1 | 62789 | Internal API |
|
||||
| `inbound-127.0.0.1:8445` | vless | 127.0.0.1 | 8445 | XHTTP stream, 4 clients |
|
||||
| `inbound-56928` | mixed | 0.0.0.0 | 56928 | SOCKS/HTTP proxy, routes → AMS-Server |
|
||||
|
||||
### Routing Rules
|
||||
|
||||
| # | Match | Outbound |
|
||||
|---|-------|----------|
|
||||
| 1 | inboundTag: `inbound-56928` | `AMS-Server` |
|
||||
| 2 | inboundTag: `api` | `api` |
|
||||
| 3 | ip: `geoip:private` | `blocked` |
|
||||
| 4 | protocol: `bittorrent` | `blocked` |
|
||||
| 5 | domain: `ext:geosite_RU.dat:ru-blocked` + inbound `8445` | `AMS-Server` |
|
||||
|
||||
### VLESS Clients (inbound-127.0.0.1:8445)
|
||||
|
||||
| Email | UUID | Comment |
|
||||
|-------|------|---------|
|
||||
| 36npz8zz | 13a01d7c-9ca7-4ee6-83d8-4c59907b13d1 | ipad pro |
|
||||
| 4camw53nd | 108fdf6b-f8e4-4e1a-9bbe-b7c1fa9fffa0 | pixel |
|
||||
| y3673rul | 584cba3d-2d43-464a-9b29-67e02adc092d | iphone promax |
|
||||
| j5x2285y | f6781d19-cf77-4f8f-9114-0e612aa3081c | AlinaSt |
|
||||
|
||||
### juris-reality Outbound (full config)
|
||||
|
||||
```json
|
||||
{
|
||||
"tag": "juris-reality",
|
||||
"protocol": "vless",
|
||||
"settings": {
|
||||
"vnext": [
|
||||
{
|
||||
"address": "share.alogins.net",
|
||||
"port": 443,
|
||||
"users": [
|
||||
{
|
||||
"id": "64522a14-54aa-4b3c-8071-8c8b17aa1f08",
|
||||
"flow": "xtls-rprx-vision",
|
||||
"encryption": "none"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"streamSettings": {
|
||||
"network": "tcp",
|
||||
"security": "reality",
|
||||
"realitySettings": {
|
||||
"fingerprint": "chrome",
|
||||
"serverName": "www.delfi.lv",
|
||||
"publicKey": "58Iqd6LuWXgvjAgo92-7KURhTp0Vj79yGF81l_iuvTw",
|
||||
"shortId": "48b4c16249ad44ff",
|
||||
"spiderX": "/"
|
||||
},
|
||||
"tcpSettings": {
|
||||
"header": { "type": "none" }
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### AMS-Server Outbound (existing)
|
||||
|
||||
```json
|
||||
{
|
||||
"tag": "AMS-Server",
|
||||
"protocol": "trojan",
|
||||
"settings": {
|
||||
"servers": [
|
||||
{
|
||||
"address": "45.32.235.202",
|
||||
"port": 443,
|
||||
"password": "z5Y2tMeDs1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"streamSettings": {
|
||||
"network": "tcp",
|
||||
"security": "reality",
|
||||
"realitySettings": {
|
||||
"publicKey": "J37AuaLzZYRTQZ-pxUpbIndo15EpoY1lhnAXZ1rUFnQ",
|
||||
"fingerprint": "chrome",
|
||||
"serverName": "www.nvidia.com",
|
||||
"shortId": "22",
|
||||
"spiderX": "/"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## File Paths
|
||||
|
||||
### Local server
|
||||
| Path | Purpose |
|
||||
|------|---------|
|
||||
| `/usr/local/x-ui/bin/config.json` | Live xray config (auto-generated by x-ui, do NOT edit directly) |
|
||||
| `/usr/local/x-ui/bin/xray-linux-amd64` | Xray binary |
|
||||
| `/usr/local/x-ui/x-ui` | x-ui panel binary |
|
||||
| `/etc/x-ui/x-ui.db` | x-ui database (settings, inbounds, users) |
|
||||
| `/home/alvis/ai-xray/venv/` | Python venv with paramiko for SSH |
|
||||
|
||||
### Remote server (inside LXD container "xray")
|
||||
| Path | Purpose |
|
||||
|------|---------|
|
||||
| `/usr/local/x-ui/bin/config.json` | Live xray config (auto-generated) |
|
||||
| `/usr/local/x-ui/bin/xray-linux-amd64` | Xray binary |
|
||||
| `/etc/x-ui/x-ui.db` | x-ui database |
|
||||
|
||||
---
|
||||
|
||||
## How to Route Traffic Through juris-reality
|
||||
|
||||
Currently `juris-reality` has no routing rules. To use it, add a rule to the xray template in the DB:
|
||||
|
||||
**Route specific domains:**
|
||||
```json
|
||||
{
|
||||
"type": "field",
|
||||
"domain": ["example.com", "example.org"],
|
||||
"outboundTag": "juris-reality"
|
||||
}
|
||||
```
|
||||
|
||||
**Route all SOCKS proxy traffic (replaces AMS-Server):**
|
||||
```json
|
||||
{
|
||||
"type": "field",
|
||||
"inboundTag": ["inbound-56928"],
|
||||
"outboundTag": "juris-reality"
|
||||
}
|
||||
```
|
||||
|
||||
**Route Russian-blocked domains through juris-reality instead of AMS-Server:**
|
||||
Change outboundTag in rule #5 from `AMS-Server` to `juris-reality`.
|
||||
|
||||
---
|
||||
|
||||
## Updating Xray Config via x-ui REST API (no sudo)
|
||||
|
||||
`config.json` is auto-generated by x-ui from the DB template. **Never edit it directly.**
|
||||
|
||||
### Step-by-step
|
||||
|
||||
**1. Authenticate:**
|
||||
```bash
|
||||
curl -s -c /tmp/xui-cookie.txt -X POST \
|
||||
'http://127.0.0.1:58959/gnYCNq4EbYukS5qtOe/login' \
|
||||
-H 'Content-Type: application/x-www-form-urlencoded' \
|
||||
-d 'username=3ZHPoQdd89&password=1c1QUbKhQP'
|
||||
```
|
||||
|
||||
**2. Read current xray template:**
|
||||
```bash
|
||||
curl -s -b /tmp/xui-cookie.txt -X POST \
|
||||
'http://127.0.0.1:58959/gnYCNq4EbYukS5qtOe/panel/xray/'
|
||||
```
|
||||
Returns `{"success":true,"obj":"{ \"xraySetting\": {...}, \"inboundTags\": [...] }"}`.
|
||||
The `obj` value is a JSON string containing the full xray template under the `xraySetting` key.
|
||||
|
||||
**3. Update xray template:**
|
||||
```bash
|
||||
curl -s -b /tmp/xui-cookie.txt -X POST \
|
||||
'http://127.0.0.1:58959/gnYCNq4EbYukS5qtOe/panel/xray/update' \
|
||||
-d 'xraySetting=<URL-encoded JSON of the full xray template>'
|
||||
```
|
||||
|
||||
The key detail: use **form-urlencoded** with a single field `xraySetting` whose value is the full xray template JSON string. This is the `xraySetting` object from step 2 (the inner JSON, not the wrapper).
|
||||
|
||||
**4. Restart xray to apply:**
|
||||
```bash
|
||||
curl -s -b /tmp/xui-cookie.txt -X POST \
|
||||
'http://127.0.0.1:58959/gnYCNq4EbYukS5qtOe/panel/api/server/restartXrayService'
|
||||
```
|
||||
|
||||
### Python example (recommended)
|
||||
|
||||
```python
|
||||
import requests, json
|
||||
|
||||
BASE = "http://127.0.0.1:58959/gnYCNq4EbYukS5qtOe"
|
||||
s = requests.Session()
|
||||
|
||||
# Login
|
||||
s.post(f"{BASE}/login", data={"username": "3ZHPoQdd89", "password": "1c1QUbKhQP"})
|
||||
|
||||
# Read current template
|
||||
r = s.post(f"{BASE}/panel/xray/")
|
||||
obj = json.loads(r.json()["obj"])
|
||||
xray = obj["xraySetting"]
|
||||
|
||||
# Modify (example: change SNI)
|
||||
for ob in xray["outbounds"]:
|
||||
if ob.get("tag") == "juris-reality":
|
||||
ob["streamSettings"]["realitySettings"]["serverName"] = "www.delfi.lv"
|
||||
|
||||
# Write back (form field, NOT JSON body)
|
||||
s.post(f"{BASE}/panel/xray/update", data={"xraySetting": json.dumps(xray)})
|
||||
|
||||
# Restart xray
|
||||
s.post(f"{BASE}/panel/api/server/restartXrayService")
|
||||
```
|
||||
|
||||
### API gotchas
|
||||
|
||||
| Endpoint | Method | Works? | Notes |
|
||||
|----------|--------|--------|-------|
|
||||
| `POST /panel/xray/update` | form-urlencoded `xraySetting=<json>` | **Yes** | Correct way to persist template changes |
|
||||
| `POST /panel/xray/update` | JSON body `{"xraySetting": ...}` | No | Returns "unexpected end of JSON input" |
|
||||
| `POST /panel/setting/update` | any | No | Accepts request but silently ignores `xrayTemplateConfig` |
|
||||
| `GET /panel/setting/getDefaultJsonConfig` | — | — | Returns factory defaults, not actual config |
|
||||
| `GET /panel/api/server/getConfigJson` | — | Read-only | Returns live running xray config |
|
||||
| `xray api ado` CLI | — | Ephemeral | Adds outbound to running instance only, lost on restart |
|
||||
|
||||
---
|
||||
|
||||
## Important Notes
|
||||
|
||||
- The `xray api ado` CLI can add outbounds to the running instance (ephemeral, lost on restart). Requires full-config JSON format: `{"outbounds": [{...}]}`.
|
||||
Reference in New Issue
Block a user