Trojan: the config (and why it's going obsolete)
I keep Trojan as a backup of a different "kind" — in case someone starts fingerprinting the VLESS pattern. It disguises itself as an ordinary HTTPS site and, when poked, serves a real page. Below are two working configs and an honest take on why I don't make it my primary channel. Fill in your data in the constructor above.
Where Trojan belongs
Let me set expectations right away so they don't run too high. Trojan is a backup, not the primary channel under Russian DPI. Its point is that it's of a different protocol "kind": if a client's specific VLESS pattern starts getting fingerprinted, Trojan may not fall under the same wave — from the outside it looks like an ordinary HTTPS site. When poked with a browser, it serves a real page via fallback, and only proxies clients with the correct password.
But bare Trojan+TLS exposes your domain's SNI exactly the same way honest VLESS+TLS does — and gets cut off by domain lists. So if you're going to use Trojan under DPI, do it paired with Reality. Both variants are below.
Variant A — Trojan + TLS (your own domain, with fallback to a site)
Honest TLS on your own certificate, with a fallback to a real page. First, the cert:
apt -y install certbot
certbot certonly --standalone -d your-domain.com -m admin@your-domain.com --agree-tos --non-interactiveThe full config profile:
{
"log": { "loglevel": "none" },
"inbounds": [
{
"tag": "trojan-tls",
"listen": "0.0.0.0",
"port": 443,
"protocol": "trojan",
"settings": {
"clients": [{ "password": "STRONG_PASSWORD" }],
"fallbacks": [{ "dest": "8080" }]
},
"sniffing": { "enabled": true, "destOverride": ["http", "tls", "quic"] },
"streamSettings": {
"network": "raw",
"security": "tls",
"tlsSettings": {
"serverName": "your-domain.com",
"alpn": ["h2", "http/1.1"],
"certificates": [
{
"certificateFile": "/etc/letsencrypt/live/your-domain.com/fullchain.pem",
"keyFile": "/etc/letsencrypt/live/your-domain.com/privkey.pem"
}
]
}
}
}
],
"outbounds": [
{ "tag": "DIRECT", "protocol": "freedom" },
{ "tag": "BLOCK", "protocol": "blackhole" }
],
"routing": { "rules": [
{ "ip": ["geoip:private"], "outboundTag": "BLOCK" },
{ "domain": ["geosite:category-ads-all"], "outboundTag": "BLOCK" },
{ "protocol": ["bittorrent"], "outboundTag": "BLOCK" }
]}
}fallbacks → dest 8080 — "stray" traffic without the correct password goes to a real site/nginx on :8080; poke it with a browser and you'll see a normal page. In the panel you can leave clients empty (the panel will populate it); the password is shown here for clarity.
Variant B — Trojan + Reality (no domain/cert of your own)
The stealth is more robust here — Reality masquerades as someone else's donor, and no cert of your own is needed. Keys:
xray x25519 # privateKey → into the config
openssl rand -hex 8 # shortId{
"log": { "loglevel": "none" },
"inbounds": [
{
"tag": "trojan-reality",
"listen": "0.0.0.0",
"port": 443,
"protocol": "trojan",
"settings": { "clients": [{ "password": "STRONG_PASSWORD" }] },
"sniffing": { "enabled": true, "destOverride": ["http", "tls", "quic"] },
"streamSettings": {
"network": "raw",
"security": "reality",
"realitySettings": {
"show": false,
"target": "your-donor.de:443",
"serverNames": ["your-donor.de"],
"privateKey": "PRIVATE_KEY_X25519",
"shortIds": ["REALITY_SHORT_ID"]
}
}
}
],
"outbounds": [
{ "tag": "DIRECT", "protocol": "freedom" },
{ "tag": "BLOCK", "protocol": "blackhole" }
],
"routing": { "rules": [
{ "ip": ["geoip:private"], "outboundTag": "BLOCK" },
{ "domain": ["geosite:category-ads-all"], "outboundTag": "BLOCK" },
{ "protocol": ["bittorrent"], "outboundTag": "BLOCK" }
]}
}Host settings in the panel
Password : STRONG_PASSWORD
Address : your-domain.com (or node IP/domain)
Port : 443
SNI / Host : your-domain.com (Variant B — your-donor.de)
publicKey : REALITY_PUBLIC_KEY (Variant B only)
shortId : REALITY_SHORT_ID (Variant B only)
fingerprint : firefoxWhy it's going obsolete
The honest part. Trojan is a fading breed, and here's why I don't build a service on it:
- Bare Trojan+TLS exposes SNI — the same weakness as honest VLESS+TLS, cut off by domain lists. Without Reality, under harsh Russian DPI it stands out.
- The Reality wrapping saves it, but then it's simpler to just take VLESS+Reality — the same stealth, a more developed ecosystem, active support. Trojan is only justified as a "different kind" to diversify protocols on a node.
- The password should be long, with no spaces (
openssl rand -hex 16), identical on the server and the host. It's Trojan's only secret — a weak password kills the whole scheme.
Bottom line: keep Trojan as a backup protocol of a different "kind" in case of targeted VLESS fingerprinting, but build your primary channel on VLESS+Reality. The Reality mechanics, which do the heavy lifting here too, I covered in the Reality theory piece.
Next guide Shadowsocks: why it's no longer an option → ↗ Article unclear or something off? Message me and I will help or fix it. @notrealvpn →