# `BEP-0009` - Trojan Proxy and Subscription Import ```text Status: Superseded Proposal: BEP-0009 Authors: gpt-5.5 Coordinator: gpt-5.5 Reviewers: Pending Constitution Sections: II, IV, V Implementation PRs: Pending Decision Date: 2026-05-27 ``` ## Summary Superseded by `evolution/proposals/BEP-0010-proxy-subscriptions-as-packet-tunnel-networks.md`. Burrow should add daemon-owned Trojan proxy support as a proxy egress transport, plus a subscription importer that can parse base64 URI subscriptions containing `trojan://` nodes. This proposal covers Trojan profile ingestion, validation, storage, runtime boundaries, and user-facing import behavior without claiming broader Clash or Mihomo protocol parity. Trojan support should be implemented as an explicit Burrow protocol family with tested URI parsing and daemon-managed runtime behavior. Apple clients may present imported profiles and statuses, but they must continue to talk only to the daemon over gRPC. ## Motivation - Real-world proxy subscriptions commonly expose Trojan nodes as base64-encoded lists of `trojan://` URIs rather than static Clash YAML. - Users should be able to import a subscription URL and let Burrow identify compatible nodes without leaking tokens into logs, source files, or UI copy. - Trojan is different from WireGuard, Tailnet, and future MASQUE `CONNECT-IP`; it needs an explicit profile model, TLS validation policy, and proxy egress runtime. - Supporting one proxy protocol first gives Burrow a concrete path for future proxy families without adding an unbounded "Clash compatible" claim. ## Detailed Design - Add a new daemon-owned network/profile type for Trojan proxy egress. - The stable code/protocol identifier should use `trojan`. - User-facing copy should spell the project name as `Burrow` and should name the protocol as `Trojan`. - The profile type should be distinct from `WireGuard` and `Tailnet`. - Define a `TrojanProfile` payload with at least: - display name - server host - server port - password or credential reference - TLS server name indication - optional peer/host metadata when present in imported subscriptions - transport, initially restricted to `tcp` - certificate verification policy - source metadata such as imported subscription name and refresh timestamp - Add a subscription import flow owned by the daemon. - Fetch subscription URLs in daemon code, not Swift UI. - Redact query tokens and credentials from logs and errors. - Accept base64 URI subscriptions whose decoded body is a newline-separated URI list. - Parse `trojan://` URIs and reject unknown schemes unless future proposals add them. - Preserve node labels from URI fragments as display names after normalization. - Treat `allowInsecure=1`, `skip-cert-verify=true`, or equivalent flags as an explicit insecure TLS policy. - Deduplicate imported nodes by stable profile fields rather than display label alone. - Add daemon gRPC methods before any Apple UI work. - A minimal shape is `SubscriptionImportPreview`, `SubscriptionImportApply`, and `SubscriptionRefresh`. - Preview should return compatible profile counts, rejected entry counts, redacted warnings, and normalized display labels. - Apply should write only selected compatible profiles. - Refresh should preserve local enable/order choices where possible. - Add runtime support in stages. - Stage 1: parser, preview, storage, and tests only. - Stage 2: daemon-managed Trojan outbound connector for TCP proxy egress. - Evaluate `trojan-rust/trojan-rust` as the first implementation dependency for this stage. - Prefer the narrowest usable crate, likely `trojan-proto` for protocol parsing/serialization or `trojan-client` for a SOCKS5-backed client runtime. - Avoid depending on the top-level `trojan` crate with default features unless Burrow needs the bundled CLI, certificate, SQL, or agent features. - Wrap any external runtime API behind a Burrow-owned adapter so profile storage, logging, kill-switch behavior, and daemon lifecycle remain local. - Stage 3: route/DNS integration with Burrow's tunnel and proxy selection model. - Stage 4: UI controls for import, refresh, certificate policy warnings, and per-profile status. - Keep the runtime boundary explicit. - Apple UI may display forms, previews, warning states, and daemon statuses. - Apple UI must not fetch subscription URLs directly. - Apple UI must not open Trojan sockets directly. - Any helper process must be brokered and supervised by the daemon. ## Security and Operational Considerations - Subscription URLs often contain bearer tokens. Burrow must treat full subscription URLs as secrets. - Imported Trojan URIs contain passwords. Burrow must avoid writing decoded raw subscriptions to logs, crash reports, test snapshots, or telemetry. - Certificate verification defaults should be secure. Insecure imported nodes may be stored only with an explicit warning field and UI-visible risk state. - Passwords should move into the same secret-storage path Burrow uses for other long-lived credentials instead of remaining in plain payload blobs. - The importer must set fetch limits for response size, redirect depth, and timeout. - The parser must be independent and fuzzable enough to handle malformed URI lists without panics. - Runtime support should include a kill-switch path so disabling a profile tears down active sockets and route state. - Burrow must not present Trojan as a VPN with the same security or routing semantics as WireGuard. It is a proxy egress transport unless later proposals define full-device routing behavior. ## Contributor Playbook 1. Add parser-only fixtures for representative `trojan://` URIs, including TLS SNI, host, peer, TCP transport, fragments, duplicate labels, malformed ports, unsupported schemes, and insecure certificate flags. 2. Add a redacted subscription fixture that mirrors a real base64 URI-list response without preserving live tokens, passwords, or hostnames that identify a paid account. 3. Extend `proto/burrow.proto` with daemon-owned subscription preview/apply/refresh RPCs before adding Apple UI. 4. Add daemon storage for `trojan` profiles and migrate old payload storage only if the profile model requires it. 5. Verify generated Swift and Rust bindings compile after proto changes. 6. Implement runtime behind a feature flag or internal capability gate until end-to-end proxy egress tests exist. 7. Run: ```bash cargo test --workspace --all-features python3 Scripts/check-bep-metadata.py ``` 8. For Apple work, verify no Swift UI or support code fetches subscription URLs or talks to Trojan endpoints directly. ## Alternatives Considered - Import full Clash or Mihomo YAML first. Rejected for this proposal because it would imply a broad compatibility contract across many protocols before Burrow has a proxy abstraction. - Shell out to Mihomo as a helper. Rejected as the default path because it would create a large external runtime dependency and make Burrow's protocol guarantees harder to test. A future proposal may revisit helper-based compatibility as an explicit adapter. - Vendor or reimplement the Trojan wire protocol immediately. Rejected as the default path while `trojan-rust/trojan-rust` appears to provide GPL-compatible Rust crates for protocol parsing and client behavior. Burrow should still keep an adapter boundary so it can replace the dependency if maintenance, API, or security review fails. - Treat Trojan nodes as WireGuard-like networks. Rejected because Trojan is proxy egress over TLS, not a packet VPN with WireGuard peer semantics. - Let Apple UI fetch and parse subscriptions for convenience. Rejected because it violates the daemon IPC boundary and spreads subscription tokens into UI code. ## Impact on Other Work - Depends on the daemon boundary in BEP-0005. - Should align with the transport-neutral route and policy work described in BEP-0003, but should not block parser-only subscription import. - Creates a path for future Shadowsocks or VLESS proposals by forcing shared subscription parsing and redaction rules. - May require a follow-up secret-storage proposal if current network payload storage cannot safely hold proxy credentials. ## Decision Superseded by `evolution/proposals/BEP-0010-proxy-subscriptions-as-packet-tunnel-networks.md` on 2026-05-27. ## References - Trojan protocol: https://trojan-gfw.github.io/trojan/protocol.html - Trojan config: https://trojan-gfw.github.io/trojan/config.html - Trojan reference implementation: https://github.com/trojan-gfw/trojan - Rust Trojan implementation candidate: https://github.com/trojan-rust/trojan-rust - Rust `trojan-client` crate: https://crates.io/crates/trojan-client - Rust `trojan-proto` crate: https://crates.io/crates/trojan-proto - Mihomo Trojan proxy configuration: https://wiki.metacubex.one/en/config/proxies/trojan/ - BEP-0003: `evolution/proposals/BEP-0003-connect-ip-and-negotiation-roadmap.md` - BEP-0005: `evolution/proposals/BEP-0005-daemon-ipc-and-apple-boundary.md` - Burrow protocol schema: `proto/burrow.proto`