Split-tunneling is a powerful technique for balancing performance, privacy, and granular control when using encrypted proxy protocols. For operators and developers deploying Trojan-based VPN setups, proper split-tunneling configuration can yield fast, reliable connections for sensitive traffic while leaving less critical flows on the direct path. This article dives into the technical details of implementing split-tunneling with Trojan (including trojan-go variants), covers routing and DNS hardening to prevent leaks, and offers practical configuration snippets and troubleshooting tips for Linux, Windows, macOS, and Android/iOS environments.

Why Split-Tunneling with Trojan?

Trojan is a TLS-based proxy that mimics HTTPS traffic to evade censorship and provide robust privacy. Compared to full-tunnel VPNs, split-tunneling lets you:

  • Preserve bandwidth and lower latency by keeping non-sensitive traffic on a direct ISP route.
  • Reduce server load and cost because only selected traffic traverses the Trojan server.
  • Apply fine-grained policies — per-app or per-destination routing, improved access control for enterprise deployments.

Core Principles for Reliable Split-Tunneling

Before implementing, follow these principles:

  • Policy-first routing: Decide routing by destination IP blocks, domains, or application identity (UID/GID on Linux).
  • DNS control: Avoid leaks by forcing DNS queries for tunneled flows through private resolvers or the Trojan server.
  • Mark and route: Use packet marking (iptables/ip rule/fwmark) or dedicated routing tables to separate flows.
  • Authentication and certificate validation: Ensure TLS certs and SNI match to avoid man-in-the-middle attacks; pin certificates when possible.

trojan-go Client: Built-in Policy Features

trojan-go (a popular go-implementation) includes flexible routing and policy configuration. Use the client-side router section to define rules and bypass lists. A representative snippet:

<pre>{
“run_type”: “client”,
“local_addr”: “127.0.0.1”,
“local_port”: 1080,
“remote_addr”: “trojan.example.com”,
“remote_port”: 443,
“password”: [“your-password”],
“ssl”: {…},
“router”: {
“enabled”: true,
“bypass”: [
“geoip:CN”,
“domain:localhost”,
“domain:example.com”
],
“default_policy”: “proxy”,
“rules”: [
{“type”:”field”,”outboundTag”:”direct”,”domain”:[“geosite:category-ads”]},
{“type”:”field”,”outboundTag”:”proxy”,”domain”:[“geosite:google”,”domain:your-cdn.com”]}
] }
}</pre>

Key points: Use geosite and geoip lists to bulk-bypass or proxy. The client can operate as a SOCKS5/HTTP proxy for per-app proxification tools or as a transparent intercept with system iptables rules.

Linux: IP Tables, Marks, and Multiple Routing Tables

On Linux servers or clients where you control networking, using iptables/ip rule and separate routing tables is the most robust approach for transparent split-tunneling.

Workflow

  • Mark packets with iptables based on user, port, or process owner.
  • Add ip rules to route marked packets through a separate routing table that sends traffic to the local Trojan client (e.g., SOCKS5) or directly re-routes to the remote Trojan server.
  • Ensure DNS queries for marked packets are routed to a safe resolver (e.g., local dnsmasq binding to 127.0.0.1 that forwards to upstream via the tunnel).

Example: Marking and Routing

Assume trojan-go listens on 127.0.0.1:1080 (SOCKS5). Mark traffic from UID 1001 (specific app) and route via the local proxy using redsocks or iptables REDIRECT for transparent proxying.

<pre># Create a new routing table
echo “200 trojan” >> /etc/iproute2/rt_tables

Mark packets from user 1001

iptables -t mangle -A OUTPUT -m owner –uid-owner 1001 -j MARK –set-mark 0x1

Use ip rule to route marked packets using table ‘trojan’

ip rule add fwmark 0x1 table trojan

Add a default route in the trojan table to the local transparent proxy (e.g., redsocks)

ip route add default via 127.0.0.1 dev lo table trojan
</pre>

For transparent TCP interception (no SOCKS-aware apps), run a local transparent proxy (redsocks2, chinadns-ng + tproxy) and redirect marked traffic to the proxy port instead of changing routing directly. Use -m tproxy targets for UDP where supported.

Preventing DNS Leaks on Linux

Common mistake: apps still query the system resolver, leaking DNS to your ISP. Use these strategies:

  • Run a local DNS resolver (dnsmasq/unbound) and configure it to forward via the Trojan tunnel (via TCP/DOH/DOH-over-proxy) for marked processes.
  • Use iptables to redirect DNS (udp/53 tcp/53) from marked UIDs to the local resolver: iptables -t nat -A OUTPUT -p udp --dport 53 -m owner --uid-owner 1001 -j DNAT --to-destination 127.0.0.1:5353.
  • Alternatively, set /etc/resolv.conf on per-network-namespace instances to point to an internal resolver.

