Install
$ agentstack add skill-xkhoshizora-cross-border-network-best-practices-3x-ui-best-practices ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ● Network access Used
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
3x-ui Best Practices
Use this skill to work with 3x-ui as a full Xray control-plane lifecycle: install, harden, configure inbounds/clients, validate links, and troubleshoot failures.
Operating Rules
- Treat every panel as production unless the user says otherwise.
- Never call destructive or disruptive endpoints without explicit user approval: delete, bulk delete, reset traffic, restart/stop Xray, update panel, import DB, restore DB, regenerate live TLS/Reality secrets, or overwrite settings.
- Never write API tokens, Reality private keys, client UUIDs/passwords/auth values, subscription IDs, Telegram IDs, or live URLs containing secrets into committed artifacts unless the user explicitly asks for those exact values.
- Prefer
/panel/api/inbounds/options,/panel/api/inbounds/list/slim, and paged client lists for discovery. Fetch full inbound/client details only when the task requires secret-bearing fields. - Prefer client-first APIs (
/panel/api/clients/add,/update/:email,/bulkCreate,/bulkAttach,/bulkDetach) over hand-editingsettings.clients[]inside an inbound. - Use nested JSON for
settings,streamSettings, andsniffing; 3x-ui still accepts legacy JSON-encoded strings, but nested objects are the modern API shape. - If using Bearer auth, assume it is reliable for
/panel/api/*. Some deployed versions and source routes keep/panel/setting/*and/panel/xray/*behind UI session + CSRF even when OpenAPI describes global security.
Discovery Workflow
- Identify the panel base path and OpenAPI URL, usually
/panel/api/openapi.jsonor//panel/api/openapi.json. - Read the OpenAPI first, then confirm against source or live responses if behavior matters.
- Inventory current topology with read-only calls:
GET /panel/api/inbounds/optionsGET /panel/api/inbounds/list/slimGET /panel/api/clients/list/paged?page=1&pageSize=25- optional status:
GET /panel/api/server/status
- Summarize protocol, port, transport, security, sniffing, client count, and whether an inbound is
tlsFlowCapable. - For any proposed write, present the exact payload and the rollback/validation plan before executing.
Fresh Install Workflow
- Gather target OS, architecture, provider firewall rules, desired panel port/path, domain/SSL availability, and whether Docker is required.
- Choose installation mode:
- Native one-line install for a normal Linux VPS where the user wants the upstream management menu.
- Docker Compose when repeatability, simple backup, or isolated filesystem layout matters.
- Docker host networking when many inbound ports will be created dynamically.
- Before install, open SSH and intended panel/inbound ports in the provider firewall and local firewall.
- Install 3x-ui, then immediately rotate admin credentials, set a custom web base path, enable HTTPS for the panel when a domain/cert is available, and consider 2FA.
- If using Docker with Fail2ban/IP limits, include
NET_ADMINandNET_RAW. If not using host networking, publish every inbound port explicitly. - Verify with: panel login, service/container status,
/panel/api/openapi.json,/panel/api/server/status, and a simple inbound/client link.
Upgrade and Backup Workflow
- Back up before any upgrade, migration, or risky write. The SQLite DB is
/etc/x-ui/x-ui.db(native) or the./db/volume (Docker); also save./cert/when certificates are local. Prefer backing up with the service stopped, or use the panel/x-uimenu backup. - Native upgrade: rerun the official installer or use the
x-uimenu update entry. Docker upgrade:docker compose pull && docker compose up -dwhile reusing the same./db/and./cert/volumes. - Record the prior version/image tag so a misbehaving migration can be rolled back to a known-good state.
- After upgrade, confirm
/panel/api/server/status, check that inbound/client counts are unchanged, and re-test one client link. Treat panel update and DB import/restore as high-risk: confirm with the user first.
Configuration Guidance
Prefer these defaults unless the user's network constraints say otherwise:
- Public direct server, single 443 entry: VLESS over TCP with REALITY,
settings.decryption="none",settings.encryption="none", sniffing enabled forhttpandtlsat minimum. - CDN/reverse-proxy path routing: VLESS/VMess/Trojan over WebSocket, gRPC, HTTPUpgrade, or XHTTP with TLS. Do not put REALITY behind a CDN reverse proxy.
- XTLS Vision flow: use only on VLESS over TCP with
securityoftlsorreality; 3x-ui exposestlsFlowCapablefor this exact gate. - Fallbacks: only use a VLESS or Trojan master on TCP with TLS or REALITY. Point fallback children to loopback/private listeners and document match rules (
alpn,path,dest,xver). - IP limits: require access logs and Fail2ban enforcement. Warn that IP tunnel/proxy chains can make IP limits inaccurate.
- Client identity:
emailis the unique stable key.expiryTime=0means no expiry,totalGB=0means no quota, and API quota values are bytes despite the historicaltotalGBname.
Troubleshooting Workflow
- Classify the failure: panel unreachable, login/auth problem, Xray stopped, client cannot connect, traffic not counted, IP limit not enforced, subscription broken, high CPU/disk, or routing/site access issue.
- Use read-only checks first:
GET /panel/api/server/statusPOST /panel/api/server/logs/{count}POST /panel/api/server/xraylogs/{count}GET /panel/api/server/getConfigJsonGET /panel/api/inbounds/list/slimGET /panel/api/clients/traffic/{email}POST /panel/api/clients/onlines
- Compare intended config to runtime config. Watch for port conflicts, missing Docker port publishes, wrong base path, expired client, exhausted quota, disabled inbound/client, bad Reality SNI/public key/shortId, CDN in front of Reality, and missing access log for IP limits.
- Only after evidence, propose a minimal fix and name its side effects, especially Xray restart, traffic reset, DB restore, or client secret rotation.
API Use
Use environment variables in examples:
export XUI_BASE='https://example.com/access-path'
export XUI_API_TOKEN='...'
curl -fsS -H "Authorization: Bearer ${XUI_API_TOKEN}" \
"${XUI_BASE}/panel/api/inbounds/options"
For writes:
- Fetch the current object first.
- Preserve fields the user did not ask to change.
- Use the most specific endpoint (
setEnablefor enable flips, client endpoints for client changes). - Verify with a read-only endpoint and, if needed, generated links (
/panel/api/clients/links/:email) without exposing secrets in the final answer.
Scripts
Offline helpers in scripts/ run on any surface (no network, no panel access). They complement — but never replace — showing the user each payload and command:
- Execute
scripts/validate_config.pyto validate an inbound or client-add payload before POSTing it: flow placement, VLESSdecryption/encryption, XTLS-Vision gating, REALITY-behind-CDN, and byte-vs-GiB / ms-vs-seconds mistakes. The exit code is the error count; use it as the validate step before any write. - Execute
scripts/parse_share_link.py ''to decode a VLESS/VMess/Trojan link into normalized fields to compare against an inbound; the credential is masked by default.
Run a script's --self-test to confirm it works. Do not add network-calling scripts: some surfaces have no network, and hiding live calls would undercut the show-then-confirm workflow.
References
Read [references/api-and-config-reference.md](references/api-and-config-reference.md) when you need endpoint groups, field tables, protocol-specific settings, streamSettings, or example payloads.
Read [README.md](README.md) when the user wants English human-facing documentation, diagrams, or copy-pasteable configuration examples.
Read [README.zhCN.md](README.zhCN.md) when the user wants the same documentation in Simplified Chinese.
Use the offline helpers in [scripts/](scripts/): validate_config.py (validate a payload before writing) and parse_share_link.py (decode a share link, secrets masked).
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: XKHoshizora
- Source: XKHoshizora/cross-border-network-best-practices
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.