Contents

Self-steal: be your own decoy

Point REALITY at a real website you run on the same box, so the cover site and the proxy share one host — no foreign dependency, a decoy you control.

REALITY works by borrowing a real site’s TLS handshake, but the default advice — point dest at www.microsoft.com:443 — makes you a tenant on someone else’s property. Self-steal points dest at a real website you run on the same box, so the SNI you present is a domain you actually control and serve. The cover site and the proxy become one host: no foreign dependency, no third-party latency, and a decoy you can log into and inspect.

Assumes you’ve read REALITY, Choosing an SNI, and Surviving active probes — this page is the deployment shape, not the protocol.

Own the domain in serverNames, own the site in dest

A borrowed decoy means a censor decides what your cover looks like; a self-hosted decoy means you do. REALITY only cares about two things — the SNI the client claims must be in serverNames, and unauthenticated handshakes get mirrored to dest — and both keys accept a host you operate.

{
	"listen": "0.0.0.0",
	"port": 443,
	"protocol": "vless",
	"settings": {
		"clients": [{ "id": "UUID-HERE", "flow": "xtls-rprx-vision" }],
		"decryption": "none"
	},
	"streamSettings": {
		"network": "tcp",
		"security": "reality",
		"realitySettings": {
			"show": false,
			"dest": "127.0.0.1:8443",
			"xver": 0,
			"serverNames": ["cover.example.com"],
			"privateKey": "SERVER_PRIVATE_KEY",
			"shortIds": ["", "0123abcd"]
		}
	}
}

Every key here exists in the config loader: dest, serverNames, privateKey, shortIds, xver, and show are all fields of REALITYConfig. dest is parsed leniently — a bare "127.0.0.1:8443" is classified as type: "tcp", and a value starting with / or @ becomes a type: "unix" socket, so you can even point at a local UNIX socket your web server listens on.

infra/conf/transport_internet.go transport/internet/reality/config.go

One host: the prober is mirrored to your own site

Because dest is your own HTTPS site, an active prober that fails REALITY auth is transparently relayed to it and shown its genuine certificate — the cover story is a site you actually serve.

One host: authenticated clients tunnel; probers are mirrored to your own web server and shown its genuine cert.

The unauthenticated path is Xray’s own fallback triage — it lowercases the real ServerName from the connection, longest-substring-matches it against your fallbacks, then narrows by alpn and request path before dialing the dest. So the same box answers real browsers, probers, and your authenticated clients consistently.

proxy/vless/inbound/inbound.go
Don't

Borrow a stranger's domain you can't control

dest: www.microsoft.com:443 works, but the cover is someone else’s — its latency, its cipher choices, and its availability are outside your control, and its geography may not match your server’s IP (see Choosing an SNI).

Do

Serve the decoy yourself on the same box

Run a real HTTPS site for cover.example.com on 127.0.0.1:8443 and point dest at it. The SNI is a domain you own, the cert is yours, and the handshake latency is local and consistent.

Whether that local decoy should be a bare Xray fallback or a full web server — and whether an NGINX belongs in front at all — is the fronting question, covered in NGINX in front of Xray. Self-steal is just the choice to make the borrowed site your own.