RepoPilotOpen in app →

p4gefau1t/trojan-go

Go实现的Trojan代理,支持多路复用/路由功能/CDN中转/Shadowsocks混淆插件,多平台,无依赖。A Trojan proxy written in Go. An unidentifiable mechanism that helps you bypass GFW. https://p4gefau1t.github.io/trojan-go/

Mixed

Stale — last commit 2y ago

weakest axis
Use as dependencyConcerns

copyleft license (GPL-3.0) — review compatibility; last commit was 2y ago

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • 7 active contributors
  • GPL-3.0 licensed
  • CI configured
Show all 7 evidence items →
  • Tests present
  • Stale — last commit 2y ago
  • Concentrated ownership — top contributor handles 65% of recent commits
  • GPL-3.0 is copyleft — check downstream compatibility
What would change the summary?
  • Use as dependency ConcernsMixed if: relicense under MIT/Apache-2.0 (rare for established libs)

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Forkable" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Forkable
[![RepoPilot: Forkable](https://repopilot.app/api/badge/p4gefau1t/trojan-go?axis=fork)](https://repopilot.app/r/p4gefau1t/trojan-go)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/p4gefau1t/trojan-go on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: p4gefau1t/trojan-go

Generated by RepoPilot · 2026-05-09 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/p4gefau1t/trojan-go shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

WAIT — Stale — last commit 2y ago

  • 7 active contributors
  • GPL-3.0 licensed
  • CI configured
  • Tests present
  • ⚠ Stale — last commit 2y ago
  • ⚠ Concentrated ownership — top contributor handles 65% of recent commits
  • ⚠ GPL-3.0 is copyleft — check downstream compatibility

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live p4gefau1t/trojan-go repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/p4gefau1t/trojan-go.

What it runs against: a local clone of p4gefau1t/trojan-go — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in p4gefau1t/trojan-go | Confirms the artifact applies here, not a fork | | 2 | License is still GPL-3.0 | Catches relicense before you depend on it | | 3 | Default branch master exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 692 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>p4gefau1t/trojan-go</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of p4gefau1t/trojan-go. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/p4gefau1t/trojan-go.git
#   cd trojan-go
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of p4gefau1t/trojan-go and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "p4gefau1t/trojan-go(\\.git)?\\b" \\
  && ok "origin remote is p4gefau1t/trojan-go" \\
  || miss "origin remote is not p4gefau1t/trojan-go (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(GPL-3\\.0)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"GPL-3\\.0\"" package.json 2>/dev/null) \\
  && ok "license is GPL-3.0" \\
  || miss "license drift — was GPL-3.0 at generation time"

# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
  && ok "default branch master exists" \\
  || miss "default branch master no longer exists"

# 4. Critical files exist
test -f "main.go" \\
  && ok "main.go" \\
  || miss "missing critical file: main.go"
test -f "config/config.go" \\
  && ok "config/config.go" \\
  || miss "missing critical file: config/config.go"
test -f "component/base.go" \\
  && ok "component/base.go" \\
  || miss "missing critical file: component/base.go"
test -f "api/service/api.proto" \\
  && ok "api/service/api.proto" \\
  || miss "missing critical file: api/service/api.proto"
test -f "common/common.go" \\
  && ok "common/common.go" \\
  || miss "missing critical file: common/common.go"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 692 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~662d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/p4gefau1t/trojan-go"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

Trojan-Go is a complete Trojan proxy implementation in Go that bypasses GFW (Great Firewall) detection through TLS tunneling, multiplexing, and pluggable transport layers. It extends the original Trojan protocol with features like WebSocket-over-TLS for CDN transit, AEAD encryption, TLS fingerprint spoofing, and transparent proxy support (TCP/UDP), all without external dependencies. Layered monolith: cmd/ holds entry points; config/ handles YAML/JSON parsing; component/ is a plugin registry (server.go, client.go, nat.go for different modes); protocol/ implements Trojan wire format; tunnel/ manages multiplexing (smux integration); api/service/ exposes gRPC control plane; common/geodata/ handles IP-based routing. No hard separation between server and client logic—both are conditional modes of the same binary.

👥Who it's for

Network engineers and system administrators in regions with internet censorship who need to deploy censorship-resistant proxy servers; developers building privacy-focused applications that require transparent routing and traffic splitting between domestic and international networks.

🌱Maturity & risk

Production-ready but moderately maintained. The project has substantial feature completeness (344k lines of Go code), organized CI/CD via GitHub Actions (test.yml, release-build.yml), and a real userbase with Docker and CLI support. However, go.mod pins dependencies to 2021 versions (no recent security updates visible), suggesting the maintainer may be less active than peak development.

Low-to-moderate risk for deployment but requires awareness: dependencies are pinned to 2021 (refraction-networking/utls, shadowsocks/go-shadowsocks2), no major version bumps visible in go.mod, and the single-maintainer structure (p4gefau1t) means stalled PRs/issues if the maintainer becomes unavailable. The gRPC API surface (api/service/) and transparent proxy code (component/nat.go) are security-sensitive and would benefit from recent audits.

Active areas of work

No recent commit metadata provided in the repo snapshot, so current activity is unknown. Based on file presence: gRPC API exists (api/service/api.proto), Docker builds are automated (docker-build.yml, docker-nightly-build.yml), and linting is enforced (.golangci.yml), suggesting mature CI practices but unclear if active development continues.

🚀Get running

git clone https://github.com/p4gefau1t/trojan-go.git
cd trojan-go
make build  # Uses Makefile for compilation
# Server: ./trojan-go -server -remote 127.0.0.1:80 -local 0.0.0.0:443 -key key.key -cert cert.crt -password secret
# Client: ./trojan-go -client -remote example.com:443 -local 127.0.0.1:1080 -password secret
# Or config-based: ./trojan-go -config config.json

Daily commands:

make build                                # Compiles trojan-go binary
./trojan-go -config config.json        # Standard mode with config file
./trojan-go -server -remote 127.0.0.1:80 -local 0.0.0.0:443 -key key.key -cert cert.crt -password pwd  # Quick server
./trojan-go -client -remote host:443 -local 127.0.0.1:1080 -password pwd  # Quick client
docker run -v /etc/trojan-go/:/etc/trojan-go --network host p4gefau1t/trojan-go  # Docker

🗺️Map of the codebase

  • main.go — Entry point for the entire Trojan-Go proxy; must understand how the application initializes and routes to client/server components
  • config/config.go — Core configuration parsing and validation; all deployment modes depend on correct config structure understanding
  • component/base.go — Abstract base for all protocol components (server, client, forward, etc.); defines the plugin/component architecture that the entire system builds on
  • api/service/api.proto — gRPC service definition for the control plane API; essential for understanding remote management and status reporting capabilities
  • common/common.go — Shared utilities and error handling patterns used throughout the codebase; affects error reporting and logging everywhere
  • log/log.go — Logging abstraction layer; critical for debugging and understanding runtime behavior across all modules
  • easy/easy.go — High-level convenience API for quick initialization; entry point for understanding the simplified usage patterns

🛠️How to make changes

Add a New Custom Protocol Component

  1. Create a new struct implementing the Service interface from component/base.go with Name(), Start(), Stop(), Close() methods (component/base.go)
  2. Register your component in component/custom.go's NewCustom() factory function, mapping your config name to a constructor (component/custom.go)
  3. Update config/config.go to accept your new component type in the transport/mux/router configuration sections (config/config.go)
  4. Add example configuration to docs/content/basic/full-config.md and add a reference to docs/content/advance/customize-protocol-stack.md (docs/content/basic/full-config.md)

Add a New Routing Rule Type

  1. Extend the routing decision logic by adding new match criteria to common/geodata/loader.go or creating a new matcher struct (common/geodata/loader.go)
  2. Update the router component (referenced in component/base.go) to call your new matcher function (component/base.go)
  3. Extend config/config.go to parse your new rule format from YAML/JSON (config/config.go)
  4. Document the new rule type in docs/content/advance/router.md with examples (docs/content/advance/router.md)

Add a New Logging Backend

  1. Create a new file in log/ implementing the Logger interface from log/log.go (log/log.go)
  2. Register your logger in the factory function that initializes log output based on config (config/config.go)
  3. Export your logger type and ensure it implements io.Writer for integration with common.go utilities (common/common.go)

Add a New API Service Endpoint

  1. Define new RPC methods and message types in api/service/api.proto (api/service/api.proto)
  2. Run api/service/gen.sh to regenerate api_grpc.pb.go and api.pb.go from the proto file (api/service/gen.sh)
  3. Implement your RPC handler in api/service/server.go by adding a method to the server struct (api/service/server.go)
  4. Add a corresponding client method in api/service/client.go for testing the new endpoint (api/service/client.go)

🔧Why these technologies

  • Go 1.17 — Provides static compilation, native concurrency with goroutines, cross-platform binary support, and minimal runtime overhead ideal for proxy applications
  • gRPC + Protocol Buffers — Enables efficient remote control plane communication for statistics, user management, and multi-instance coordination
  • TLS with refraction-networking/utls — utls allows TLS fingerprint obfuscation and anti-detection mechanisms against active probing by GFW
  • xtaci/smux (multiplexing) — Combines multiple logical connections over a single TLS tunnel, reducing handshake overhead and improving throughput for multiplexed clients
  • WebSocket over TLS — Allows traffic to traverse CDNs and proxies by mimicking normal HTTP(S) connections, useful for censorship circumvention
  • MySQL Backend — Provides persistent storage for user accounts, credentials, traffic statistics, and quota enforcement across restarts
  • AEAD (Shadowsocks AEAD cipher) — Adds optional second layer of encryption on top of Trojan protocol, preventing plaintext Trojan headers from being detected

⚖️Trade-offs already made

  • Plugin/component architecture with reflection-based loading

    • Why: Allows dynamic addition of custom protocols, transports, and routing logic without recompilation
    • Consequence: Increases code complexity, potential performance overhead from interface indirection, requires careful error handling at runtime
  • Support for both TLS and alternative transports (WebSocket, custom plugins)

    • Why: Provides flexibility for different deployment scenarios and censorship countermeasures
    • Consequence: Large codebase with many conditional paths, testing surface grows exponentially, maintenance burden higher
  • Optional MySQL integration vs. in-memory mode

    • Why: Balances simplicity (in-
    • Consequence: undefined

🪤Traps & gotchas

Certificate/key paths: config.json must reference valid TLS cert/key files at absolute or relative paths; startup will fail silently if paths are wrong. MySQL mode: config requires a valid MySQL connection string and schema if using MySQL authentication; no embedded SQLite fallback. Transparent proxy (NAT): requires Linux kernel TProxy support and iptables rules; Windows/macOS cannot use nat mode. gRPC API: enabled by api.enabled=true in config.json but requires port binding; conflicts if port is already in use (no clear error). Multiplexing (smux): enabled per tunnel but adds latency overhead on slow connections; not beneficial for low-concurrency scenarios. WebSocket mode: requires a reverse proxy (nginx) or CDN in front for real deployments; direct trojan-go cannot serve both WS and regular TLS simultaneously on port 443.

🏗️Architecture

💡Concepts to learn

  • TLS Fingerprinting & Spoofing — GFW detects Trojan by analyzing TLS ClientHello patterns; Trojan-Go's refraction-networking/utls library mimics browser TLS signatures to evade active probing.
  • Multiplexing (smux) — Multiple logical tunnels over a single TCP connection reduce connection overhead and latency; Trojan-Go uses github.com/xtaci/smux to implement this.
  • AEAD (Authenticated Encryption with Associated Data) — Provides cipher-level authentication and confidentiality; Trojan-Go applies Shadowsocks AEAD ciphers (AES-GCM, ChaCha20-Poly1305) as an optional second encryption layer.
  • Transparent Proxy (TProxy / iptables NAT) — Intercepts traffic at kernel level without application-level SOCKS5 configuration; Trojan-Go's nat.go implements Linux TProxy for system-wide transparent routing.
  • WebSocket over TLS (WSS) Tunneling — Allows Trojan traffic to masquerade as HTTPS WebSocket, enabling CDN caching and DDoS mitigation; requires reverse proxy setup in real deployments.
  • Component Registry Pattern — Trojan-Go uses a plugin-like architecture where components (server, client, router, nat) are conditionally loaded based on config; enables extensibility without modifying core.
  • GFW Evasion Mechanisms — Trojan-Go integrates multiple anti-detection strategies: TLS fingerprinting, WebSocket masquerading, AEAD obfuscation, and pluggable transports—understanding which defense is active is critical for debugging connection issues.
  • shadowsocks/shadowsocks-go — Alternative Go-based proxy project; shares AEAD cipher logic with Trojan-Go and inspiration for pluggable transport design.
  • v2ray/v2ray-core — Larger proxy ecosystem (already a dependency in go.mod); Trojan-Go is compatible with v2ray's routing rules and can be wrapped by v2ray.
  • Qv2ray/Qv2ray — Official GUI client for Trojan-Go on desktop; users deploying servers will need this or Igniter-Go for end-to-end testing.
  • trojan/trojan — Original C++ Trojan implementation that Trojan-Go extends; protocol-level compatibility tested against this reference.
  • p4gefau1t/trojan-go-android — Official Android client (Igniter-Go fork); maintained by same author; demonstrates how to integrate Trojan-Go core into mobile apps.

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add comprehensive unit tests for common/geodata package

The geodata package (common/geodata/) handles critical GeoIP data loading and decoding functionality with only decode_test.go present. Missing tests for cache.go, loader.go, and interface.go means potential bugs in geo-routing could go undetected. This is especially important for a proxy tool where routing decisions directly impact functionality.

  • [ ] Create common/geodata/cache_test.go with tests for cache operations (Get, Set, expiration)
  • [ ] Create common/geodata/loader_test.go with tests for loading different data sources and error handling
  • [ ] Create common/geodata/interface_test.go with mock implementations to test the interface contract
  • [ ] Ensure tests cover edge cases like corrupted data, missing files, and concurrent access

Add missing integration tests for component package initialization

The component/ directory contains core protocol stack components (api.go, server.go, client.go, mysql.go, nat.go, forward.go) but has no accompanying test files. These components are essential for proxy functionality and server initialization. Without tests, refactoring or adding features risks breaking the plugin/component system.

  • [ ] Create component/server_test.go to test server component initialization and lifecycle
  • [ ] Create component/client_test.go to test client component setup and routing
  • [ ] Create component/custom_test.go to verify custom component loading and configuration
  • [ ] Create component/base_test.go to test the component interface contract and base functionality

Add GitHub Actions workflow for protobuf code generation validation

The repo uses Protocol Buffers (api/service/api.proto) with generated code (api.pb.go, api_grpc.pb.go) that's already committed. There's no CI check to ensure generated code stays in sync with .proto definitions. This can lead to deserialization bugs and API inconsistencies. The gen.sh script exists but isn't validated by CI.

  • [ ] Create .github/workflows/protobuf-validation.yml that runs on .proto file changes and PRs
  • [ ] Add step to run api/service/gen.sh and compare output against committed files
  • [ ] Fail the workflow if generated code differs from what's committed (catch out-of-sync .proto changes)
  • [ ] Document the required protoc version in the workflow and add it to CONTRIBUTING.md

🌿Good first issues

  • Add unit tests for common/geodata/decode.go: the decode_test.go exists but only tests one function; add tests for IP range validation and cache miss scenarios to improve coverage.
  • Document the gRPC API client usage with a runnable example in api/service/client_test.go: currently only has TestServerAPI() but no real client-side usage example; add a commented example showing how to call ListUsers() and SetSpeedLimit().
  • Implement missing component/router.go if it doesn't exist: the common/geodata/ infrastructure exists but no visible routing decision logic in component/; create a pluggable router component that evaluates geolocation rules and splits traffic.

Top contributors

Click to expand

📝Recent commits

Click to expand
  • 2dc60f5 — Chore: format code & update dependencies (#385) (Loyalsoldier)
  • 6341a5e — Chore: update test key pairs & add tests for ECC certificate (#384) (Loyalsoldier)
  • e28864f — Chore: use Go v1.17.1 (#383) (Loyalsoldier)
  • 8583de1 — Chore: include geoip-only-cn-private.dat to Docker images (#382) (Loyalsoldier)
  • 98cfe18 — Chore: use Go v1.17 & support Windows ARM64 (#377) (Loyalsoldier)
  • 07fec5e — Fix: read geoip and geosite in config file (#359) (Sousa Chinensis)
  • 068d233 — Fix(atomic panic): 64-bit fields must be 64-bit aligned on 32-bit systems (#358) (Loyalsoldier)
  • 7f8d638 — Refinement: minor fixes (#354) (cty)
  • 15817b5 — Fix: stdin config priority (#353) (Loyalsoldier)
  • d538823 — Refinement: change the default behavior of reading default configurations (#346) (Sousa Chinensis)

🔒Security observations

  • High · Outdated Go Dependencies with Known Vulnerabilities — go.mod. The project uses go.mod with dependencies pinned to versions from mid-2021. Multiple critical security vulnerabilities have been discovered in these packages since then, including golang.org/x/crypto, golang.org/x/net, and google.golang.org/grpc. For example, golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 predates multiple critical vulnerability fixes. Fix: Update all dependencies to their latest stable versions. Run 'go get -u' and perform security audits using 'go list -json -m all | nancy sleuth' or similar tools. Pay special attention to crypto and networking libraries.
  • High · Potential SQL Injection Vulnerability — component/mysql.go, common/error.go database operations. The codebase includes MySQL component (component/mysql.go) and MySQL driver dependency (github.com/go-sql-driver/mysql). Without visibility into the actual SQL query construction in component/mysql.go, there's a high risk of SQL injection if user input is directly concatenated into queries rather than using parameterized statements. Fix: Audit all SQL queries in component/mysql.go to ensure parameterized queries are used exclusively. Never concatenate user input directly into SQL statements. Use prepared statements with placeholders.
  • High · Insecure Data Download in Dockerfile — Dockerfile (lines downloading dlc.dat, geoip.dat, geoip-only-cn-private.dat). The Dockerfile downloads GeoIP and GeoSite data files from GitHub over HTTPS without checksum verification. If an attacker compromises the GitHub repository or performs a man-in-the-middle attack, malicious data files could be injected. Fix: Implement checksum verification for downloaded files. Store expected SHA256 hashes and verify them after download. Consider using signed releases or alternative distribution methods with integrity guarantees.
  • Medium · No Input Validation on Configuration Files — config/config.go, config/config_test.go. The application loads JSON/YAML configuration files (config/config.go) without apparent strict schema validation. Malformed or malicious configurations could lead to unexpected behavior, buffer overflows, or resource exhaustion attacks. Fix: Implement strict schema validation for all configuration inputs. Use a configuration validation library. Add bounds checking for numerical values (ports, timeouts, buffer sizes). Document all valid configuration options and their constraints.
  • Medium · Potential Command Injection via Git Checkout — Dockerfile (git checkout ${REF}). The Dockerfile uses an ARG REF parameter in a git checkout command without proper validation. Although the current bash syntax appears safe due to quoting, untrusted REF values could potentially be exploited if the script logic changes. Fix: Validate the REF parameter to ensure it matches expected git reference patterns (commits, tags, branches). Use strict validation before passing to shell commands. Consider using Docker build arguments validation or multi-stage verification.
  • Medium · Hardcoded Default Configuration in Docker Image — Dockerfile, example/server.json. The Dockerfile includes a hardcoded default configuration from example/server.json. This may contain insecure default settings, open ports, or credentials that users forget to override in production. Fix: Review example/server.json for secure defaults. Provide only a minimal template configuration. Document the security implications of all configuration options. Encourage users to explicitly set required parameters rather than relying on defaults.
  • Medium · Lack of TLS Certificate Pinning — Component TLS implementations, client configuration. While the project uses TLS/HTTPS extensively (WebSocket over TLS, TLS tunneling), there's no apparent certificate pinning mechanism. Users could be vulnerable to man-in-the-middle attacks if their CA stores are compromised. Fix: Implement optional TLS certificate pinning for high-security scenarios. Allow users to pin specific certificates or public keys. Document how to use this feature securely.
  • Low · Missing Security Headers Documentation — api/api.go, api/service/server.go, docs/content/. No explicit security headers or best practices documentation for deploying this proxy in production environments. Users may accidentally expose management interfaces or APIs without proper authentication. Fix: undefined

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Mixed signals · p4gefau1t/trojan-go — RepoPilot