Split‑tunneling with Shadowsocks lets you route only selected traffic through an encrypted proxy while leaving the rest to your regular ISP. For webmasters, enterprise IT, and developers this approach reduces latency, protects sensitive traffic, and conserves proxy bandwidth. This guide provides a practical, step‑by‑step walkthrough with technical details and real‑world commands so you can implement secure and maintainable client‑side split‑tunneling.
Why use split‑tunneling with Shadowsocks?
Before diving into configuration, understand the tradeoffs. A full‑tunnel routes all client traffic through the proxy, which is simple but can increase latency, increase proxy costs, and create single points of failure. Split‑tunneling selectively routes only specified hosts, networks, or applications through Shadowsocks, offering:
- Performance — Keep local services local to minimize latency and bandwidth usage.
- Security — Protect only the traffic that needs confidentiality or geo‑bypass.
- Flexibility — Route by IP, domain, or per‑application depending on client platform.
High‑level architectures and methods
There are three common split‑tunneling approaches on client devices:
- Proxy‑level routing using PAC/GFWList — Configure your browser or system proxy to use Shadowsocks for domains listed in a PAC file or gfwlist. Works well for HTTP(S) and SOCKS aware apps.
- Application‑level routing — Use platform tools (Proxifier on Windows, ShadowsocksX‑NG on macOS, Shadowrocket on iOS) to send specific applications through the proxy.
- IP/route‑level routing (network stack) — Mark packets via firewall rules and route marked packets through a tun/tap interface or a local SOCKS tunnel (with redsocks/tsocks/tun2socks). This is the most flexible and transparent method — it works for all apps — but requires elevated privileges and careful routing table manipulation.
Choose the best method for your environment
For developers and sysadmins needing broad transparency, IP/route‑level split‑tunneling is preferred. For quick browser or app work, a PAC file or per‑app proxy is faster to deploy. Below we cover both the simpler PAC/app approaches and a robust Linux route‑based example with commands you can adapt.
Prerequisites
- Running Shadowsocks server reachable from the client (IP, port, password, encryption method).
- Client machine with administrative/root access for route or firewall changes (for route‑level method).
- Installed Shadowsocks client (Shadowsocks‑Windows, ShadowsocksX‑NG, shadowsocks‑android, or command line ss-local).
Method A — PAC file or domain list (fastest, for HTTP(S) and SOCKS aware apps)
Use a PAC (Proxy Auto‑Configuration) file to tell browsers or system proxy how to select the proxy based on hostname. PAC files can implement fast matching rules and integrate gfwlist.
Step‑by‑step (PAC)
- 1) Create a PAC file that routes targeted domains through the Shadowsocks SOCKS5 proxy. Example logic: use proxy for *.example.com and fallback to DIRECT otherwise.
- 2) Host the PAC file locally or on a web server and point your browser or system proxy settings to its URL.
- 3) Configure your Shadowsocks client to run a local SOCKS5 listener (default is usually 1080). Ensure “Use system proxy” or manual proxy settings point to localhost:1080.
Note: You can generate a PAC from gfwlist with online tools or use existing gfwlist‑based scripts to keep the domain list updated. PAC is lightweight and avoids tinkering with network routes.
Method B — Per‑application routing (desktop & mobile)
Use client applications that support per‑app proxying.
Windows
- Install Shadowsocks‑Windows and a third‑party tool like Proxifier or Fiddler. Configure Shadowsocks to expose a local SOCKS5 port, then create rules in Proxifier to route selected processes (e.g., chrome.exe, curl.exe) through the SOCKS5 proxy.
macOS
- Use ShadowsocksX‑NG or V2rayU which supports bypass lists and per‑app proxying. Add apps to the routing list so only those apps use the proxy.
iOS and Android
- iOS: Shadowrocket, Quantumult (require App Store availability). These clients allow per‑host, per‑app, and rule‑based routing using domain/IP matchers.
- Android: Shadowsocks Android app supports “Per‑App Proxy” on modern versions; you can also use Android’s built‑in VPN API in combination with plugin apps to create system‑wide or per‑app rules.
Method C — IP/Route‑level split‑tunneling on Linux (detailed example)
This method marks packets based on destination and routes them through a tun interface that connects to a local socks2tcp or tun2socks instance. It’s robust and works for any application without per‑app configuration.
Overview of components
- ss‑local — local Shadowsocks client that creates a SOCKS5 proxy (e.g., localhost:1080).
- tun2socks — converts tun device traffic into SOCKS5 requests and forwards them to ss‑local.
- iptables/ip rule/ip route — mark and route selected outbound packets through the tun device.
Step‑by‑step commands (conceptual, adapt to your distro)
- 1) Start ss‑local: run ss‑local -s -p -l 1080 -k -m &
- 2) Create a tun device: sudo ip tuntap add dev tunshadowsocks mode tun; sudo ip link set dev tunshadowsocks up
- 3) Run tun2socks pointed to ss‑local: tun2socks -device /dev/net/tun -proxy socks5://127.0.0.1:1080 -v
- 4) Use iptables mangle table to mark packets destined for proxied networks. For example, mark traffic to 8.8.8.8: sudo iptables -t mangle -A OUTPUT -d 8.8.8.8 -j MARK –set-mark 0x1
- 5) Add an ip rule for marked packets: sudo ip rule add fwmark 0x1 table 100
- 6) Create a routing table that uses the tun device as default: sudo ip route add default dev tunshadowsocks table 100
With these rules, any packet matching your iptables criteria is marked, and the kernel routes it via the tun device. tun2socks encapsulates those packets to the SOCKS proxy, which sends them to your remote Shadowsocks server.
Advanced: using REDIRECT + redsocks for transparent proxying
If you prefer to avoid tun devices, use redsocks to accept redirected TCP connections and forward them to a SOCKS5 proxy:
- 1) Configure redsocks to listen on 127.0.0.1:12345 and forward to socks5 127.0.0.1:1080.
- 2) Use iptables: sudo iptables -t nat -A OUTPUT -p tcp -m owner –uid-owner -j REDIRECT –to-ports 12345
- 3) This captures TCP flows from specific users/processes and redirects them into redsocks transparently.
UDP requires additional tools like tun2socks or specialized UDP relay support.
Testing and validation
After configuring, always validate routing and proxy behavior:
- Check the local listener: ss‑local should be listening on the correct port (use netstat -ltnp or ss -ltnp).
- Verify routing: ip rule show; ip route show table 100; iptables -t mangle -L -v.
- Confirm traffic source: use tcpdump or tshark on the tun device to see proxied packets: sudo tcpdump -i tunshadowsocks host .
- Use external IP checks from both proxied and non‑proxied hosts to confirm split behavior (e.g., curl –interface ifconfig.co).
Common pitfalls and hardening tips
- DNS leaks — Ensure DNS queries for proxied domains are either sent through the proxy (use a remote DNS) or filtered. Configure systemd‑resolved, dnsmasq, or the client’s DNS setting to avoid leaking DNS to the local ISP. For route‑level setups, redirect DNS traffic through the proxy as needed.
- Firewall order — On Linux iptables order matters. Check nat/mangle/forward chains carefully and persist rules across reboots.
- UDP traffic — Many transparent proxy tools handle TCP only. Use tun2socks or specialized UDP relays for DNS/VoIP/QUIC traffic.
- Performance — Marking and tunneling add overhead. Monitor latency and CPU usage; use optimized implementations and consider multi‑threaded tun2socks if available.
- Security — Keep your Shadowsocks server software and client libraries updated. Restrict server access via firewall and consider using ACLs or port knocking for higher security.
Operational recommendations for enterprises
For multi‑user environments and enterprise deployments, consider:
- Centralized PAC or configuration distribution (use group policies or MDM for macOS/iOS) so rules remain consistent across devices.
- Logging and monitoring — track which destinations are proxied and integrate with IDS/IPS to detect anomalous behaviour.
- Automated updates — use managed packages or containerized ss‑local for predictable deployment and easier patching.
- Failover and redundancy — use multiple Shadowsocks endpoints and client logic to switch if one server fails.
Troubleshooting checklist
- No proxied traffic: verify ss‑local and tun2socks are running and that ip route and ip rule entries exist.
- DNS still leaking: intercept port 53 with iptables and redirect it to your stub resolver or ensure the client uses a secure DNS over HTTPS/TLS tunneled through the proxy.
- Only some apps proxied: confirm app uses system proxy or is included in per‑app rules; for transparent routing ensure iptables marking covers the socket owner or destination correctly.
Split‑tunneling with Shadowsocks provides a powerful balance of security and efficiency when you need precise control over which traffic should be protected. Whether you choose PAC files, per‑app routing, or a robust route‑based solution with tun2socks and iptables, the key is careful testing and ongoing monitoring to avoid leaks and maintain performance.
For additional enterprise‑grade guides, configuration snippets, and managed deployment strategies, visit Dedicated‑IP‑VPN: https://dedicated-ip-vpn.com/