mysite/content/posts/vpn.md

177 lines
4.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: "Stealth Trojan VPN Behind Cloudflare Guide"
date: 2025-09-09T11:05:00+02:00
draft: false
tags: ["VPN", "Trojan", "Cloudflare", "Xray", "3x-ui", "Bypass", "Privacy", "Debugging"]
categories: ["Guides"]
---
## 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).
Well anonymise domains and secrets, so substitute with your own:
- VPN domain: `web.example.com`
- Panel domain: `panel.example.com`
- Secret WS path: `/stealth-path_abcd1234`
- Password: `<PASSWORD>`
---
## Architecture at a Glance
Think of it as a disguise party:
- **Trojan** = the shy guest (your VPN protocol)
- **Nginx** = the bouncer checking IDs (reverse proxy)
- **Cloudflare** = the doorman who makes sure nobody sees who's inside (CDN & proxy)
- **Your fake website** = the mask (camouflage page)
Traffic flow:
```
Client → Cloudflare (443) → Nginx (443) → Trojan (localhost:54321)
```
---
## Step 1: Panel Setup (`panel.example.com`)
- Bind the 3x-ui panel to localhost (e.g., `127.0.0.1:46309`).
- Choose a funky **web base path** like `/panel-bananas_42/`.
- Proxy it through Nginx with HTTPS + Basic Auth.
- Test it at `https://panel.example.com/panel-bananas_42/`.
**Pro tip:** If you see a blank page → your base path is mismatched or Nginx is eating it. Check logs!
---
## Step 2: Trojan Inbound
In 3x-ui, create a Trojan inbound:
- Local port: `54321`
- Transport: WebSocket
- Path: `/stealth-path_abcd1234`
- Security: none
- Password: `<PASSWORD>`
---
## Step 3: Nginx for VPN Domain (`web.example.com`)
Your Nginx is the gatekeeper. Sample config:
```nginx
server {
listen 443 ssl http2;
server_name web.example.com;
ssl_certificate /etc/letsencrypt/live/web.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/web.example.com/privkey.pem;
# Fake website at root
location / {
root /var/www/html;
index index.html;
}
# Real VPN under secret WS path
location /stealth-path_abcd1234 {
proxy_pass http://127.0.0.1:54321;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
}
```
---
## Step 4: Firewall Rules
Lock things down! Only Cloudflare should reach you:
```bash
ufw allow 22/tcp
ufw allow 80/tcp
ufw allow 443/tcp
ufw deny 54321/tcp
```
---
## Step 5: Client Config
Trojan URI:
```
trojan://<PASSWORD>@web.example.com:443?type=ws&security=tls&host=web.example.com&path=%2Fstealth-path_abcd1234&sni=web.example.com#MyStealthVPN
```
iOS clients: Shadowrocket, Stash, FoXray
Android clients: v2rayNG, Clash Meta, NekoBox
---
## Debugging Time (a.k.a. “Why the heck doesnt it work?!”)
### Symptom: **520 Unknown Error (Cloudflare)**
- Likely cause: Nginx couldnt talk to Trojan.
- Check Nginx error log:
```bash
tail -n 50 /var/log/nginx/error.log
```
- If you see `upstream sent no valid HTTP/1.0 header` → youre mixing HTTPS/HTTP between Nginx and Trojan.
---
### Symptom: **526 Invalid SSL certificate**
- Cloudflare → Nginx cert mismatch.
- Run:
```bash
openssl s_client -connect web.example.com:443 -servername web.example.com -showcerts
```
- Make sure CN = `web.example.com`. If not, fix your cert.
---
### Symptom: **Blank page on panel**
- Check if the base path matches exactly (case-sensitive, slash-sensitive).
- Watch for sneaky trailing spaces!
- Test locally:
```bash
curl -s -D- http://127.0.0.1:46309/panel-bananas_42/
```
---
### Symptom: **Client wont connect**
- Run a WebSocket test:
```bash
curl -i -k -H "Connection: Upgrade" -H "Upgrade: websocket" https://web.example.com/stealth-path_abcd1234
```
Expect `101 Switching Protocols`. If not, check Nginx config.
---
### Symptom: **Censor still blocks you**
- Did you expose another service (like SSH, Matrix, or Minecraft) on the same IP?
→ Theyll find your origin IP. Use a second VPS or lock those ports down.
- Did you use an obvious path like `/ws`?
→ Use a random-looking one like `/cdn-assets-329df/`.
---
## Pro Tips & Fun Tricks
- Serve a fake blog or portfolio at root so your domain looks legit.
- Rotate WebSocket paths occasionally.
- Use Cloudflare **Page Rules** to disable Rocket Loader & Minify for your VPN domain.
- Make friends with your Nginx error.log — it will roast you but it tells the truth.
---
## Conclusion
By putting Trojan behind Cloudflare, youve given your VPN a shiny new disguise:
- Looks like normal HTTPS.
- Hides your origin IP.
- Forces censors into a tough choice: block Cloudflare (and half the web) or let you pass.
Congrats — youve built a VPN with both **style** and **stealth**. 🥷
---
{{< sigdl >}}