A story
The seed of the problem
Not so many years ago when I used to live in Cuba, the only access to the internet I could use was using a Proxy set by the institution I was working for or the college I studied at. The managers on these networks used to restrict the contents you could access as hard as possible so at work you could not check Facebook or other social media, but that was not the main problem. Since Cuba is embargoed by the United States of America, several important resources like Docker images, Gitlab, and Google resources for coding in Android were all blocked for any Cuban IP. Conclusion: you need to use a VPN if you want anything done.
Not being able to pay for a VPS (no such thing as credit cards in Cuba) I was heavily using Tor, YourFreedom, or even an SSH tunnel if someone borrowed me their access to a VPS, and many other alternatives to circumvent censorship. Most of the time, these connections ended up in being a socks proxy either on my computer or my local trusted network, and I could use them easily from my browser or on several applications using tsocks or proxychains. But the holy grail of this problem was to get all the traffic from your computer to be tunneled only using a socks proxy, and that I could not achieve. Until now :-)
Recent development
What I could not foresee is that after all these years, a friend of mine would also face the same problem. As for today, two great alternatives for this are a good match in my opinion.
First, we have sshuttle and I absolutely love it. It helped me a lot during some time but it has a downside. It only works on top of SSH which is currently blocked by the only Cuban telecommunications company so we could not really use it.
Second, we have Outline and this one is also brilliant. I have read a lot about it because it seems it's heavily used to bypass censorship and all it is is a wrapper around a very nice set of tools. It basically sets a shadowsocks connection and configures your device so it behaves like a VPN. This seemed to be the right way to go, but for some odd reason, it did not want to work properly on my friend's computer.
Why not just using a VPN?
Well, Cuba is not precisely happy about their citizens using tricks to bypass their censorship and control, so they have managed to block protocols like OpenVPN. Every VPN that uses a handshake/header which is easily identifiable can be easily blocked. We could set up some obfuscation on top of the VPNs but this will require our users to also set up something on their side and that's "just fine" for a tech-savvy person, but not for our elders. In most cases, Outline is just perfectly fine because it's very hard to identify or block shadowsocks.
Making it work on a broken Linux
Most people will just re-install their OS and try again, but this time that was not an option. Also, I really wanted to fight this problem again, so, since Outline was the fittest option, I decided to go on and see what they are doing under the hood. They are open source (https://github.com/Jigsaw-Code/outline-client) so this was kind of an easy task.
Sadly, we could not isolate the problem in my friend's computer, but we were able to reproduce what the Outline folks do, and here's a guide to that:
Just tell me how to do it already!
- Start a shadowsocks server if you don't have one set already
ss-server -p 6276 -k password
. The IP address of this server is going to be $server_ip from now on. - Install the
shadowsocks-libev
package. This will provide you with all the shadowsocks utilities and will set up your local proxy connected to the shadowsocks server. - Install
badvpn-tun2socks
. This application will tunnel all your data using a Tun network interface in Linux. To install it clone their repository https://github.com/ambrop72/badvpn and follow the compile and install instructions here. - Now, let's create a new tun network interface
ip tuntap add dev tun0 mode tun user my_user
, add an IP address to itip a add 10.0.0.1/24 dev tun0
, and bring the interface upip link set dev tun0 up
. - Connect to our shadowsocks server
ss-local -s $server_ip -p 6276 -k password -l 1080
and give it a trycurl --socks5 socks5://localhost:1080 https://myip.wtf/json
. If it shows your server IP address it means it's working. - Start badvpn-tun2socks to start tunneling the data sent to
tun0
to the socks proxybadvpn-tun2socks --tundev tun0 --netif-ipaddr 10.0.0.2 --netif-netmask 255.255.255.0 --socks-server-addr 127.0.0.1:1080
. After this point you should be able to ping the virtual gatewayping 10.0.0.2
with successful results. - Add a network route to guarantee your socks proxy is still going to connect using your default gateway
ip r a $server_ip via $default_gateway
- Add a default route with a metric lower than the one provided by NetworkManager for your default gateway
ip r a default via 10.0.0.2 metric 10
And this is it. After this point, all the connections on your Linux machine are routed to the tun0 interface and therefore to the socks proxy. Do a quickcurl https://myip.wtf/json
to check that you are in the location where your shadowsocks server is and enjoy another cup of coffee.
Final words
No, you probably won't need any of this if Outline works for you, but for me, it was very satisfying to finally beat this problem and to help my friend. We could not find why Outline was not working for him, but we managed to reproduce almost exactly what Outline does and had fun in the process.
Did you enjoy reading? Leave a <3 for me on this post and share it with your nerdy friends :-)
Top comments (4)
Thanks for sharing. Based on this I created simple scripts to switch on and off socket traffic forwarding, and also added IPv6. I thought I'd share this in response, so here goes. The prerequisites are
shadowsocks-rust
andbadvpn-git
(the stable release1.999.130
from 2015 does not support--socks5-udp
).UPD: add UDP support.
First, I use two systemd template services:
/usr/lib/systemd/system/shadowsocks-rust@.service
(on Arch linux it comes withshadowsocks-rust
package):And a minimalistic service for
badvpn-tun2socks
,/etc/systemd/system/tun2socks@.service
:Then we also need
/etc/shadowsocks-rust/shadowsocket-client.json
(feel in with your info):Finally on/off scripts.
The on script:
The off script:
Thanks for this. It seems that shadowsocks-rust has built-in TUN support.
It does, but I couldn't get both IPv4 AND IPv6 tunneling to work at the same time, without
badvpn
, withshadowsocks-rust
alone.thanks for this article. it worked for me
but how can i disable it?