Windows: Per-App Proxies and Route Overrides

Windows lacks native packet-marking by UID, so use per-application proxifiers or route rules:

  • Use a GUI Trojan client (trojan-qt5) that exposes a local SOCKS/HTTP proxy and configure per-app proxy settings within applications that support it.
  • For system-wide yet selective routing, add static route entries using route ADD to route specific destination networks via the local gateway or VPN adapter.
  • Use third-party tools like Proxifier, ProxyCap, or Proxychains (for Windows equivalents) to define which apps use the local Trojan proxy. These tools let you specify domain/IP rules and chain to SOCKS5 listeners.

Tip: To avoid DNS leaks on Windows, either set apps to use the SOCKS/HTTP proxy for DNS resolution (many proxifiers provide this option) or configure the system to use a DNS server reachable only via the tunnel and bind the VPN adapter accordingly.

macOS: PF and Proxification

macOS can leverage PF (packet filter) rules and tools like Proxifier for per-app policies. A common approach:

  • Run trojan-qt5 or trojan-go locally as a SOCKS5/HTTP proxy.
  • Use Proxifier to route selected apps through that proxy; Proxifier supports DNS-through-proxy to avoid leaks.
  • For advanced setups, use PF anchors to redirect traffic from certain processes or destination IPs to a local transparent proxy port.

Mobile: Android/iOS Strategies

On mobile devices you typically have two options:

  • Use an app that supports Trojan protocol natively and has split-tunnel/policy features (some trojan clients based on V2RayNG/trojan-go provide domain/geo lists).
  • Use the VPN API to create a local VPN that selectively tunnels traffic; Android VPN apps can implement per-app allowlists/blocklists, while iOS offers per-app VPN only for managed devices.

Performance Tuning and Server Considerations

To maximize throughput and reduce latency while using Trojan:

  • Keep TLS on 1.3: TLS 1.3 offers lower handshake overhead and better resumption semantics.
  • TLS session reuse: Enable session tickets/resumption on server and client to cut down on handshake time.
  • Use HTTP/2 or WebSocket transports when helpful: trojan-go supports WebSocket; this can improve compatibility behind restrictive middleboxes.
  • TCP stack tuning: Use TCP congestion control algorithms like BBR on Linux servers for better throughput in high-latency links.
  • MTU tuning: Ensure the path MTU is correct to avoid fragmentation; lower MTU slightly for encapsulated flows if you see fragmentation.
  • Multiplexing: trojan-go can multiplex connections (reduce TCP connection churn) — beneficial for high-connection-density clients.

Security Hardening

Split-tunneling inherently increases the attack surface because some traffic stays local. Harden your setup:

  • Pin TLS certificates: Configure clients to validate server certificate fingerprints (where supported) to prevent rogue CAs.
  • Enforce SNI/ALPN validation: Confirm SNI matches expected hostnames on both ends.
  • Use a kill-switch: Implement fail-closed rules for sensitive UIDs or destination IPs — if the tunnel drops, block those flows locally.
  • Log and monitor: Use connection logging (anonymized where needed) and probes to detect leaks or route failures. Tools like tcpdump, iperf, and vnstat are helpful.

Testing and Troubleshooting

Verify split-tunnel behavior carefully:

  • Use traceroute and curl --interface to confirm which path traffic takes.
  • Run tcpdump -i any port 1080 or host trojan.example.com to see proxied vs direct flows.
  • Use DNSLeakTest or dig to verify DNS queries are routed through the intended resolver.
  • Monitor ss / netstat for socket states to spot excessive SYN/FIN churn or half-open connections that affect throughput.

Example Deployment Patterns

Two practical patterns:

  • Per-application proxying: Use a local trojan client with SOCKS5 and configure only chosen apps to use it. Best for application-layer control and minimal network stack changes.
  • Transparent routing by destination: Use iptables + ip rule + separate routing table to redirect traffic destined for particular IP ranges (e.g., blocked geonets) to the trojan client. Best for enterprise environments and devices you manage fully.

Implementing split-tunneling with Trojan gives you the flexibility to optimize both performance and privacy. Whether you choose per-app proxies, routing marks, or VPN-based per-app policies, the combination of TLS-based Trojan protocol, robust DNS handling, and system-level routing ensures secure, high-performance selective tunneling.

For deployment examples, advanced configuration snippets, and dedicated IP options to reduce server-side fingerprinting, visit Dedicated-IP-VPN at https://dedicated-ip-vpn.com/.