# Recommended Xray Inbound Configuration This reference covers the best protocol/transport combinations for security and performance, and the API payloads to create them via the x-ui REST API. ## Protocol Recommendation (ranked) | Rank | Protocol | Transport | TLS | Why | |------|----------|-----------|-----|-----| | ✅ Best | VLESS | WebSocket | TLS (via Nginx) | CDN-friendly, low overhead, widely supported | | ✅ Best | VLESS | gRPC | TLS (via Nginx) | Multiplexed, low latency, CDN-friendly | | Good | VLESS | TCP | XTLS/Reality | No CDN needed, excellent performance, anti-detection | | Good | VMess | WebSocket | TLS (via Nginx) | Broad client support | | Avoid | VMess | TCP | none | Detectable, no forward secrecy | | Avoid | Shadowsocks | — | — | Blocked in many regions | **Default recommendation**: VLESS + WebSocket + TLS, proxied through Nginx. - Panel port stays on `127.0.0.1` (localhost-only) - Nginx terminates TLS on 443 and forwards to the inbound port on `127.0.0.1` - Inbound port also stays localhost-only (e.g. `127.0.0.1:10000`) --- ## Step-by-Step: Create VLESS + WS + TLS Inbound ### 1. Collect inbound parameters Ask the user (or use defaults): | Field | Default | |-------|---------| | Inbound port | `10000` | | WS path | `/ws/` (use a random string for security) | | Remark | `vless-ws` | ### 2. Create inbound via x-ui API The x-ui panel exposes a REST API at `http://127.0.0.1:`. Authenticate with a session cookie first, then POST the inbound. ```bash # 1. Login and save session cookie PANEL_USER=$(bash /repo/common-skills/tools/kp-get.sh "" UserName) PANEL_PASS=$(bash /repo/common-skills/tools/kp-get.sh "" Password) ssh -i -p @ " curl -sc /tmp/xui-cookie.txt \ -X POST http://127.0.0.1:login \ -H 'Content-Type: application/json' \ -d '{\"username\":\"'\"$PANEL_USER\"'\",\"password\":\"'\"$PANEL_PASS\"'\"}' " # 2. Generate a UUID for the client UUID=$(ssh -i -p @ "cat /proc/sys/kernel/random/uuid") # 3. Create VLESS + WebSocket inbound ssh -i -p @ " curl -sb /tmp/xui-cookie.txt \ -X POST http://127.0.0.1:xui/API/inbounds/add \ -H 'Content-Type: application/json' \ -d '{ \"remark\": \"vless-ws\", \"enable\": true, \"protocol\": \"vless\", \"listen\": \"127.0.0.1\", \"port\": 10000, \"settings\": \"{\\\"clients\\\":[{\\\"id\\\":\\\"'\"$UUID\"'\\\",\\\"flow\\\":\\\"\\\"}],\\\"decryption\\\":\\\"none\\\"}\", \"streamSettings\": \"{\\\"network\\\":\\\"ws\\\",\\\"wsSettings\\\":{\\\"path\\\":\\\"/ws/\\\"}}\", \"sniffing\": \"{\\\"enabled\\\":true,\\\"destOverride\\\":[\\\"http\\\",\\\"tls\\\"]}\" }' " ``` ### 3. Add Nginx location for the WS path Append to the existing Nginx config (`/etc/nginx/conf.d/x-ui.conf`): ```nginx location /ws/ { proxy_pass http://127.0.0.1:10000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_read_timeout 86400s; } ``` Reload Nginx: `systemctl reload nginx` ### 4. Report client config Output the connection info for the user to import into their client (v2rayN, Clash, etc.): ``` Protocol : VLESS Address : Port : 443 UUID : Transport: WebSocket Path : /ws/ TLS : TLS SNI : ``` Or generate a VLESS share link: ``` vless://@:443?encryption=none&security=tls&type=ws&path=%2Fws%2F&sni=#vless-ws ``` --- ## Alternative: VLESS + Reality (no CDN, no domain needed) Reality is the best option when no domain is available. It mimics a real TLS handshake against a target site. ```bash # Generate Reality key pair inside the container/host ssh -i -p @ \ "docker exec x-ui xray x25519" # Docker # or: xray x25519 # native ``` Save the `Private key` and `Public key` output. Create inbound via API (replace keys and port): ```json { "remark": "vless-reality", "enable": true, "protocol": "vless", "listen": "", "port": 443, "settings": "{\"clients\":[{\"id\":\"\",\"flow\":\"xtls-rprx-vision\"}],\"decryption\":\"none\"}", "streamSettings": "{\"network\":\"tcp\",\"security\":\"reality\",\"realitySettings\":{\"show\":false,\"dest\":\"www.microsoft.com:443\",\"serverNames\":[\"www.microsoft.com\"],\"privateKey\":\"\",\"shortIds\":[\"\"]}}" } ``` Client connection info: ``` Protocol : VLESS Address : Port : 443 UUID : Flow : xtls-rprx-vision Transport : TCP Security : Reality PublicKey : SNI : www.microsoft.com ``` > Note: Reality listens on `0.0.0.0:443` (must be public). This is intentional — it's the proxy traffic port, not the panel. --- ## Security Hardening for Inbounds - Always set `"listen": "127.0.0.1"` for WS/gRPC inbounds (Nginx handles public exposure). - Use a random UUID per client; rotate periodically. - Use a non-obvious WS path (e.g. `/a3f9k2/` not `/ws/`). - Enable sniffing (`destOverride: ["http","tls"]`) to block DNS leaks. - For Reality, use a high-traffic legitimate domain as `dest` (e.g. `www.microsoft.com`, `www.apple.com`).