Files
op-packages/vless-core-cli
..
2026-11-02 01:02:56 +08:00
2026-11-01 12:58:10 +08:00

vless-core-cli

OpenWrt package for notfence/vless-core-cli — a standalone C client that connects to a VLESS, Trojan, VMess, Shadowsocks or SOCKS5 server and exposes a local SOCKS5 proxy.

Compared to Go-based cores it is very small and depends only on libopenssl, which makes it suitable for devices with small flash and RAM.

Supported upstreams:

  • VLESS (with xtls-rprx-vision and VLESS Encryption), Trojan, VMess AEAD (alterId=0), Shadowsocks (AEAD and 2022) over TCP / WebSocket / gRPC / XHTTP / HTTPUpgrade with no security, TLS or Reality (Reality is not available for WebSocket and HTTPUpgrade).
  • Plain SOCKS5, optionally with username/password.

Files

Path Purpose
/usr/bin/vless-core client binary
/etc/init.d/vless-core procd init script
/etc/config/vless-core UCI config

Quick start

uci set vless-core.main.uri='vless://UUID@example.com:443?type=tcp&security=reality&sni=www.example.org&fp=chrome&pbk=PUBLIC_KEY&sid=SHORT_ID&flow=xtls-rprx-vision#server'
uci set vless-core.main.listen_port='1080'
uci set vless-core.main.enabled='1'
uci commit vless-core
/etc/init.d/vless-core enable
/etc/init.d/vless-core start

Check:

curl -x socks5h://127.0.0.1:1080 https://2ip.io

The SOCKS5 listener binds to 127.0.0.1 only. Use it with tun2socks, redsocks or anything else that can talk to a SOCKS5 proxy. Logs go to logread.

UCI options

Section config vless-core 'main':

Option Default Description
enabled 0 Start the service (1/0)
uri – vless://, vmess://, trojan://, ss:// or socks5:// upstream URI (required)
listen_port 1080 Local SOCKS5 port on 127.0.0.1
routing – Optional routing rules, see below
tls_mode strict Certificate verification: strict, insecure or tofu

Always quote the URI in uci set: it contains &, # and ?.

The client serves exactly one upstream URI, so the init script runs a single instance.

URI examples

Reality + Vision:

vless://UUID@example.com:443?type=tcp&security=reality&sni=www.example.org&fp=chrome&pbk=PUBLIC_KEY&sid=SHORT_ID&flow=xtls-rprx-vision#reality

XHTTP + TLS:

vless://UUID@example.com:443?type=xhttp&security=tls&sni=example.com&path=%2Fxh&mode=auto#xhttp

WebSocket + TLS:

vless://UUID@example.com:443?type=ws&security=tls&sni=example.com&host=example.com&path=%2Fws#ws

gRPC + Reality:

vless://UUID@example.com:443?type=grpc&security=reality&serviceName=svc&sni=www.example.org&fp=chrome&pbk=PUBLIC_KEY&sid=SHORT_ID#grpc

HTTPUpgrade + TLS:

vless://UUID@example.com:443?type=httpupgrade&security=tls&sni=example.com&host=example.com&path=%2Fup#httpupgrade

Trojan (TLS by default, the whole userinfo is the password):

trojan://PASSWORD@example.com:443?sni=example.com#trojan

VMess (encryption is the body mode, scy is an alias; the base64 JSON form is accepted too):

vmess://UUID@example.com:443?type=ws&security=tls&sni=example.com&host=example.com&path=%2Fws&encryption=auto#vmess

Shadowsocks (SIP002, userinfo is base64url of method:password):

ss://BASE64URL_METHOD_PASSWORD@example.com:8388#ss

Upstream SOCKS5:

socks5://192.0.2.1:1080

Supported fp values: chrome, firefox, edge, random, randomized, qq (there are no safari or ios fingerprints).

Routing

routing is a single string, fields separated by ;:

ENABLED;DEFAULT;LAN;action,type,value;action,type,value;...
Field Values
ENABLED 1 / 0
DEFAULT proxy / direct / block — used when no rule matches
LAN 1 / 0 — private IP ranges always go direct (checked before the rules)
action proxy / direct / block
type domain (exact), suffix (domain and subdomains), cidr, port (single or a-b)

Rules are checked in order, first match wins. Up to 48 rules, 8191 characters total. Domains are lowercase a-z0-9-_. without leading or trailing dot (ru, not .ru).

Example: everything through the proxy, .ru and .lan direct, SMTP and one subnet blocked:

uci set vless-core.main.routing='1;proxy;1;direct,suffix,ru;direct,suffix,lan;block,port,25;block,cidr,203.0.113.0/24'
uci commit vless-core
/etc/init.d/vless-core restart

Notes:

  • Domain rules match when the client sends a hostname (socks5h). For a bare IP the client tries to sniff the domain from the first packet, but only if domain/suffix rules exist.
  • 8.8.8.8:53 always goes through the proxy if no rule matched earlier, even with DEFAULT=direct.
  • A direct connection is opened by vless-core itself via the normal routing table. If your default route points into a tun device (tun2socks), direct traffic will loop back into it. The client has --route-control-port / --route-control-socket for an external controller, they are not exposed in UCI.

TLS verification

tls_mode is passed to the client as VLESS_TLS_MODE:

  • strict — only verified TLS, no fallback (default). For security=tls install ca-bundle.
  • insecure — never verify certificates.
  • tofu — pin the certificate on first connection, later connections must match.

Reality client version

For Reality the client writes an Xray version (x.y.z, default 26.3.27) into the ClientHello session ID. Override it with the XRAY_VER environment variable or --xray-version x.y.z, for example if the server limits client versions with minClientVer / maxClientVer. This is not exposed in UCI.

Build notes

Upstream's Makefile runs its test suite (clang sanitizers, a separate OpenSSL 3.5, Xray) and an x86-64-only binary check, and hardcodes the output name vless-core-linux-amd64. The package therefore does not use it: it compiles src/*.c directly with the SDK toolchain and installs the result as /usr/bin/vless-core.

ML-KEM based features (VLESS Encryption, the X25519MLKEM768 key share) need OpenSSL 3.5 or newer.

Tested: OpenWrt SDK, musl x86-64, OpenSSL 3.5.9.

ToDo

  • luci-app-vless-core — LuCI web interface (someday).