Try Live
Add Docs
Rankings
Pricing
Enterprise
Docs
Install
Install
Docs
Pricing
Enterprise
More...
More...
Try Live
Rankings
Add Docs
Xray
https://github.com/xtls/xray-core
Admin
Project X, originating from the XTLS protocol, offers a suite of network tools including Xray-core
...
Tokens:
16,762
Snippets:
135
Trust Score:
8.8
Update:
1 week ago
Context
Skills
Chat
Benchmark
78.7
Suggestions
Latest
Show doc for...
Code
Info
Show Results
Context Summary (auto-generated)
Raw
Copy
Link
# Xray-core Xray-core is a high-performance, modular network proxy framework written in Go (module `github.com/xtls/xray-core`). It originates from the XTLS protocol and provides a unified platform for building censorship-resistant network tools. The project supports a wide range of inbound and outbound proxy protocols — VLESS, VMess, Shadowsocks, Trojan, Hysteria, WireGuard, SOCKS, HTTP, Dokodemo-door — multiplexed over multiple transport layers including TCP, WebSocket, gRPC, QUIC, KCP, SplitHTTP, and HTTPUpgrade. Security is enforced via TLS, REALITY (a novel TLS camouflage mechanism), and post-quantum key exchange schemes (X25519, ML-KEM768, ML-DSA65). The architecture is built around an `Instance` object that wires together `Feature` modules — a `Dispatcher`, an `InboundHandlerManager`, an `OutboundHandlerManager`, a DNS client, a router, a stats manager, and optional features such as an API server, observatory, and metrics. Configuration is expressed in JSON (or YAML/TOML), parsed into typed protobuf structures, and built into running components at startup. A live gRPC management API allows adding/removing inbounds, outbounds, users, and routing rules at runtime without restarting the server. --- ## APIs and Key Functions ### `core.StartInstance` — Start an Xray instance from raw config bytes Loads a config in the specified format (e.g. `"json"`, `"protobuf"`), creates and starts an `Instance`. This is the primary embedding API for embedding Xray in another Go program. ```go import ( "os" "github.com/xtls/xray-core/core" _ "github.com/xtls/xray-core/main/distro/all" // register all protocols/transports ) func main() { configBytes, err := os.ReadFile("config.json") if err != nil { panic(err) } // Start an Xray instance — loads config, initialises all features, starts listeners instance, err := core.StartInstance("json", configBytes) if err != nil { panic("failed to start xray: " + err.Error()) } defer instance.Close() // instance is now running; block until shutdown signal select {} } // Output: Xray 26.5.3 (Xray, Penetrates Everything.) <commit> started ``` --- ### `core.New` / `instance.Start` / `instance.Close` — Lifecycle management `New` creates an uninitialised `Instance` from a `*core.Config` protobuf. `Start` starts all registered features. `Close` shuts everything down gracefully. ```go import ( "github.com/xtls/xray-core/core" "github.com/xtls/xray-core/infra/conf/serial" "strings" ) func startXray(jsonConfig string) (*core.Instance, error) { // Parse JSON → *core.Config pbConfig, err := serial.LoadJSONConfig(strings.NewReader(jsonConfig)) if err != nil { return nil, err } // Create instance (not yet running) server, err := core.New(pbConfig) if err != nil { return nil, err } // Start all features (DNS, router, inbounds, outbounds, etc.) if err := server.Start(); err != nil { return nil, err } return server, nil } // Shutdown func stopXray(server *core.Instance) { if err := server.Close(); err != nil { // handle partial shutdown error } } ``` --- ### `core.LoadConfig` — Load config from file(s) or reader Accepts a format name (`"auto"`, `"json"`, `"yaml"`, `"toml"`, `"protobuf"`) and either an `io.Reader` or a `cmdarg.Arg` slice of file paths. Returns a `*core.Config` ready for `core.New`. ```go import ( "bytes" "github.com/xtls/xray-core/core" "github.com/xtls/xray-core/common/cmdarg" ) // From io.Reader func loadFromReader(jsonBytes []byte) (*core.Config, error) { return core.LoadConfig("json", bytes.NewReader(jsonBytes)) } // From multiple files (auto-detects format by extension) func loadFromFiles(paths []string) (*core.Config, error) { files := make(cmdarg.Arg, len(paths)) copy(files, paths) return core.LoadConfig("auto", files) } // Load and merge multiple JSON configs from a directory func loadFromDir() (*core.Config, error) { files := cmdarg.Arg{"/etc/xray/base.json", "/etc/xray/routing.json"} return core.LoadConfig("auto", files) } ``` --- ### `core.Dial` — Create a `net.Conn` routed through Xray Dispatches a TCP connection to a destination through the running Xray instance, applying all routing rules and outbound proxies. ```go import ( "context" "fmt" "io" "github.com/xtls/xray-core/core" "github.com/xtls/xray-core/common/net" ) func fetchViaXray(instance *core.Instance, host string, port uint32) error { dest := net.Destination{ Network: net.Network_TCP, Address: net.ParseAddress(host), Port: net.Port(port), } conn, err := core.Dial(context.Background(), instance, dest) if err != nil { return fmt.Errorf("dial failed: %w", err) } defer conn.Close() // Write an HTTP request fmt.Fprintf(conn, "GET / HTTP/1.0\r\nHost: %s\r\n\r\n", host) // Read response data, err := io.ReadAll(conn) if err != nil { return err } fmt.Println(string(data[:200])) return nil } ``` --- ### `core.DialUDP` — Create a UDP `net.PacketConn` through Xray Opens a UDP packet connection dispatched through the Xray routing pipeline. ```go import ( "context" "net" "github.com/xtls/xray-core/core" corenet "github.com/xtls/xray-core/common/net" ) func udpViaXray(instance *core.Instance) error { // xray:api:beta pc, err := core.DialUDP(context.Background(), instance) if err != nil { return err } defer pc.Close() addr := &net.UDPAddr{IP: net.ParseIP("8.8.8.8"), Port: 53} // Send a DNS query payload _, err = pc.WriteTo([]byte{0x00, 0x01, 0x01, 0x00 /* ... */}, addr) return err } ``` --- ### `instance.GetFeature` / `instance.AddFeature` — Feature registry The `Instance` acts as a service locator. Features (DNS client, router, inbound/outbound managers, stats) are registered and retrieved by interface type. ```go import ( "github.com/xtls/xray-core/core" "github.com/xtls/xray-core/features/routing" "github.com/xtls/xray-core/features/dns" "github.com/xtls/xray-core/features/stats" ) func inspectFeatures(instance *core.Instance) { // Retrieve the dispatcher (required feature) dispatcher := instance.GetFeature(routing.DispatcherType()) if dispatcher == nil { panic("dispatcher not registered") } // Retrieve the DNS client dnsClient := instance.GetFeature(dns.ClientType()) if dnsClient != nil { client := dnsClient.(dns.Client) ips, ttl, err := client.LookupIP("example.com", dns.IPOption{IPv4Enable: true}) if err == nil { fmt.Printf("example.com -> %v (TTL %ds)\n", ips, ttl) } } // Retrieve stats manager statsManager := instance.GetFeature(stats.ManagerType()) _ = statsManager } ``` --- ### `instance.RequireFeatures` — Deferred feature dependency injection Registers a callback that fires automatically when all its parameter types are available in the instance. Used inside `init()` functions of app packages. ```go import ( "github.com/xtls/xray-core/core" "github.com/xtls/xray-core/features/dns" "github.com/xtls/xray-core/features/routing" ) func wireComponents(instance *core.Instance) error { // Callback fires immediately if both features are already registered, // or deferred until they are. return instance.RequireFeatures(func(d routing.Dispatcher, c dns.Client) { // Both features are now available fmt.Printf("Dispatcher type: %T\n", d) fmt.Printf("DNS client type: %T\n", c) }, false /* not optional */) } ``` --- ### `core.AddInboundHandler` / `core.AddOutboundHandler` — Dynamic handler registration Add inbound or outbound handlers to a running instance programmatically at startup or after configuration has been loaded. ```go import ( "github.com/xtls/xray-core/core" coreproto "github.com/xtls/xray-core/core" "github.com/xtls/xray-core/common/serial" "github.com/xtls/xray-core/app/proxyman" "github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/proxy/socks" ) func addSocksInbound(instance *core.Instance) error { socksConfig := &socks.ServerConfig{ AuthType: socks.AuthType_NO_AUTH, UdpEnabled: true, } inboundConfig := &coreproto.InboundHandlerConfig{ Tag: "socks-dynamic", ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ PortList: &net.PortList{Range: []*net.PortRange{{From: 1080, To: 1080}}}, }), ProxySettings: serial.ToTypedMessage(socksConfig), } return core.AddInboundHandler(instance, inboundConfig) } ``` --- ### CLI: `xray run` — Start Xray server The primary command to run an Xray server process from the terminal. Reads one or more config files (JSON, YAML, TOML, or Protobuf). ```bash # Single config file (auto-detected as JSON) xray run -c /etc/xray/config.json # Multiple config files merged together xray run -c base.json -c routing.json -c outbounds.json # Directory of config files xray run -confdir /etc/xray/conf.d/ # Test config validity without starting xray run -c config.json -test # Dump merged config to stdout xray run -c config.json -dump # Read from stdin echo '{"inbounds":[...],"outbounds":[...]}' | xray run # Expected output when starting: # Xray 26.5.3 (Xray, Penetrates Everything.) <git-hash> (go1.26 linux/amd64) # A unified platform for anti-censorship. ``` --- ### CLI: `xray api adi` — Add inbound handler at runtime Dynamically adds inbound handlers to a running Xray instance via its gRPC API. ```bash # Add inbound from JSON config file xray api adi --server=127.0.0.1:8080 new-inbound.json # new-inbound.json example: # { # "inbounds": [{ # "tag": "vless-new", # "port": 8443, # "protocol": "vless", # "settings": { # "clients": [{"id": "f96a5034-2f34-4e26-bc8d-43f8ebc54217", "flow": "xtls-rprx-vision"}], # "decryption": "none" # } # }] # } # Add from stdin echo '{"inbounds":[{"tag":"test","port":9090,"protocol":"socks","settings":{"auth":"noauth"}}]}' \ | xray api adi --server=127.0.0.1:8080 # Output: adding: vless-new # {} ``` --- ### CLI: `xray api ado` — Add outbound handler at runtime Dynamically adds outbound handlers to a running Xray instance. ```bash # Add a VLESS outbound via config file xray api ado --server=127.0.0.1:8080 new-outbound.json # new-outbound.json example: # { # "outbounds": [{ # "tag": "proxy-new", # "protocol": "vless", # "settings": { # "vnext": [{ # "address": "example.com", # "port": 443, # "users": [{"id": "f96a5034-2f34-4e26-bc8d-43f8ebc54217", "flow": "xtls-rprx-vision", "encryption": "none"}] # }] # }, # "streamSettings": {"network": "tcp", "security": "reality", "realitySettings": {...}} # }] # } # Output: adding: proxy-new # {} ``` --- ### CLI: `xray api adu` — Add users to inbound at runtime Adds users to a running VLESS, VMess, Trojan, or Shadowsocks inbound handler. ```bash # Add users from a config file to a running inbound xray api adu --server=127.0.0.1:8080 users.json # users.json (must contain an "inbounds" array with the target tag and new clients): # { # "inbounds": [{ # "tag": "vless-main", # "protocol": "vless", # "settings": { # "clients": [ # {"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "email": "alice@example.com", "flow": "xtls-rprx-vision"}, # {"id": "b2c3d4e5-f6a7-8901-bcde-f01234567891", "email": "bob@example.com"} # ], # "decryption": "none" # } # }] # } # Output: # processing inbound: vless-main # add user: alice@example.com # result: ok # add user: bob@example.com # result: ok # Added 2 user(s) in total. ``` --- ### CLI: `xray api stats` — Retrieve a single traffic counter Queries a named traffic counter from the running Xray stats service. ```bash # Get downlink bytes for a specific inbound xray api stats --server=127.0.0.1:8080 -name "inbound>>>main-in>>>traffic>>>downlink" # Output: # { # "stat": { # "name": "inbound>>>main-in>>>traffic>>>downlink", # "value": "1048576" # } # } # Get and reset (zero-out) a user's uplink counter xray api stats --server=127.0.0.1:8080 \ -name "user>>>alice@example.com>>>traffic>>>uplink" \ -reset # Get system stats (goroutines, memory, uptime) xray api sys --server=127.0.0.1:8080 # Output: {"numGoroutine":42,"numGC":10,"alloc":8388608,...} ``` --- ### CLI: `xray api statsquery` — Query multiple counters by pattern Fetches all stats counters whose names match a substring pattern. ```bash # Query all user traffic counters xray api statsquery --server=127.0.0.1:8080 -pattern "user>>>" # Query all traffic stats and reset them xray api statsquery --server=127.0.0.1:8080 -pattern "traffic" -reset # Output example: # { # "stat": [ # {"name": "user>>>alice@example.com>>>traffic>>>uplink", "value": "204800"}, # {"name": "user>>>alice@example.com>>>traffic>>>downlink", "value": "1048576"}, # {"name": "user>>>bob@example.com>>>traffic>>>uplink", "value": "51200"} # ] # } ``` --- ### CLI: `xray api adrules` — Add routing rules at runtime Adds routing rules to a running instance without restarting. ```bash # Add routing rules from a config snippet (must have a "routing" field) xray api adrules --server=127.0.0.1:8080 routing-patch.json # routing-patch.json: # { # "routing": { # "rules": [ # { # "type": "field", # "domain": ["geosite:cn"], # "outboundTag": "direct" # }, # { # "type": "field", # "ip": ["geoip:private"], # "outboundTag": "direct" # } # ] # } # } # Append to existing rules instead of replacing them xray api adrules --server=127.0.0.1:8080 -append extra-rules.json # Output: {} ``` --- ### CLI: `xray tls cert` — Generate TLS certificates Generates self-signed TLS certificates, optionally as a CA, for use in `streamSettings.tlsSettings`. ```bash # Generate a self-signed cert for a domain (JSON output) xray tls cert --domain=example.com --expire=8760h # Output (JSON with PEM-encoded cert and key lines): # { # "certificate": ["-----BEGIN CERTIFICATE-----", "...", "-----END CERTIFICATE-----"], # "key": ["-----BEGIN EC PRIVATE KEY-----", "...", "-----END EC PRIVATE KEY-----"] # } # Generate a CA certificate and save to files xray tls cert --ca --domain=myca.local --name="My CA" --org="My Org" \ --expire=87600h --json=false --file=/etc/xray/ca # Creates /etc/xray/ca.crt and /etc/xray/ca.key ``` --- ### CLI: `xray x25519` — Generate X25519 key pair (REALITY / VLESS Encryption) Generates a Curve25519 key pair for use in REALITY server configuration or VLESS post-quantum encryption. ```bash # Generate a random key pair xray x25519 # Output: # Private key: <base64url-encoded 32-byte private key> # Public key: <base64url-encoded 32-byte public key> # Derive public key from an existing private key xray x25519 -i "PrivateKeyBase64URLHere==" # Use standard base64 encoding (for WireGuard compatibility) xray x25519 --std-encoding ``` --- ### CLI: `xray wg` — Generate WireGuard key pair Generates an X25519 key pair using standard base64 encoding for WireGuard outbound configuration. ```bash # Random WireGuard key pair xray wg # Output: # Private key: <base64std-encoded 32-byte private key> # Public key: <base64std-encoded 32-byte public key> # From existing private key xray wg -i "WireGuardPrivateKeyBase64==" # Use in config: # "wireguard": { # "secretKey": "<private key>", # "peers": [{"publicKey": "<server public key>", "endpoint": "vpn.example.com:51820"}] # } ``` --- ### CLI: `xray uuid` — Generate UUID for VLESS/VMess Generates a UUIDv4 (random) or UUIDv5 (deterministic from a short input string) for use as a VLESS/VMess user ID. ```bash # Random UUIDv4 xray uuid # Output: f96a5034-2f34-4e26-bc8d-43f8ebc54217 # Deterministic UUIDv5 from a short string (≤30 bytes) xray uuid -i "mySecretPassword" # Output: <deterministic UUID derived from input> # Use in VLESS inbound config: # "clients": [{"id": "f96a5034-2f34-4e26-bc8d-43f8ebc54217", "flow": "xtls-rprx-vision"}] ``` --- ### JSON Configuration — Full server config structure The top-level JSON config that drives Xray. All sections are optional except at least one inbound and one outbound. ```json { "log": { "loglevel": "warning", "access": "/var/log/xray/access.log", "error": "/var/log/xray/error.log" }, "api": { "tag": "api", "services": ["HandlerService", "LoggerService", "StatsService", "RoutingService"] }, "stats": {}, "policy": { "levels": {"0": {"statsUserUplink": true, "statsUserDownlink": true}}, "system": {"statsInboundUplink": true, "statsInboundDownlink": true} }, "dns": { "servers": [ {"address": "https://1.1.1.1/dns-query", "domains": ["geosite:geolocation-!cn"]}, {"address": "114.114.114.114", "domains": ["geosite:cn"]}, "localhost" ] }, "routing": { "domainStrategy": "IPIfNonMatch", "rules": [ {"type": "field", "inboundTag": ["api"], "outboundTag": "api"}, {"type": "field", "ip": ["geoip:private"], "outboundTag": "direct"}, {"type": "field", "domain": ["geosite:cn"], "outboundTag": "direct"}, {"type": "field", "network": "tcp,udp", "outboundTag": "proxy"} ] }, "inbounds": [ { "tag": "vless-in", "port": 443, "protocol": "vless", "settings": { "clients": [ {"id": "f96a5034-2f34-4e26-bc8d-43f8ebc54217", "flow": "xtls-rprx-vision"} ], "decryption": "none" }, "streamSettings": { "network": "tcp", "security": "reality", "realitySettings": { "dest": "www.example.com:443", "serverNames": ["www.example.com"], "privateKey": "<x25519 private key>", "shortIds": ["abcdef1234567890"] } }, "sniffing": {"enabled": true, "destOverride": ["http", "tls"]} }, { "tag": "api", "listen": "127.0.0.1", "port": 8080, "protocol": "dokodemo-door", "settings": {"address": "127.0.0.1"} } ], "outbounds": [ { "tag": "proxy", "protocol": "vless", "settings": { "vnext": [{ "address": "remote.example.com", "port": 443, "users": [{"id": "f96a5034-2f34-4e26-bc8d-43f8ebc54217", "flow": "xtls-rprx-vision", "encryption": "none"}] }] }, "streamSettings": { "network": "tcp", "security": "reality", "realitySettings": { "serverName": "www.example.com", "publicKey": "<x25519 public key>", "shortId": "abcdef1234567890" } } }, {"tag": "direct", "protocol": "freedom"}, {"tag": "blackhole", "protocol": "blackhole"} ] } ``` --- ### JSON Configuration — VMess inbound/outbound VMess protocol with WebSocket transport and TLS, commonly used for CDN-based deployments. ```json { "inbounds": [{ "tag": "vmess-ws", "port": 10086, "protocol": "vmess", "settings": { "clients": [ {"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "alterId": 0, "email": "user@example.com"} ] }, "streamSettings": { "network": "ws", "security": "tls", "tlsSettings": { "certificates": [{"certificateFile": "/etc/ssl/cert.pem", "keyFile": "/etc/ssl/key.pem"}] }, "wsSettings": {"path": "/ray", "headers": {"Host": "cdn.example.com"}} } }], "outbounds": [{ "tag": "vmess-out", "protocol": "vmess", "settings": { "vnext": [{ "address": "cdn.example.com", "port": 443, "users": [{"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "alterId": 0, "security": "auto"}] }] }, "streamSettings": { "network": "ws", "security": "tls", "wsSettings": {"path": "/ray", "headers": {"Host": "cdn.example.com"}}, "tlsSettings": {"serverName": "cdn.example.com", "allowInsecure": false} }, "mux": {"enabled": true, "concurrency": 8} }] } ``` --- ### JSON Configuration — Routing rules and balancer Advanced routing with geographic data, balancing strategy, and process-based rules. ```json { "routing": { "domainStrategy": "IPIfNonMatch", "balancers": [ { "tag": "balancer", "selector": ["proxy-us", "proxy-jp", "proxy-sg"], "strategy": {"type": "leastPing"}, "fallbackTag": "proxy-us" } ], "rules": [ {"type": "field", "domain": ["geosite:category-ads-all"], "outboundTag": "blackhole"}, {"type": "field", "ip": ["geoip:cn", "geoip:private"], "outboundTag": "direct"}, {"type": "field", "domain": ["geosite:cn"], "outboundTag": "direct"}, {"type": "field", "network": "tcp,udp", "balancerTag": "balancer"} ] } } ``` --- ### JSON Configuration — DNS with FakeDNS FakeDNS enables transparent proxy by assigning fake IPs to domain lookups, then recovering the domain during routing. ```json { "fakeDns": { "ipPool": "198.18.0.0/15", "poolSize": 65535 }, "dns": { "servers": [ {"address": "fakedns", "domains": ["geosite:geolocation-!cn"]}, {"address": "https://8.8.8.8/dns-query"} ] }, "inbounds": [{ "tag": "tproxy-in", "port": 12345, "protocol": "dokodemo-door", "settings": {"network": "tcp,udp", "followRedirect": true}, "streamSettings": {"sockopt": {"tproxy": "tproxy"}}, "sniffing": { "enabled": true, "destOverride": ["fakedns"], "metadataOnly": false } }] } ``` --- ### `dns.Client.LookupIP` — Programmatic DNS resolution The `dns.Client` feature exposes DNS lookup for use inside Xray components and external embedders. ```go import ( "fmt" "github.com/xtls/xray-core/core" "github.com/xtls/xray-core/features/dns" ) func resolveDomain(instance *core.Instance, domain string) { rawClient := instance.GetFeature(dns.ClientType()) if rawClient == nil { fmt.Println("DNS client not available") return } client := rawClient.(dns.Client) // Resolve both IPv4 and IPv6 ips, ttl, err := client.LookupIP(domain, dns.IPOption{ IPv4Enable: true, IPv6Enable: true, FakeEnable: false, }) if err != nil { fmt.Printf("lookup error: %v (rcode=%d)\n", err, dns.RCodeFromError(err)) return } fmt.Printf("%s -> %v (TTL: %ds)\n", domain, ips, ttl) // example.com -> [93.184.216.34 2606:2800:220:1:248:1893:25c8:1946] (TTL: 3600s) } ``` --- ## Summary Xray-core's primary use cases are privacy-preserving network access and censorship circumvention. Typical deployments involve a server node running a VLESS+XTLS-Vision or VMess+WebSocket inbound behind a CDN or with REALITY camouflage, paired with client-side instances that route domestic traffic direct and foreign traffic through the encrypted tunnel. The modular proxy chain supports multi-hop setups where one outbound's `proxySettings.tag` chains through another, and the Mux/XUDP features collapse many streams into a single connection to minimize fingerprinting. Integration patterns range from simple CLI operation (`xray run -c config.json`) to embedded Go library use via `core.StartInstance` or `core.New` + `instance.Start`. Panels and management tools interact through the live gRPC API (`xray api adi/ado/adu/adrules`) to add users, update routing, and read per-user traffic statistics without restarting the proxy. Observability is handled by the stats service (per-user/inbound/outbound byte counters via `xray api stats/statsquery`), the observatory module for automatic latency-based outbound health checks, and optional Prometheus metrics (`metricsSettings`). Post-quantum security extensions (ML-KEM768 key encapsulation in `decryption`/`encryption` fields) and the REALITY TLS fingerprint camouflage make Xray-core suitable for high-threat network environments.