Run Trojan over WebSocket behind a CDN
A server behind a CDN that relays WebSocket, and a client that reaches it. The censor sees only a CDN address and TLS to a name on it. Before you start, read what these guides assume.
json
{
"version": 1,
"log": {
"level": "info",
"outputs": [{ "type": "stderr" }]
},
"inbounds": [
{
"tag": "trojan-ws-in",
"listen": "0.0.0.0",
"port": 8080,
"network": "tcp",
"transport": [
{ "type": "tcp" },
{
"type": "ws",
"settings": { "path": "/chat", "host": "proxy.example.com" }
}
],
"protocol": {
"type": "trojan",
"settings": {
"users": [{ "name": "alice", "password": "change me" }]
}
}
}
],
"outbounds": [
{
"tag": "direct",
"protocol": { "type": "freedom" }
}
]
}- The CDN ends TLS and reaches the server over plain HTTP on port 8080, so the server has no
tls. If the CDN reaches it over TLS, addtlsbetweentcpandws. - The client's
"alpn": ["http/1.1"]is required: otherwise the CDN may choose HTTP/2, whichwscannot speak. early_datasaves a round trip; the server accepts it without configuration.- The server reads each client's address from
X-Forwarded-For; see Client address behind a proxy.
WARNING
The CDN ends the outer TLS, so it can read the Trojan request, password hash included. Use only a CDN you trust with that.
Trojan over HTTPUpgrade
The same as WebSocket, without framing after the handshake. Swap the ws layer on both sides for:
json
{
"type": "httpupgrade",
"settings": { "path": "/up", "host": "proxy.example.com" }
}Leave pipeline off unless both ends are Apranik: Xray's and sing-box's servers may drop bytes sent before their 101 answer.