Thursday, August 29, 2019

Getting Split-Tunneling in Linux to work








In general when you are connected to virtual private network of your office without split tunneling, all the data will go through your vpn network interface.
Problems:
  1. It makes your system network to work slow as all the data will go through the vpn network.
  2. There might be some domains, websites which might be restricted on vpn network. For eg torrent application is running which might be prohibited in your office network.
The purpose of this article is to allow normal internet traffic via systems default network interface (eth0) and private network traffic via vpn interface (vpn0).

Next >>

The first thing to make sure is that once vpn is connected that it should not be your default route gateway.
This is achieved using vpn profile in Network Manager. Go through the vpn profile in Network Manager settings and check the box as shown below.



Next >>

The route table should look like this. Note the default traffic is still going through eth0 as per the table.

$ route -n
Kernel IP routing table
Destination  Gateway     Genmask Flags Metric Ref Use Iface
0.0.0.0      192.168.0.1 0.0.0.0 UG 600 0 0 eth0
10.193.199.0 0.0.0.0     255.255.224.0 U 50 0 0 vpn0
169.254.0.0  0.0.0.0     255.255.0.0 U 1000 0 0 eth0
192.168.0.0  0.0.0.0     255.255.255.0 U 600 0 0 eth0
192.168.0.1  0.0.0.0     255.255.255.255 UH 600 0 0 eth0
196.11.21.67 192.168.0.1 255.255.255.255 UGH 600 0 0 eth0

0.0.0.0 is the default route, any route which is not matching will end up in this route and go through it.
There may be some extra routes added by the vpn client, so you can keep them. Some VPN servers push the routes from the VPN server so as to make sure the particular range of IP traffic always go through the particular route.
  1. 10.193.199.0 is the endpoint IP through which the vpn traffic flows in and out. This is an internally assigned IP by vpn server. Each and every vpn client will get a different IP.
  2. 196.11.21.67 is the public IP through which the vpn traffic flows via internet. This IP will be common throughout all vpn clients and usually this is the vpn public server IP.

Next >>

Integrate custom script into the system default behavior whenever a vpn client connection is established and terminated.
Let’s assume you have created a vpnscript.
$HOME/bin/vpnscript.sh

#!/bin/sh
# Don't run until we bring up a real network device
[ "$IFACE" != "lo" ] || exit 0
if [ "$IFACE" = "vpn0" ]; then
if [ "$MODE" = "start" ] && [ "$ADDRFAM" = "inet" ]; then
/home/<user>/bin/routes.sh
fi
if [ "$MODE" = "stop" ] && [ "$ADDRFAM" = "inet" ]; then
#do something else
fi
fi
Make the vpnscript functional. You can also copy these scripts to a permanent place. Change $HOME to an absolute path..

sudo ln -vsf $HOME/bin/vpnscript /etc/network/if-up.d/
sudo ln -vsf $HOME/bin/vpnscript /etc/network/if-down.d/
sudo ln -vsf $HOME/bin/vpnscript /etc/network/if-post-down.d/


$HOME/bin/routes.sh
route add vpnsystem.domain.com dev vpn0
route add vpnsystem2.domain.com dev vpn0
route add VPN.SYSTEM.IP.0 dev vpn0
route add dns.vpn.ip dev vpn0
...
...
...

dns.vpn.ip could be your vpn dns server, this would also be populated into /etc/resolv.conf once vpn is connected. You can also use two dns servers in this order to make sure if the dns lookup fails in the public server then the VPN dns server is tried for lookup.
  Public/Default DNS server
  VPN DNS server

Manually enter the hosts entries which are contacted frequently. This may not be required if you are only using DNS server approach.

/etc/hosts


10.2.3.4 vpnsystem.domain.com
10.2.3.4 vpnsystem2.domain.com
..
..
..

Woof!! That is a lot of networking system but not too much for a networking expert.
Now take a pause and lets understand before moving forward.

Scenario 1:
You want to surf https://www.wikipedia.org
The public dns server will resolve your dns query to a public IP and the internet traffic goes via eth0

Scenario 2:
You want to do ssh to somesystem.domain.com
The dns query to somesystem.domain.com will fail first via public IP then the system will try to resolve dns query using vpn dns server which will eventually resolve to an IP.
Hint: Try this command first to make sure the dns query is working properly for a vpn domain.

$ dig somesystem.domain.com
; <<>> DiG 9.11.3-1ubuntu1.8-Ubuntu <<>> somesystem.domain.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 11024
;; flags: qr rd ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; WARNING: recursion requested but not available
;; QUESTION SECTION:
;somesystem.domain.com. IN A
;; ANSWER SECTION:
somesystem.domain.com. 600 IN A 10.12.20.23
;; Query time: 0 msec
;; SERVER: 127.0.0.53#53(127.0.0.53)
;; WHEN: Thu Aug 29 20:48:41 IST 2019
;; MSG SIZE rcvd: 78

After the IP is resolved to 10.12.20.23, the system will check if there a specific route in the routing table. If it is there then it will go through that interface, otherwise the ssh will try to connect it through default route which is eth0.
If it fails then you have to add the route manually like this.

$ sudo route add 10.12.20.23 dev vpn0
#also add it in routes.sh for future use.


Next >>

Seamless browsing in Firefox/Chrome without worrying about the data traffic. This will also work if your VPN provider has http proxy. In my case I will use socks5 proxy.
  • Install the FoxyProxy Extension/Add-on
  • Select the default mode User proxies based on their pre-defined patterns and priorities.
  • Add a proxy for your vpn provider and enter details.
  • Add the pattern rules for this proxy, for eg: *.domain.com*
  • If there is an option to use proxy for dns then select this option to make sure private domains are resolved via this proxy.
  • Great enjoy!!
Socks5 proxy using ssh
$ ssh -D 5353 -o ConnectTimeout=10 -o ConnectionAttempts=1 -C -N user@somesystem.domain.com
# -D dynamic socks5 port
# -C compression
# -o for extra option
# -N do not execute any remote command

3 comments: