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.
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.
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.
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).
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.