SOCKS5 as a VPN under Linux

Being able to proxy via SOCKS5 on browser sometimes wasn’t enough, one needs a system-wide proxy. The best and simplest solution is of course VPN, but VPN is not as fast compare to SOCKS proxy like ShadowSocks under Linux. What can we do? In this article, I am going to briefly introduce System-wide SOCKS5 proxy for all applications.

This tutorial uses ShadowSocks as the primary proxy service. You should obtain ShadowSocks service before doing the following steps. You should also know this is a generic setup for SOCKS5 proxy, including SSH and others SOCKS services.

Warning: You cannot proxy DNS request with ShadowSocks, you can with SSH (requires remote server configuration). Hence if your ISP pollutes your DNS result, you must find another way to relay your DNS queries.

I am going to use BadVPN software for this purpose. Most of the steps are learned from their WiKi, I merely take notes here.

Obtain BadVPN.

Please note that the curly braced names are placeholders for you to change to a real value (without the braces themselves). This is a jinja2 template style.

ArchLinux user is able to install from AUR directly. For others, follow the following steps (Fedora as the example):

  1. Clone the repository:
git clone
  1. Install necessary libraries
sudo dnf install nspr-devel nss-devel cmake -y
  1. Create the build folder and start the compilation
mkdir build
cd build
make -j`nproc`

Now you see all the compiled software under build.

Setup BadVPN

All IP commands are used by root.
1. Create TUN device

ip tuntap add dev tun0 mode tun user 

Replace <your_user> with your normal privileged user. This rule follows in the next steps.

  1. Assign IP to TUN interface
ip addr add dev tun0
  1. Enable TUN device
ip link set tun0 up
  1. Add your ShadowSocks remote server and DNS servers to the routing table using the default gateway.
ip route add via {{ default_gw }} metric 5
ip route add via {{ default_gw }} metric 5 # or you can combine those 2 with
ip route add {{ shadowsocks_remote_server }} via {{ default_gw }} metric 5
  1. Start BadVPN
    Use normal user
cd tun2socks
./badvpn-tun2socks --tundev tun0 --netif-ipaddr --netif-netmask --socks-server-addr{{ shadowsocks_local_port }}
  1. Add default route to tun0
    Use root user
ip route add default via metric 6

Now everything you visit including Steam and Email agents etc will be routed via Socks.

Cleaning up

Remove the added default routes to, you optionally may remove other added routes but not necessary.

ip route delete dev tun0

Stop BadVPN and ShadowSocks as usual (Ctrl-C).


If you want to proxy specifically with ShadowSocks, you may install the shadowsocks-libev package and use that instead of this way.

Join the conversation


  1. Hi!

    Thanks for your article. You may want to check the code samples as some things are not showing up on the page because WordPress thinks they are HTML elements (default_gw, etc).

    Thought I’d let you know! 🙂

Leave a comment

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.