Stealth Trojan VPN Behind Cloudflare Guide

Introduction So you want a VPN that doesn’t scream “I am a VPN” to every censor and firewall out there? Welcome to the world of Trojan over WebSocket + TLS behind Cloudflare. This guide not only shows you how to set it up but also sprinkles in some debugging magic so you can figure out why things break (and they will break, trust me). We’ll anonymise domains and secrets, so substitute with your own: ...

September 9, 2025 · 4 min · Iman Alipour
Matrix, Signal but distributed

Self-hosting Matrix + Element Call with LiveKit: from zero to working (and the [not so!!] fun debugging along the way)

TL;DR: The call kept saying “waiting for media” because the browser never opened a WebSocket to LiveKit. The root cause was duplicate Access-Control-Allow-Origin headers on /sfu/get (CORS), which stopped the JWT response. Fixing CORS and ensuring the WS proxy worked (HTTP 101 in logs) solved it. What I’m building A Matrix homeserver (Synapse) at matrix.example.com (replace with your domain). TURN/STUN (coTURN) for NAT traversal. Element Call backed by LiveKit, fronted by rtc.example.com. Nginx (host) as the single reverse proxy for everything. Cloudflare DNS (with rtc.* set to DNS-only, no orange cloud). UFW firewall opened for Matrix federation, TURN, and LiveKit media ports. I used Docker for Synapse, PostgreSQL, LiveKit and the JWT helper. I used host Nginx (not Nginx in Docker) to avoid port binding conflicts on 80/443/8448. ...

August 26, 2025 · 9 min · Iman Alipour
RSS