github lilendian0x00/xray-knife v9.11.0

latest releases: v9.12.1, v9.12.0
3 hours ago

What's New

🚀 Bind-Interface Support

  • New --bind <iface> flag on http, cfscanner, and proxy commands
  • Pins outbound dials to a specific OS interface (e.g. eth0) — useful when the host has multiple paths and you want to bypass a VPN tunnel for the proxy itself
  • Implemented at every layer: raw scanner dials, xray-core (via internet.RegisterDialerController), sing-box (via RouteOptions.DefaultInterface)
  • Cross-platform: SO_BINDTOIFINDEXSO_BINDTODEVICE on Linux, IP_BOUND_IF on Darwin, IP_UNICAST_IF on Windows
  • Interface existence is validated up front — a typo fails fast instead of silently doing nothing

🌐 Configurable Tunnel DNS (App Mode)

  • --dns <server> lets you pick the resolver used inside the app-mode tunnel (default 1.1.1.1)
  • --dns-type {udp,tcp,tls,https} picks the transport (default udp — changed from the previous TCP default since TCP/53 is often blocked at exit proxies)
  • HTTPS form supports full URL: --dns-type https --dns https://1.1.1.1/dns-query
  • Bad values rejected at tunnel start with a clear error

🔌 cfscanner Custom Ports

  • New --port flag (default 443) for scanning Cloudflare's alternate TLS ports — 2053, 2083, 2087, 2096, 8443
  • Useful when 443 is filtered by the local network

🛡️ Proxy App-Mode Hardening

  • Concurrent proxy --mode app invocations no longer clobber each other — veth names are now PID-suffixed and the on-disk state file stamps PID + boot_id
  • RecoverFromCrash checks the owning PID is actually dead before reclaiming resources
  • State file writes are atomic (tmp + rename)
  • TUN device teardown is now awaited before the namespace is deleted (no more "device busy" warnings)

🔗 Proxy Chaining (Multi-Hop)

  • New --chain flag chains multiple outbound configs into a single circuit
  • --chain-links / --chain-file for fixed chains, --chain-hops for random selection from pool
  • --chain-rotation {none,exit,full} controls how rotation interacts with chains

🔄 Upstream Updates

  • xray-core: v1.260123.0v1.260327.0 (latest)
  • Minimum Go 1.26 (auto-toolchain bump driven by xray-core)
  • Migrated TLSConfig.InsecureAllowInsecure (xray-core rename; old field becomes a hard error after 2026-06-01 upstream)
  • sing-box InboundOptions.Sniff* migrated to a sniff route rule action (deprecated fields are removed in sing-box 1.13 final)

🐛 Bug Fixes

  • App-mode routing loop: AutoDetectInterface=true inside the namespace was resolving the "default interface" to the TUN itself, causing the SOCKS dialer to loop back into gvisor. SOCKS dialer is now pinned to the veth, and the upstream proxy IP is added to RouteExcludeAddress
  • OS-thread leak: StartTunnel no longer hands a thread that briefly entered the target netns back to the Go scheduler — the tunnel goroutine now owns its OS thread for life
  • Trojan parser: removed bogus "method": "chacha20" and "ota": false fields that were copy-paste leftovers from shadowsocks; these aren't part of xray-core's TrojanServerTarget schema
  • VLESS parser: removed dead "alterId": 0 field (VLESS has no alterId)
  • JSON-injection hardening: replaced fmt.Sprintf JSON templates with json.Marshal over typed maps for vless / vmess / trojan, so passwords or UUIDs containing quotes can no longer corrupt the emitted config
  • WireGuard test: bracketed bare IPv6 host that Go 1.26's stricter url.Parse was rejecting
  • Cleanup order: tunnel Close errors are now captured and logged; cleanup waits for the TUN device to disappear before deleting the namespace
  • Privilege check in proxy.New() was running after sysproxy.LoadState and RecoverFromCrash — hoisted to the top so non-root invocations fail fast without side effects

⚡ Improvements

  • Single OS-thread guard around RegisterDialerController so repeated core construction in the same process doesn't stack bind hooks
  • core.FactoryOptions struct gives callers a backward-compatible way to pass new core options without breaking CoreFactory(coreType, insecure, verbose) callers
  • DNS transport registration is now lazy — only the configured --dns-type transport is registered at tunnel start

Note for app-mode users: the upstream config link's hostname (the proxy server itself) is still resolved by the host's stdlib resolver. The new --dns flags only affect DNS for apps running inside the namespace.

Don't miss a new xray-knife release

NewReleases is sending notifications on new releases.