Initial import of Hugo site to Forgejo
This commit is contained in:
commit
cb1ba0317f
1259 changed files with 236349 additions and 0 deletions
708
public-onion/posts/vpn/index.html
Normal file
708
public-onion/posts/vpn/index.html
Normal file
|
|
@ -0,0 +1,708 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en" dir="auto">
|
||||
|
||||
<head><meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="robots" content="noindex, nofollow">
|
||||
<title>Stealth Trojan VPN Behind Cloudflare Guide | AlipourIm journeys</title>
|
||||
<meta name="keywords" content="VPN, Trojan, Cloudflare, Xray, 3x-ui, Bypass, Privacy, Debugging">
|
||||
<meta name="description" content="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:">
|
||||
<meta name="author" content="Iman Alipour">
|
||||
<link rel="canonical" href="http://fjthpp2h3mj2rup25r3psmqamutnkbvxbpltlohdthw6fscgo3t6bpad.onion/posts/vpn/">
|
||||
<link crossorigin="anonymous" href="/assets/css/stylesheet.31b150d909186c48d6dbbf653acc2489945fa9ac2c8f8cd3fe8448e89e40fccf.css" integrity="sha256-MbFQ2QkYbEjW279lOswkiZRfqawsj4zT/oRI6J5A/M8=" rel="preload stylesheet" as="style">
|
||||
<link rel="icon" href="http://fjthpp2h3mj2rup25r3psmqamutnkbvxbpltlohdthw6fscgo3t6bpad.onion/favicon.ico">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="http://fjthpp2h3mj2rup25r3psmqamutnkbvxbpltlohdthw6fscgo3t6bpad.onion/favicon-16x16.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="http://fjthpp2h3mj2rup25r3psmqamutnkbvxbpltlohdthw6fscgo3t6bpad.onion/favicon-32x32.png">
|
||||
<link rel="apple-touch-icon" href="http://fjthpp2h3mj2rup25r3psmqamutnkbvxbpltlohdthw6fscgo3t6bpad.onion/apple-touch-icon.png">
|
||||
<link rel="mask-icon" href="http://fjthpp2h3mj2rup25r3psmqamutnkbvxbpltlohdthw6fscgo3t6bpad.onion/safari-pinned-tab.svg">
|
||||
<meta name="theme-color" content="#2e2e33">
|
||||
<meta name="msapplication-TileColor" content="#2e2e33">
|
||||
<link rel="alternate" hreflang="en" href="http://fjthpp2h3mj2rup25r3psmqamutnkbvxbpltlohdthw6fscgo3t6bpad.onion/posts/vpn/">
|
||||
<noscript>
|
||||
<style>
|
||||
#theme-toggle,
|
||||
.top-link {
|
||||
display: none;
|
||||
}
|
||||
|
||||
</style>
|
||||
<style>
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--theme: rgb(29, 30, 32);
|
||||
--entry: rgb(46, 46, 51);
|
||||
--primary: rgb(218, 218, 219);
|
||||
--secondary: rgb(155, 156, 157);
|
||||
--tertiary: rgb(65, 66, 68);
|
||||
--content: rgb(196, 196, 197);
|
||||
--code-block-bg: rgb(46, 46, 51);
|
||||
--code-bg: rgb(55, 56, 62);
|
||||
--border: rgb(51, 51, 51);
|
||||
}
|
||||
|
||||
.list {
|
||||
background: var(--theme);
|
||||
}
|
||||
|
||||
.list:not(.dark)::-webkit-scrollbar-track {
|
||||
background: 0 0;
|
||||
}
|
||||
|
||||
.list:not(.dark)::-webkit-scrollbar-thumb {
|
||||
border-color: var(--theme);
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
</noscript><script>
|
||||
(function () {
|
||||
|
||||
|
||||
window.goatcounter = { endpoint: "/count" };
|
||||
|
||||
const s = document.createElement("script");
|
||||
s.async = true;
|
||||
s.src = "/js/count.js";
|
||||
document.head.appendChild(s);
|
||||
})();
|
||||
</script>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
|
||||
const GC = "";
|
||||
const nf = new Intl.NumberFormat();
|
||||
const SING = "visit";
|
||||
const PLUR = "visits";
|
||||
|
||||
function ready(fn) {
|
||||
if (document.readyState === "complete" || document.readyState === "interactive") setTimeout(fn, 0);
|
||||
else document.addEventListener("DOMContentLoaded", fn);
|
||||
}
|
||||
|
||||
function gcPath() {
|
||||
try {
|
||||
return window.goatcounter && window.goatcounter.get_data
|
||||
? window.goatcounter.get_data().p
|
||||
: location.pathname;
|
||||
} catch (_) {
|
||||
return location.pathname;
|
||||
}
|
||||
}
|
||||
|
||||
async function fetchCount(path, period) {
|
||||
try {
|
||||
const q = new URLSearchParams({ t: String(Date.now()) });
|
||||
if (period) q.set("start", period);
|
||||
const url = `${GC}/counter/${encodeURIComponent(path)}.json?${q}`;
|
||||
const r = await fetch(url, { credentials: "omit" });
|
||||
if (r.status === 404) return 0;
|
||||
if (!r.ok) throw 0;
|
||||
const j = await r.json();
|
||||
|
||||
const n = Number(String(j.count).replace(/,/g, ""));
|
||||
return Number.isFinite(n) ? n : 0;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
const labelVisits = (n) =>
|
||||
n === null ? "—" : `${nf.format(n)} ${n === 1 ? SING : PLUR}`;
|
||||
|
||||
ready(async function () {
|
||||
const post = document.querySelector(".post-single");
|
||||
if (post) {
|
||||
const meta = post.querySelector(
|
||||
".post-header .post-meta, .post-header .entry-meta, .post-meta"
|
||||
);
|
||||
const visits = await fetchCount(gcPath());
|
||||
if (meta) {
|
||||
let span = meta.querySelector(".post-views");
|
||||
if (!span) {
|
||||
span = document.createElement("span");
|
||||
span.className = "post-views";
|
||||
meta.appendChild(span);
|
||||
}
|
||||
span.textContent = labelVisits(visits ?? 0);
|
||||
}
|
||||
}
|
||||
|
||||
const cards = document.querySelectorAll("article.post-entry");
|
||||
await Promise.all(
|
||||
Array.from(cards).map(async (card) => {
|
||||
const meta = card.querySelector(".entry-footer, .post-meta");
|
||||
const link = card.querySelector("a.entry-link, h2 a, .entry-title a");
|
||||
if (!meta || !link) return;
|
||||
try {
|
||||
const u = new URL(link.getAttribute("href"), location.origin);
|
||||
if (u.origin !== location.origin) return;
|
||||
let span = meta.querySelector(".post-views");
|
||||
if (!span) {
|
||||
span = document.createElement("span");
|
||||
span.className = "post-views";
|
||||
meta.appendChild(span);
|
||||
}
|
||||
span.textContent = labelVisits((await fetchCount(u.pathname)) ?? 0);
|
||||
} catch {}
|
||||
})
|
||||
);
|
||||
|
||||
const uvEl = document.getElementById("gc_site_visitors_week");
|
||||
if (uvEl) {
|
||||
const n = await fetchCount("TOTAL", "week");
|
||||
uvEl.textContent = n === null ? "—" : nf.format(n);
|
||||
}
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body class="" id="top">
|
||||
<script>
|
||||
if (localStorage.getItem("pref-theme") === "dark") {
|
||||
document.body.classList.add('dark');
|
||||
} else if (localStorage.getItem("pref-theme") === "light") {
|
||||
document.body.classList.remove('dark')
|
||||
} else if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
||||
document.body.classList.add('dark');
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<header class="header">
|
||||
<nav class="nav">
|
||||
<div class="logo">
|
||||
<a href="http://fjthpp2h3mj2rup25r3psmqamutnkbvxbpltlohdthw6fscgo3t6bpad.onion/" accesskey="h" title="AlipourIm journeys (Alt + H)">AlipourIm journeys</a>
|
||||
<div class="logo-switches">
|
||||
<button id="theme-toggle" accesskey="t" title="(Alt + T)" aria-label="Toggle theme">
|
||||
<svg id="moon" xmlns="http://www.w3.org/2000/svg" width="24" height="18" viewBox="0 0 24 24"
|
||||
fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
|
||||
stroke-linejoin="round">
|
||||
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path>
|
||||
</svg>
|
||||
<svg id="sun" xmlns="http://www.w3.org/2000/svg" width="24" height="18" viewBox="0 0 24 24"
|
||||
fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
|
||||
stroke-linejoin="round">
|
||||
<circle cx="12" cy="12" r="5"></circle>
|
||||
<line x1="12" y1="1" x2="12" y2="3"></line>
|
||||
<line x1="12" y1="21" x2="12" y2="23"></line>
|
||||
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
|
||||
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
|
||||
<line x1="1" y1="12" x2="3" y2="12"></line>
|
||||
<line x1="21" y1="12" x2="23" y2="12"></line>
|
||||
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
|
||||
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<ul id="menu">
|
||||
<li>
|
||||
<a href="http://fjthpp2h3mj2rup25r3psmqamutnkbvxbpltlohdthw6fscgo3t6bpad.onion/posts/" title="Posts">
|
||||
<span>Posts</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://fjthpp2h3mj2rup25r3psmqamutnkbvxbpltlohdthw6fscgo3t6bpad.onion/phd_journey/" title="PhD_journey">
|
||||
<span>PhD_journey</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://fjthpp2h3mj2rup25r3psmqamutnkbvxbpltlohdthw6fscgo3t6bpad.onion/about/" title="About">
|
||||
<span>About</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</header>
|
||||
<main class="main">
|
||||
|
||||
<article class="post-single">
|
||||
<header class="post-header">
|
||||
<div class="breadcrumbs"><a href="http://fjthpp2h3mj2rup25r3psmqamutnkbvxbpltlohdthw6fscgo3t6bpad.onion/">Home</a> » <a href="http://fjthpp2h3mj2rup25r3psmqamutnkbvxbpltlohdthw6fscgo3t6bpad.onion/posts/">Posts</a></div>
|
||||
<h1 class="post-title entry-hint-parent">
|
||||
Stealth Trojan VPN Behind Cloudflare Guide
|
||||
</h1>
|
||||
<div class="post-meta"><span title='2025-09-09 11:05:00 +0200 +0200'>September 9, 2025</span> · 4 min · Iman Alipour
|
||||
|
||||
<span class="post-meta-item">
|
||||
<a href="http://fjthpp2h3mj2rup25r3psmqamutnkbvxbpltlohdthw6fscgo3t6bpad.onion/posts/vpn/#isso-thread" class="isso-comments-link">Comments</a>
|
||||
</span>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</header>
|
||||
<div class="post-content"><h2 id="introduction">Introduction<a hidden class="anchor" aria-hidden="true" href="#introduction">#</a></h2>
|
||||
<p>So you want a VPN that <strong>doesn’t scream “I am a VPN”</strong> to every censor and firewall out there?<br>
|
||||
Welcome to the world of <strong>Trojan over WebSocket + TLS behind Cloudflare</strong>.</p>
|
||||
<p>This guide not only shows you how to set it up but also sprinkles in some <strong>debugging magic</strong> so you can figure out why things break (and they <em>will</em> break, trust me).</p>
|
||||
<p>We’ll anonymise domains and secrets, so substitute with your own:</p>
|
||||
<ul>
|
||||
<li>VPN domain: <code>web.example.com</code></li>
|
||||
<li>Panel domain: <code>panel.example.com</code></li>
|
||||
<li>Secret WS path: <code>/stealth-path_abcd1234</code></li>
|
||||
<li>Password: <code><PASSWORD></code></li>
|
||||
</ul>
|
||||
<hr>
|
||||
<h2 id="architecture-at-a-glance">Architecture at a Glance<a hidden class="anchor" aria-hidden="true" href="#architecture-at-a-glance">#</a></h2>
|
||||
<p>Think of it as a disguise party:</p>
|
||||
<ul>
|
||||
<li><strong>Trojan</strong> = the shy guest (your VPN protocol)</li>
|
||||
<li><strong>Nginx</strong> = the bouncer checking IDs (reverse proxy)</li>
|
||||
<li><strong>Cloudflare</strong> = the doorman who makes sure nobody sees who’s inside (CDN & proxy)</li>
|
||||
<li><strong>Your fake website</strong> = the mask (camouflage page)</li>
|
||||
</ul>
|
||||
<p>Traffic flow:</p>
|
||||
|
||||
<div class="mermaid">Client → Cloudflare (443) → Nginx (443) → Trojan (localhost:54321)</div>
|
||||
|
||||
<hr>
|
||||
<h2 id="step-1-panel-setup-panelexamplecom">Step 1: Panel Setup (<code>panel.example.com</code>)<a hidden class="anchor" aria-hidden="true" href="#step-1-panel-setup-panelexamplecom">#</a></h2>
|
||||
<ul>
|
||||
<li>Bind the 3x-ui panel to localhost (e.g., <code>127.0.0.1:46309</code>).</li>
|
||||
<li>Choose a funky <strong>web base path</strong> like <code>/panel-bananas_42/</code>.</li>
|
||||
<li>Proxy it through Nginx with HTTPS + Basic Auth.</li>
|
||||
<li>Test it at <code>https://panel.example.com/panel-bananas_42/</code>.</li>
|
||||
</ul>
|
||||
<p><strong>Pro tip:</strong> If you see a blank page → your base path is mismatched or Nginx is eating it. Check logs!</p>
|
||||
<hr>
|
||||
<h2 id="step-2-trojan-inbound">Step 2: Trojan Inbound<a hidden class="anchor" aria-hidden="true" href="#step-2-trojan-inbound">#</a></h2>
|
||||
<p>In 3x-ui, create a Trojan inbound:</p>
|
||||
<ul>
|
||||
<li>Local port: <code>54321</code></li>
|
||||
<li>Transport: WebSocket</li>
|
||||
<li>Path: <code>/stealth-path_abcd1234</code></li>
|
||||
<li>Security: none</li>
|
||||
<li>Password: <code><PASSWORD></code></li>
|
||||
</ul>
|
||||
<hr>
|
||||
<h2 id="step-3-nginx-for-vpn-domain-webexamplecom">Step 3: Nginx for VPN Domain (<code>web.example.com</code>)<a hidden class="anchor" aria-hidden="true" href="#step-3-nginx-for-vpn-domain-webexamplecom">#</a></h2>
|
||||
<p>Your Nginx is the gatekeeper. Sample config:</p>
|
||||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#66d9ef">server</span> {
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">listen</span> <span style="color:#ae81ff">443</span> <span style="color:#e6db74">ssl</span> <span style="color:#e6db74">http2</span>;
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">server_name</span> <span style="color:#e6db74">web.example.com</span>;
|
||||
</span></span><span style="display:flex;"><span>
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">ssl_certificate</span> <span style="color:#e6db74">/etc/letsencrypt/live/web.example.com/fullchain.pem</span>;
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">ssl_certificate_key</span> <span style="color:#e6db74">/etc/letsencrypt/live/web.example.com/privkey.pem</span>;
|
||||
</span></span><span style="display:flex;"><span>
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#75715e"># Fake website at root
|
||||
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#f92672">location</span> <span style="color:#e6db74">/</span> {
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">root</span> <span style="color:#e6db74">/var/www/html</span>;
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">index</span> <span style="color:#e6db74">index.html</span>;
|
||||
</span></span><span style="display:flex;"><span> }
|
||||
</span></span><span style="display:flex;"><span>
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#75715e"># Real VPN under secret WS path
|
||||
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#f92672">location</span> <span style="color:#e6db74">/stealth-path_abcd1234</span> {
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">proxy_pass</span> <span style="color:#e6db74">http://127.0.0.1:54321</span>;
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">proxy_http_version</span> <span style="color:#ae81ff">1</span><span style="color:#e6db74">.1</span>;
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">proxy_set_header</span> <span style="color:#e6db74">Upgrade</span> $http_upgrade;
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">proxy_set_header</span> <span style="color:#e6db74">Connection</span> <span style="color:#e6db74">"upgrade"</span>;
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">proxy_set_header</span> <span style="color:#e6db74">Host</span> $host;
|
||||
</span></span><span style="display:flex;"><span> }
|
||||
</span></span><span style="display:flex;"><span>}
|
||||
</span></span></code></pre></div><hr>
|
||||
<h2 id="step-4-firewall-rules">Step 4: Firewall Rules<a hidden class="anchor" aria-hidden="true" href="#step-4-firewall-rules">#</a></h2>
|
||||
<p>Lock things down! Only Cloudflare should reach you:</p>
|
||||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>ufw allow 22/tcp
|
||||
</span></span><span style="display:flex;"><span>ufw allow 80/tcp
|
||||
</span></span><span style="display:flex;"><span>ufw allow 443/tcp
|
||||
</span></span><span style="display:flex;"><span>ufw deny 54321/tcp
|
||||
</span></span></code></pre></div><hr>
|
||||
<h2 id="step-5-client-config">Step 5: Client Config<a hidden class="anchor" aria-hidden="true" href="#step-5-client-config">#</a></h2>
|
||||
<p>Trojan URI:</p>
|
||||
|
||||
<div class="mermaid">trojan://<PASSWORD>@web.example.com:443?type=ws&security=tls&host=web.example.com&path=%2Fstealth-path_abcd1234&sni=web.example.com#MyStealthVPN</div>
|
||||
|
||||
<p>iOS clients: Shadowrocket, Stash, FoXray<br>
|
||||
Android clients: v2rayNG, Clash Meta, NekoBox</p>
|
||||
<hr>
|
||||
<h2 id="debugging-time-aka-why-the-heck-doesnt-it-work">Debugging Time (a.k.a. “Why the heck doesn’t it work?!”)<a hidden class="anchor" aria-hidden="true" href="#debugging-time-aka-why-the-heck-doesnt-it-work">#</a></h2>
|
||||
<h3 id="symptom-520-unknown-error-cloudflare">Symptom: <strong>520 Unknown Error (Cloudflare)</strong><a hidden class="anchor" aria-hidden="true" href="#symptom-520-unknown-error-cloudflare">#</a></h3>
|
||||
<ul>
|
||||
<li>Likely cause: Nginx couldn’t talk to Trojan.</li>
|
||||
<li>Check Nginx error log:
|
||||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>tail -n <span style="color:#ae81ff">50</span> /var/log/nginx/error.log
|
||||
</span></span></code></pre></div></li>
|
||||
<li>If you see <code>upstream sent no valid HTTP/1.0 header</code> → you’re mixing HTTPS/HTTP between Nginx and Trojan.</li>
|
||||
</ul>
|
||||
<hr>
|
||||
<h3 id="symptom-526-invalid-ssl-certificate">Symptom: <strong>526 Invalid SSL certificate</strong><a hidden class="anchor" aria-hidden="true" href="#symptom-526-invalid-ssl-certificate">#</a></h3>
|
||||
<ul>
|
||||
<li>Cloudflare → Nginx cert mismatch.</li>
|
||||
<li>Run:
|
||||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>openssl s_client -connect web.example.com:443 -servername web.example.com -showcerts
|
||||
</span></span></code></pre></div></li>
|
||||
<li>Make sure CN = <code>web.example.com</code>. If not, fix your cert.</li>
|
||||
</ul>
|
||||
<hr>
|
||||
<h3 id="symptom-blank-page-on-panel">Symptom: <strong>Blank page on panel</strong><a hidden class="anchor" aria-hidden="true" href="#symptom-blank-page-on-panel">#</a></h3>
|
||||
<ul>
|
||||
<li>Check if the base path matches exactly (case-sensitive, slash-sensitive).</li>
|
||||
<li>Watch for sneaky trailing spaces!</li>
|
||||
<li>Test locally:
|
||||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>curl -s -D- http://127.0.0.1:46309/panel-bananas_42/
|
||||
</span></span></code></pre></div></li>
|
||||
</ul>
|
||||
<hr>
|
||||
<h3 id="symptom-client-wont-connect">Symptom: <strong>Client won’t connect</strong><a hidden class="anchor" aria-hidden="true" href="#symptom-client-wont-connect">#</a></h3>
|
||||
<ul>
|
||||
<li>Run a WebSocket test:
|
||||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>curl -i -k -H <span style="color:#e6db74">"Connection: Upgrade"</span> -H <span style="color:#e6db74">"Upgrade: websocket"</span> https://web.example.com/stealth-path_abcd1234
|
||||
</span></span></code></pre></div>Expect <code>101 Switching Protocols</code>. If not, check Nginx config.</li>
|
||||
</ul>
|
||||
<hr>
|
||||
<h3 id="symptom-censor-still-blocks-you">Symptom: <strong>Censor still blocks you</strong><a hidden class="anchor" aria-hidden="true" href="#symptom-censor-still-blocks-you">#</a></h3>
|
||||
<ul>
|
||||
<li>Did you expose another service (like SSH, Matrix, or Minecraft) on the same IP?<br>
|
||||
→ They’ll find your origin IP. Use a second VPS or lock those ports down.</li>
|
||||
<li>Did you use an obvious path like <code>/ws</code>?<br>
|
||||
→ Use a random-looking one like <code>/cdn-assets-329df/</code>.</li>
|
||||
</ul>
|
||||
<hr>
|
||||
<h2 id="pro-tips--fun-tricks">Pro Tips & Fun Tricks<a hidden class="anchor" aria-hidden="true" href="#pro-tips--fun-tricks">#</a></h2>
|
||||
<ul>
|
||||
<li>Serve a fake blog or portfolio at root so your domain looks legit.</li>
|
||||
<li>Rotate WebSocket paths occasionally.</li>
|
||||
<li>Use Cloudflare <strong>Page Rules</strong> to disable Rocket Loader & Minify for your VPN domain.</li>
|
||||
<li>Make friends with your Nginx error.log — it will roast you but it tells the truth.</li>
|
||||
</ul>
|
||||
<hr>
|
||||
<h2 id="conclusion">Conclusion<a hidden class="anchor" aria-hidden="true" href="#conclusion">#</a></h2>
|
||||
<p>By putting Trojan behind Cloudflare, you’ve given your VPN a shiny new disguise:</p>
|
||||
<ul>
|
||||
<li>Looks like normal HTTPS.</li>
|
||||
<li>Hides your origin IP.</li>
|
||||
<li>Forces censors into a tough choice: block Cloudflare (and half the web) or let you pass.</li>
|
||||
</ul>
|
||||
<p>Congrats — you’ve built a VPN with both <strong>style</strong> and <strong>stealth</strong>. 🥷</p>
|
||||
<hr>
|
||||
<div class="signature-block" style="margin-top:1rem">
|
||||
<p><strong>Downloads:</strong>
|
||||
<a href="/sources/posts/vpn.md">Markdown</a> ·
|
||||
<a href="/sources/posts/vpn.md.asc">Signature (.asc)</a>
|
||||
</p><details class="signature">
|
||||
<summary>View OpenPGP signature</summary>
|
||||
<pre style="font-size:0.85em; overflow-x:auto; padding:0.75rem;">-----BEGIN PGP SIGNATURE-----
|
||||
|
||||
iQIzBAABCgAdFiEEVaKl3oR5K6zGyu4/tYgoUOBMjSoFAmpkbuAACgkQtYgoUOBM
|
||||
jSo4Yw//T40cakj/BOL/Zh0gxoW4PnH014B7h67Yirq6pB3epUix6bFaZCJnndbD
|
||||
9ZIhmnWMRzbkcA3SVhW1Y3NLpHvhK5UMXNY1qGqrGATQcoVCP7EewhL/3vXgTo5l
|
||||
jFsQFzNxcgOXKKWevuRtL5MY8RuC+PbsfG2ry2jiOtJa9H2UixVJ5E8Imj+VS47O
|
||||
S3XAlxr85O9CEh/TFkS/TuY5P5+VPoOLn6WfdCH5W2IdkW+Vi3bZFJ46LBm6cNBh
|
||||
Iydo+r2msTrqOozimc9hVorPjHZVZLMADJhcsa4pSZ4pDShBYMOZWATQErROPsdl
|
||||
5iyRbmdFb4zWcG5SgjngHnRHFrJ8PVgnFXObb3yZMqA+38RGmRNFgtR0mhMdtKNt
|
||||
QxQDOO/IfO/oNfZzIERUqUnUy/iXs44v8ttTXXE6SkYYoHW335xmDuk8ntrmQA6g
|
||||
YfXO4rJCXxsMaT6RkJaoK5YirKF/9hJYaUYY62SzdfhTmY1TFGGK0+CD+M1kQILC
|
||||
E8pXSfGhaG2bFCzQ+BRMe4o1BXLNjUhvovUgWEBnYTdGF5oXNS1MM29WxD/HC3md
|
||||
d17noEPwOujrtLxEQcAOUcQe02VOfYcX36pbr+ql32hsQMQHZtho1nx5HEGCoCWG
|
||||
3sO7WQTpdBDtkwdHnRJqKBcuWqrVd3YNMwtZE0S6oXVyWkEbB4Y=
|
||||
=IovZ
|
||||
-----END PGP SIGNATURE-----
|
||||
</pre>
|
||||
</details><p><em>Verify locally:</em></p>
|
||||
<pre style="font-size:0.85em; overflow-x:auto; padding:0.75rem;">torsocks curl -fSLO http://fjthpp2h3mj2rup25r3psmqamutnkbvxbpltlohdthw6fscgo3t6bpad.onion/sources/posts/vpn.md
|
||||
torsocks curl -fSLO http://fjthpp2h3mj2rup25r3psmqamutnkbvxbpltlohdthw6fscgo3t6bpad.onion/sources/posts/vpn.md.asc
|
||||
gpg --verify vpn.md.asc vpn.md
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<footer class="post-footer">
|
||||
<ul class="post-tags">
|
||||
<li><a href="http://fjthpp2h3mj2rup25r3psmqamutnkbvxbpltlohdthw6fscgo3t6bpad.onion/tags/vpn/">VPN</a></li>
|
||||
<li><a href="http://fjthpp2h3mj2rup25r3psmqamutnkbvxbpltlohdthw6fscgo3t6bpad.onion/tags/trojan/">Trojan</a></li>
|
||||
<li><a href="http://fjthpp2h3mj2rup25r3psmqamutnkbvxbpltlohdthw6fscgo3t6bpad.onion/tags/cloudflare/">Cloudflare</a></li>
|
||||
<li><a href="http://fjthpp2h3mj2rup25r3psmqamutnkbvxbpltlohdthw6fscgo3t6bpad.onion/tags/xray/">Xray</a></li>
|
||||
<li><a href="http://fjthpp2h3mj2rup25r3psmqamutnkbvxbpltlohdthw6fscgo3t6bpad.onion/tags/3x-ui/">3x-Ui</a></li>
|
||||
<li><a href="http://fjthpp2h3mj2rup25r3psmqamutnkbvxbpltlohdthw6fscgo3t6bpad.onion/tags/bypass/">Bypass</a></li>
|
||||
<li><a href="http://fjthpp2h3mj2rup25r3psmqamutnkbvxbpltlohdthw6fscgo3t6bpad.onion/tags/privacy/">Privacy</a></li>
|
||||
<li><a href="http://fjthpp2h3mj2rup25r3psmqamutnkbvxbpltlohdthw6fscgo3t6bpad.onion/tags/debugging/">Debugging</a></li>
|
||||
</ul>
|
||||
<nav class="paginav">
|
||||
<a class="prev" href="http://fjthpp2h3mj2rup25r3psmqamutnkbvxbpltlohdthw6fscgo3t6bpad.onion/posts/tor_clearnet_blog/">
|
||||
<span class="title">« Prev</span>
|
||||
<br>
|
||||
<span>Running my blog on Tor (.onion) and the Clearnet with Hugo + PaperMod</span>
|
||||
</a>
|
||||
<a class="next" href="http://fjthpp2h3mj2rup25r3psmqamutnkbvxbpltlohdthw6fscgo3t6bpad.onion/phd_journey/augest_2025/">
|
||||
<span class="title">Next »</span>
|
||||
<br>
|
||||
<span>Augest '25</span>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
</footer><div class="comments-switch" style="display:flex;gap:.5rem;margin:.5rem 0 1rem;">
|
||||
<button id="btn-isso" type="button" aria-pressed="true">Anonymous (Isso)</button>
|
||||
<button id="btn-giscus" type="button" aria-pressed="false">GitHub (Giscus)</button>
|
||||
<a href="https://github.com/AlipourIm/blog-comments/discussions/categories/comments" target="_blank" rel="noopener">Open on GitHub ↗</a>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<div id="panel-giscus" style="display:none">
|
||||
<section id="giscus-thread"></section>
|
||||
</div>
|
||||
|
||||
|
||||
<div id="panel-isso">
|
||||
<section id="isso-thread"
|
||||
data-isso-id="/posts/vpn/"
|
||||
data-title="Stealth Trojan VPN Behind Cloudflare Guide">
|
||||
<noscript>Javascript needs to be activated to view comments.</noscript>
|
||||
</section>
|
||||
<script
|
||||
src="/isso/js/embed.min.js"
|
||||
data-isso="/isso/"
|
||||
data-isso-css="false"
|
||||
data-isso-lang="en"
|
||||
data-isso-max-comments-nested="5"
|
||||
data-isso-sorting="newest"
|
||||
async>
|
||||
</script>
|
||||
<small class="isso-powered" style="display:block;margin:.5rem 0;color:var(--secondary,#888)">
|
||||
Comments powered by <a href="https://isso-comments.de" target="_blank" rel="noopener">Isso</a>
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
var panelIsso = document.getElementById('panel-isso');
|
||||
var panelGisc = document.getElementById('panel-giscus');
|
||||
var issoBtn = document.getElementById('btn-isso');
|
||||
var giscBtn = document.getElementById('btn-giscus');
|
||||
var gLoaded = false;
|
||||
|
||||
function isDark() {
|
||||
var pref = localStorage.getItem('pref-theme');
|
||||
if (pref === 'dark') return true;
|
||||
if (pref === 'light') return false;
|
||||
|
||||
var html = document.documentElement, body = document.body;
|
||||
if (
|
||||
(html.classList && html.classList.contains('dark')) ||
|
||||
(body.classList && body.classList.contains('dark')) ||
|
||||
html.getAttribute('data-theme') === 'dark' ||
|
||||
body.getAttribute('data-theme') === 'dark' ||
|
||||
(html.classList && html.classList.contains('theme-dark')) ||
|
||||
(body.classList && body.classList.contains('theme-dark'))
|
||||
) return true;
|
||||
|
||||
return window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
}
|
||||
function gTheme(){ return isDark() ? 'dark_dimmed' : 'noborder_light'; }
|
||||
|
||||
function loadGiscus() {
|
||||
if (gLoaded) return;
|
||||
var s = document.createElement('script');
|
||||
s.src = 'https://giscus.app/client.js';
|
||||
s.async = true;
|
||||
s.crossOrigin = 'anonymous';
|
||||
s.setAttribute('data-repo','AlipourIm/blog-comments');
|
||||
s.setAttribute('data-repo-id','R_kgDOQGARyA');
|
||||
s.setAttribute('data-category','Comments');
|
||||
s.setAttribute('data-category-id','DIC_kwDOQGARyM4Cw3x-');
|
||||
s.setAttribute('data-mapping','pathname');
|
||||
s.setAttribute('data-strict','0');
|
||||
s.setAttribute('data-reactions-enabled','1');
|
||||
s.setAttribute('data-emit-metadata','0');
|
||||
s.setAttribute('data-input-position','bottom');
|
||||
s.setAttribute('data-lang','en');
|
||||
s.setAttribute('data-theme', gTheme());
|
||||
document.getElementById('giscus-thread').appendChild(s);
|
||||
|
||||
function reTheme(){
|
||||
var iframe = document.querySelector('iframe.giscus-frame');
|
||||
if (iframe && iframe.contentWindow) {
|
||||
iframe.contentWindow.postMessage(
|
||||
{ giscus: { setConfig: { theme: gTheme() } } },
|
||||
'https://giscus.app'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
var tbtn = document.getElementById('theme-toggle');
|
||||
if (tbtn) tbtn.addEventListener('click', function(){ setTimeout(reTheme, 0); });
|
||||
|
||||
var mo = new MutationObserver(function(){ reTheme(); });
|
||||
mo.observe(document.documentElement, { attributes:true, attributeFilter:['class','data-theme'] });
|
||||
mo.observe(document.body, { attributes:true, attributeFilter:['class','data-theme'] });
|
||||
|
||||
gLoaded = true;
|
||||
}
|
||||
|
||||
function show(which) {
|
||||
var showIsso = which === 'isso';
|
||||
panelIsso.style.display = showIsso ? 'block' : 'none';
|
||||
panelGisc.style.display = showIsso ? 'none' : 'block';
|
||||
if (issoBtn) issoBtn.setAttribute('aria-pressed', showIsso ? 'true' : 'false');
|
||||
if (giscBtn) giscBtn.setAttribute('aria-pressed', showIsso ? 'false' : 'true');
|
||||
if (!showIsso) loadGiscus();
|
||||
}
|
||||
|
||||
if (issoBtn) issoBtn.addEventListener('click', function(e){ e.preventDefault(); show('isso'); });
|
||||
if (giscBtn) giscBtn.addEventListener('click', function(e){ e.preventDefault(); show('giscus'); });
|
||||
|
||||
|
||||
show('isso');
|
||||
})();
|
||||
</script>
|
||||
|
||||
|
||||
</article>
|
||||
</main>
|
||||
|
||||
<footer class="footer">
|
||||
<span>© 2026 <a href="http://fjthpp2h3mj2rup25r3psmqamutnkbvxbpltlohdthw6fscgo3t6bpad.onion/">AlipourIm journeys</a></span> ·
|
||||
|
||||
<span>
|
||||
Powered by
|
||||
<a href="https://gohugo.io/" rel="noopener noreferrer" target="_blank">Hugo</a> &
|
||||
<a href="https://github.com/adityatelange/hugo-PaperMod/" rel="noopener" target="_blank">PaperMod</a>
|
||||
</span>
|
||||
</footer>
|
||||
<a href="#top" aria-label="go to top" title="Go to Top (Alt + G)" class="top-link" id="top-link" accesskey="g">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 6" fill="currentColor">
|
||||
<path d="M12 6H0l6-6z" />
|
||||
</svg>
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
<div class="site-meta-row" style="display:flex;align-items:center;gap:.75rem;flex-wrap:wrap;">
|
||||
<a href="/index.xml" rel="alternate" type="application/rss+xml" title="RSS"
|
||||
class="rss-link" style="display:inline-flex;align-items:center;gap:.35rem;">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
||||
stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M4 11a9 9 0 0 1 9 9" />
|
||||
<path d="M4 4a16 16 0 0 1 16 16" />
|
||||
<circle cx="5" cy="19" r="1" />
|
||||
</svg>
|
||||
<span>RSS</span>
|
||||
</a>
|
||||
|
||||
<span aria-hidden="true">·</span>
|
||||
|
||||
<span>Visitors this week: <span id="gc_site_visitors_week">—</span></span>
|
||||
</div>
|
||||
|
||||
|
||||
<script>
|
||||
let menu = document.getElementById('menu')
|
||||
if (menu) {
|
||||
menu.scrollLeft = localStorage.getItem("menu-scroll-position");
|
||||
menu.onscroll = function () {
|
||||
localStorage.setItem("menu-scroll-position", menu.scrollLeft);
|
||||
}
|
||||
}
|
||||
|
||||
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
|
||||
anchor.addEventListener("click", function (e) {
|
||||
e.preventDefault();
|
||||
var id = this.getAttribute("href").substr(1);
|
||||
if (!window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
|
||||
document.querySelector(`[id='${decodeURIComponent(id)}']`).scrollIntoView({
|
||||
behavior: "smooth"
|
||||
});
|
||||
} else {
|
||||
document.querySelector(`[id='${decodeURIComponent(id)}']`).scrollIntoView();
|
||||
}
|
||||
if (id === "top") {
|
||||
history.replaceState(null, null, " ");
|
||||
} else {
|
||||
history.pushState(null, null, `#${id}`);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
<script>
|
||||
var mybutton = document.getElementById("top-link");
|
||||
window.onscroll = function () {
|
||||
if (document.body.scrollTop > 800 || document.documentElement.scrollTop > 800) {
|
||||
mybutton.style.visibility = "visible";
|
||||
mybutton.style.opacity = "1";
|
||||
} else {
|
||||
mybutton.style.visibility = "hidden";
|
||||
mybutton.style.opacity = "0";
|
||||
}
|
||||
};
|
||||
|
||||
</script>
|
||||
<script>
|
||||
document.getElementById("theme-toggle").addEventListener("click", () => {
|
||||
if (document.body.className.includes("dark")) {
|
||||
document.body.classList.remove('dark');
|
||||
localStorage.setItem("pref-theme", 'light');
|
||||
} else {
|
||||
document.body.classList.add('dark');
|
||||
localStorage.setItem("pref-theme", 'dark');
|
||||
}
|
||||
})
|
||||
|
||||
</script>
|
||||
<script>
|
||||
document.querySelectorAll('pre > code').forEach((codeblock) => {
|
||||
const container = codeblock.parentNode.parentNode;
|
||||
|
||||
const copybutton = document.createElement('button');
|
||||
copybutton.classList.add('copy-code');
|
||||
copybutton.innerHTML = 'copy';
|
||||
|
||||
function copyingDone() {
|
||||
copybutton.innerHTML = 'copied!';
|
||||
setTimeout(() => {
|
||||
copybutton.innerHTML = 'copy';
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
copybutton.addEventListener('click', (cb) => {
|
||||
if ('clipboard' in navigator) {
|
||||
navigator.clipboard.writeText(codeblock.textContent);
|
||||
copyingDone();
|
||||
return;
|
||||
}
|
||||
|
||||
const range = document.createRange();
|
||||
range.selectNodeContents(codeblock);
|
||||
const selection = window.getSelection();
|
||||
selection.removeAllRanges();
|
||||
selection.addRange(range);
|
||||
try {
|
||||
document.execCommand('copy');
|
||||
copyingDone();
|
||||
} catch (e) { };
|
||||
selection.removeRange(range);
|
||||
});
|
||||
|
||||
if (container.classList.contains("highlight")) {
|
||||
container.appendChild(copybutton);
|
||||
} else if (container.parentNode.firstChild == container) {
|
||||
|
||||
} else if (codeblock.parentNode.parentNode.parentNode.parentNode.parentNode.nodeName == "TABLE") {
|
||||
|
||||
codeblock.parentNode.parentNode.parentNode.parentNode.parentNode.appendChild(copybutton);
|
||||
} else {
|
||||
|
||||
codeblock.parentNode.appendChild(copybutton);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
Loading…
Add table
Add a link
Reference in a new issue