Note: The following guide walks through deploying a Trojan VPN server and adding an obfuscation layer using an obfs-style plugin (commonly implemented via projects such as simple-obfs). The goal is to combine Trojan’s robust TLS-based transport with an additional obfuscation/transport wrapper to make detection and blocking by DPI (Deep Packet Inspection) or automated filtering systems more difficult. This article focuses on architecture, configuration, operational patterns and hardening tips tailored to site owners, enterprise operators and developers.
Why combine Trojan with an obfuscation plugin?
Trojan is a modern, TLS-based proxy that intentionally mimics HTTPS to blend traffic with normal web traffic. It is already highly effective for bypassing many types of censorship. However, in hostile environments where traffic is actively scanned, or where heuristics look for specific TLS fingerprints or connection patterns, adding a secondary obfuscation layer can significantly improve stealth and survivability.
- Defense in depth: Trojan+obfs combines application-layer masquerading (Trojan’s HTTPS mimicry) with stream-level randomization or protocol obfuscation.
- Greater resilience to automated blocking: Obfuscation plugins can present traffic as innocuous protocols (e.g., fake HTTP, simple TLS, or random bytes), confusing DPI heuristics.
- Flexibility in deployment: You can insert the obfuscation layer at the network edge (fronting) or on the client side as a local proxy, enabling chaining with other tooling such as CDN fronting or reverse proxies.
High-level architecture
There are two common deployment models when combining Trojan with an obfs plugin:
- Fronting (server-side obfs): An obfs-server (listener) accepts incoming connections on a public port (e.g., 443), deobfuscates the stream, and forwards the clear (inner) connection to a local Trojan server running on loopback. This hides the Trojan instance from public-facing scanners.
- Client-side wrapper: A client runs obfs-local which encodes traffic and sends it to the obfs-server. The obfs-local then forwards decoded traffic to the local Trojan client process. This allows legacy clients to talk to the Trojan client via localhost without native obfs support.
Diagram (conceptual):
- Client app → Trojan client (local) → obfs-local → Internet → obfs-server → Trojan server (local) → target services
Prerequisites and components
- A Linux VPS with a public IP (systemd-based distro recommended).
- Root (or sudo) access to install packages and manage ports.
- Valid TLS certificate for Trojan (recommended: automated via acme.sh or Certbot).
- Trojan server and client binaries (official Trojan or trojan-go variants).
- An obfuscation plugin implementation (simple-obfs is one widely used option; other obfs variants like obfs4 exist but have different configuration models).
Step-by-step: server-side installation and configuration
1) Obtain TLS certificate
Trojan relies on a proper TLS certificate to mimic HTTPS correctly. Use acme.sh or Certbot to obtain a certificate for the domain you will use as the SNI:
Example with acme.sh (conceptual):
acme.sh --issue --standalone -d your.domain.example --keylength ec-256
Install certs where your trojan process can read them (e.g., /etc/trojan/your.domain/).
2) Install Trojan
Follow official installation or build instructions. Place trojan configuration in /etc/trojan/config.json. A minimal server config looks like:
{
"run_type": "server",
"local_addr": "127.0.0.1",
"local_port": 4430,
"remote_addr": "0.0.0.0",
"remote_port": 0,
"password": ["your-strong-password-or-uuid"],
"ssl": {
"cert": "/etc/trojan/your.domain/fullchain.cer",
"key": "/etc/trojan/your.domain/your.key",
"sni": "your.domain.example",
"alpn": ["h2", "http/1.1"]
}
}
Note: Trojan listens on loopback (127.0.0.1:4430) because the obfs-server will accept public connections and forward locally.
3) Install obfs-plugin (example: simple-obfs)
The obfs component will accept public inbound connections and forward the de-obfuscated TCP stream to the Trojan instance.
On many distributions you can compile from source or use prebuilt packages. After installation, run obfs-server in server mode and configure it to forward to Trojan’s local port. Example (conceptual):
obfs-server --server --listen 0.0.0.0:443 --obfs tls --obfs-host your.domain.example --dest 127.0.0.1:4430
Key flags to understand:
- –listen: Public interface and port (often 443 to blend with HTTPS).
- –obfs: Obfuscation mode, e.g., tls or http (different implementations use different labels).
- –obfs-host: Hostname used in fake TLS/HTTP headers to mimic legitimate traffic.
- –dest: Where to forward the de-obfuscated stream (Trojan listening port).
4) Systemd units and process supervision
Make systemd units for both trojan and obfs-server so services restart automatically and have proper restrictions:
Example systemd snippet (conceptual):
[Unit]
Description=obfs-server wrapper
After=network.target
ExecStart=/usr/local/bin/obfs-server --server --listen 0.0.0.0:443 --obfs tls --obfs-host your.domain.example --dest 127.0.0.1:4430
Restart=on-failure
PrivateTmp=yes
NoNewPrivileges=yes [Install] WantedBy=multi-user.target
Adapt permissions and sandboxing per your security policy (CapabilityBoundingSet, ReadOnlyPaths, etc.).
5) Firewall and SELinux/AppArmor considerations
- Open only the required public ports (e.g., 443 TCP) and close unused ports.
- If using ufw/iptables, allow inbound 443 and loopback traffic to local ports.
- Adjust SELinux or AppArmor if they prevent obfs-server from binding to ports or connecting to localhost ports.
Client-side setup
On the client machine you can either run obfs-local+trojan client chained or embed obfs support into your trojan client if supported.
Option A — obfs-local chained to Trojan client
- Run obfs-local to connect to the obfs-server and expose a local SOCKS5/HTTP endpoint that your Trojan client will use (or vice versa).
- Example obfs-local client command (conceptual):
obfs-local --server server.domain.example --server-port 443 --obfs tls --obfs-host your.domain.example --local-addr 127.0.0.1 --local-port 1090 - Then configure your Trojan client to connect to the obfs-local listener, or simply configure client apps to use the obfs-local SOCKS5 proxy if you prefer not to run an additional trojan client locally.
Option B — trojan client then obfs-local
Another chaining order is Trojan client → obfs-local → obfs-server → Trojan server. Choose the direction based on your client tooling and which process expects to speak Trojan vs. raw TCP.
Security and hardening considerations
- Certificate management: Use strong crypto (ECDSA or RSA 3072+), automate renewal, and protect private keys with strict filesystem permissions.
- Port hygiene: Use 443 for public-facing obfs-server to blend with legitimate HTTPS; however, avoid exposing extra management ports publicly.
- TLS fingerprinting: Trojan’s TLS stack should be configured with ALPN and Server Name Indication (SNI) matching your domain. Obfs should also mirror common TLS characteristics if using TLS-mode obfuscation.
- Monitoring and logging: Keep minimal useful logs for troubleshooting but avoid logging sensitive secrets. Monitor connection rates and unusual behavior that may indicate active probing.
- Rate limiting and fail2ban: Protect against brute-force or probing by rate-limiting erroneous connection attempts and banning suspicious IPs.
- Isolate processes: Run obfs-server and trojan under separate, least-privileged system users and use systemd sandboxing features where appropriate.
Testing and validation
After deployment, validate behavior by:
- Connecting from a client behind a restrictive network and ensuring the tunnel establishes and data flows.
- Using packet captures (tcpdump) on the server to inspect the public stream—verify that it looks like the obfuscated protocol rather than raw Trojan payloads.
- Checking TLS details with tools like openssl s_client to validate certificates, SNI, and ALPN negotiation.
- Confirming that the Trojan server only sees connections on the loopback interface (if using server-side obfs fronting).
Operational tips and troubleshooting
- If connections fail immediately, verify that obfs-server can reach the Trojan port on loopback and that Trojan is listening correctly.
- Certificate mismatch or SNI issues commonly manifest as TLS handshakes failing—double-check the certificate paths, permissions and domain values.
- When diagnosing, temporarily enable verbose logging on both obfs and trojan (but avoid keeping verbose logs in production for privacy reasons).
- Use small-scale A/B testing when updating obfuscation modes (http vs tls) to measure detection rates and stability in your target networks.
Scalability and enterprise deployment patterns
For enterprise or high-availability deployments consider:
- Fronting obfs-server behind a load balancer or CDN (careful: CDN may interfere with custom obfs modes).
- Deploying multiple Trojan instances on different loopback ports and using a fronting process to balance connections.
- Integrating with centralized certificate management (Vault, ACME autoscripts) and configuration management (Ansible/Chef/Puppet) for consistent, repeatable deployments.
Combining Trojan with an obfuscation plugin adds meaningful complexity but also a powerful layer of stealth. For site owners and enterprise operators this pattern provides a defensible posture against active censorship while maintaining the usability and TLS-safety of Trojan.
For implementation resources, sample builds and best-practice templates, visit Dedicated-IP-VPN at https://dedicated-ip-vpn.com/.