3X-UIБесплатно

Beeline CDN + XHTTP для 3X-UI

Beeline CDN → Nginx → 3X-UI/Xray на XHTTP packet-up с дополнительными XHTTP-полями и полной диагностикой.

6 минут чтения Обновлено 16.08.2026 Доступ открыт

Переменные

```constructor id="3xui-beeline-vars" ORIGIN_DOMAIN={{ORIGIN_DOMAIN|cdn.example.com}} BEELINE_CDN_DOMAIN={{BEELINE_CDN_DOMAIN|abcd123456.a.trbcdn.net}} XHTTP_PORT={{XHTTP_PORT|2053}} XHTTP_PATH={{XHTTP_PATH|/api/getFile}} CLIENT_UUID={{CLIENT_UUID}}


### DNS origin

Создай A-запись:

`{{ORIGIN_DOMAIN}} → IP VPS`

Проверь:

```constructor id="3xui-beeline-dns"
dig +short {{ORIGIN_DOMAIN}}

Nginx и сертификат

apt update
apt install -y nginx certbot python3-certbot-nginx
mkdir -p /var/www/html

```constructor id="3xui-beeline-cert" certbot certonly --webroot -w /var/www/html -d {{ORIGIN_DOMAIN}} --agree-tos --register-unsafely-without-email


### Origin Nginx

```constructor id="3xui-beeline-nginx"
cat > /etc/nginx/sites-available/beeline-cdn <<'CONF'
server {
    listen 80;
    server_name {{ORIGIN_DOMAIN}};
    root /var/www/html;

    location /.well-known/acme-challenge/ { }
    location / { return 301 https://$host$request_uri; }
}

server {
    listen 443 ssl;
    server_name {{ORIGIN_DOMAIN}};

    ssl_certificate     /etc/letsencrypt/live/{{ORIGIN_DOMAIN}}/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/{{ORIGIN_DOMAIN}}/privkey.pem;

    location {{XHTTP_PATH|/api/getFile}} {
        proxy_pass http://127.0.0.1:{{XHTTP_PORT|2053}};
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Connection "";
        proxy_request_buffering off;
        proxy_buffering off;
        chunked_transfer_encoding on;
        proxy_read_timeout 300s;
        proxy_send_timeout 300s;
    }

    location / {
        return 404;
    }
}
CONF

ln -sfn /etc/nginx/sites-available/beeline-cdn /etc/nginx/sites-enabled/beeline-cdn
nginx -t && systemctl reload nginx

Inbound 3X-UI

Создай:

Поле Значение
Protocol VLESS
Listen IP 127.0.0.1
Port {{XHTTP_PORT}}
Transport XHTTP
Path {{XHTTP_PATH}}
Mode packet-up
Security none

Добавь клиента и сохрани UUID.

Ресурс Beeline CDN

Origin:

```constructor id="3xui-beeline-origin" https://{{ORIGIN_DOMAIN}}


Кеширование XHTTP отключи.

Сохрани технический домен:

```constructor id="3xui-beeline-tech-domain"
{{BEELINE_CDN_DOMAIN}}

Проверь:

```constructor id="3xui-beeline-tech-dns" dig +short {{BEELINE_CDN_DOMAIN}}


### Дождись развёртывания ресурса

Новый CDN-ресурс может некоторое время отвечать `403`.

Проверяй:

```constructor id="3xui-beeline-ready-check"
curl -sk -o /dev/null -w "%{http_code}\n" https://{{BEELINE_CDN_DOMAIN}}/

По исходной рабочей схеме ресурс может разворачиваться до 30 минут. Не меняй конфиг только из-за раннего 403. Продолжай после того, как корень CDN начинает отвечать ожидаемо.

Backup

SQLite:

apt install -y sqlite3 jq
mkdir -p /root/3xui-backups
sqlite3 /etc/x-ui/x-ui.db ".backup '/root/3xui-backups/pre-beeline-$(date +%Y%m%d-%H%M%S).db'"

Stream Settings

```constructor id="3xui-beeline-stream-json" { "network": "xhttp", "security": "none", "externalProxy": [ { "forceTls": "tls", "dest": "{{BEELINE_CDN_DOMAIN}}", "port": 443, "remark": "CDN" } ], "xhttpSettings": { "path": "{{XHTTP_PATH|/api/getFile}}", "host": "", "mode": "packet-up", "xPaddingBytes": "100-1000", "xPaddingObfsMode": true, "xPaddingKey": "hash", "xPaddingHeader": "X-Client-Version", "xPaddingPlacement": "queryInHeader", "xPaddingMethod": "tokenish", "seqPlacement": "query", "seqKey": "chunk_id", "noSSEHeader": false, "scMaxBufferedPosts": 100, "scStreamUpServerSecs": "20-80", "serverMaxHeaderBytes": 0, "noGRPCHeader": false, "enableXmux": true, "xmux": { "maxConcurrency": "32-64", "maxConnections": 0, "cMaxReuseTimes": 1000, "hMaxRequestTimes": "600-900", "hMaxReusableSecs": "100", "hKeepAlivePeriod": 20000 } } }


### Запиши JSON в файл

```constructor id="3xui-beeline-json-file"
cat > /root/beeline-stream-settings.json <<'JSON'
{
  "network": "xhttp",
  "security": "none",
  "externalProxy": [
    {
      "forceTls": "tls",
      "dest": "{{BEELINE_CDN_DOMAIN}}",
      "port": 443,
      "remark": "CDN"
    }
  ],
  "xhttpSettings": {
    "path": "{{XHTTP_PATH|/api/getFile}}",
    "host": "",
    "mode": "packet-up",
    "xPaddingBytes": "100-1000",
    "xPaddingObfsMode": true,
    "xPaddingKey": "hash",
    "xPaddingHeader": "X-Client-Version",
    "xPaddingPlacement": "queryInHeader",
    "xPaddingMethod": "tokenish",
    "seqPlacement": "query",
    "seqKey": "chunk_id",
    "noSSEHeader": false,
    "scMaxBufferedPosts": 100,
    "scStreamUpServerSecs": "20-80",
    "serverMaxHeaderBytes": 0,
    "noGRPCHeader": false,
    "enableXmux": true,
    "xmux": {
      "maxConcurrency": "32-64",
      "maxConnections": 0,
      "cMaxReuseTimes": 1000,
      "hMaxRequestTimes": "600-900",
      "hMaxReusableSecs": "100",
      "hKeepAlivePeriod": 20000
    }
  }
}
JSON

SQLite

```constructor id="3xui-beeline-sqlite-write" python3 - <<'PY' import json, sqlite3 DB="/etc/x-ui/x-ui.db" PORT={{XHTTP_PORT|2053}} with open("/root/beeline-stream-settings.json", "r", encoding="utf-8") as f: value=json.dumps(json.load(f), separators=(",",":")) con=sqlite3.connect(DB) cur=con.execute("UPDATE inbounds SET stream_settings=? WHERE port=?", (value, PORT)) con.commit() print("updated:", cur.rowcount) con.close() PY


Нужно:

`updated: 1`

### PostgreSQL

Если backend PostgreSQL:

```bash
jq -c . /root/beeline-stream-settings.json

```constructor id="3xui-beeline-pg-write" sudo -u postgres psql -d {{POSTGRES_DB|xui}} <<'SQL' UPDATE inbounds SET stream_settings = $j$<ВСТАВЬ_JSON_ИЗ_JQ>$j$ WHERE port={{XHTTP_PORT|2053}}; SQL


### Перезапуск

```bash
x-ui restart-xray
sleep 6
x-ui status | cat

```constructor id="3xui-beeline-port-listen" ss -tlnp | grep ':{{XHTTP_PORT|2053}}'


### Проверка Xray

```constructor id="3xui-beeline-test-local"
curl -s -o /dev/null -w '%{http_code}\n' \
  "http://127.0.0.1:{{XHTTP_PORT|2053}}{{XHTTP_PATH|/api/getFile}}/"

Проверка origin

```constructor id="3xui-beeline-test-origin" curl -sk -o /dev/null -w '%{http_code}\n' \ "https://{{ORIGIN_DOMAIN}}{{XHTTP_PATH|/api/getFile}}/"


### Проверка CDN

```constructor id="3xui-beeline-test-cdn"
curl -sk -o /dev/null -w '%{http_code}\n' \
  "https://{{BEELINE_CDN_DOMAIN}}{{XHTTP_PATH|/api/getFile}}/"

Проверка obfuscation

```constructor id="3xui-beeline-obfs-check" curl -sk -D - -o /dev/null --max-time 20 \ "https://{{BEELINE_CDN_DOMAIN}}{{XHTTP_PATH|/api/getFile}}/" \ | grep -i 'x-client-version'


### Проверка сохранённого stream_settings

```constructor id="3xui-beeline-db-check"
python3 - <<'PY'
import sqlite3, json
PORT={{XHTTP_PORT|2053}}
con=sqlite3.connect("/etc/x-ui/x-ui.db")
row=con.execute("SELECT stream_settings FROM inbounds WHERE port=?", (PORT,)).fetchone()
print(json.dumps(json.loads(row[0]), indent=2, ensure_ascii=False) if row else "NOT FOUND")
con.close()
PY

Проверь наличие:

  • externalProxy;
  • xPaddingObfsMode;
  • xPaddingHeader;
  • seqKey;
  • xmux.

Клиентская ссылка

```constructor id="3xui-beeline-vless-link" vless://{{CLIENT_UUID}}@{{BEELINE_CDN_DOMAIN}}:443?encryption=none&security=tls&type=xhttp&path=%2Fapi%2FgetFile&mode=packet-up&host=&fp=edge&sni={{BEELINE_CDN_DOMAIN}}&alpn=h2%2Chttp%2F1.1&extra=%7B%22mode%22%3A%22packet-up%22%2C%22seqKey%22%3A%22chunk_id%22%2C%22seqPlacement%22%3A%22query%22%2C%22xPaddingBytes%22%3A%22100-1000%22%2C%22xPaddingHeader%22%3A%22X-Client-Version%22%2C%22xPaddingKey%22%3A%22hash%22%2C%22xPaddingMethod%22%3A%22tokenish%22%2C%22xPaddingObfsMode%22%3Atrue%2C%22xPaddingPlacement%22%3A%22queryInHeader%22%2C%22xmux%22%3A%7B%22cMaxReuseTimes%22%3A1000%2C%22hKeepAlivePeriod%22%3A20000%2C%22hMaxRequestTimes%22%3A%22600-900%22%2C%22hMaxReusableSecs%22%3A%22100%22%2C%22maxConcurrency%22%3A%2232-64%22%2C%22maxConnections%22%3A0%7D%7D#Beeline-CDN


Если `XHTTP_PATH` отличается от `/api/getFile`, URL-encode новый path и замени параметр `path`.

Не меняй `extra` отдельно от серверных `xPadding/xmux`: обе стороны должны использовать один набор параметров.

### После прямого изменения БД

Не нажимай `Save` в старом UI inbound, если интерфейс не показывает дополнительные XHTTP-поля. Панель может пересобрать `stream_settings` без них.

### Если не работает

`000/502` на локальном Xray:

```bash
x-ui restart-xray
x-ui status | cat

404 на origin — не совпадает Nginx location и XHTTP path.

200 с обычной HTML-страницей на XHTTP path — сработал неправильный location.

403 на CDN — проверь готовность CDN и сохранность дополнительных XHTTP-полей.

504 — CDN не дождался origin.

Проверка DNS:

constructor id="3xui-beeline-final-dns" dig +short {{BEELINE_CDN_DOMAIN}}

Финальный порядок теста:

Xray → Nginx origin → Beeline CDN → реальный клиент