Why it's useful
The default approach with routing all traffic over VPN can hit user experience sometimes. If user need to do some tasks with application which requires low traffic or speed - it can be done with cheap VPN, but comfortable web browsing will be definitely broken.
Corporate network and web surfing
Remote job opened perfect opportunities for many people. In 99% cases, remote worker should be connected to corporate network over VPN and all traffic will be routed through company server and all browsing history will be collected. Do you want to buy a ticket or check a football match score? Surely it all can be done with personal mobile phone via 4G or 5G connection, but hey - you have already the working laptop or desktop around when doing your daily job.
Torrent sharing now heavily promoted by media as bad and illegal way to share files. You can't find a torrent app for iPhone, thanks Apple! Despite all, torrent protocol still popular in music, amateur movie and documentary video industries as fast way to share demo files. If you need to give your colleagues or friends 20 GB raw video with last school game - uploading it all to a file sharing will be slow in mostly cases, way easier is to create a torrent and share the magnet link.
To hide your torrent activity from automatic scanning, it's reasonable to use VPN for torrent client only and keep your web browsing experience good like before.
Namespaces on Linux
Namespaces is an environment for a process, user, block device, also for network. And this works very well for network isolation, so we can tune network stack and routing and create a full virtual network for a simple app.
- Let's create a namespace called
ipcommands should be executed with
ip netns add vpn
- Now we need to create virtual interfaces to access our namespace:
- Create the virtual interface:
ip link add eth1v type veth peer name peer1
- Now add the
ip link set peer1 netns vpn
- Set IP to the virtual interface:
ip addr add 10.0.1.1/24 dev eth1v
- Now activate this interface:
ip link set eth1v up
- Now add IP
/24subnet to the
ip netns exec vpn ip addr add 10.0.1.2/24 dev peer1
- Activate the interface:
ip -n vpn link set peer1 up
- Add local interface in our
ip -n vpn link set lo up
- Now route traffic from
vpnnamespace to root namespace through
ip -n vpn route add default via 10.0.1.1
Here we go! Our namespace called
vpn is up and running. One task left - traffic routing through virtual interfaces.
- Enable forwarding via
echo 1 > /proc/sys/net/ipv4/ip_forward echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
- Flush all forward and NAT rules, set policy DROP by default:
iptables -P FORWARD DROP iptables -F FORWARD iptables -t nat -F
- Enable masquerading:
iptables -t nat -A POSTROUTING -s 10.0.1.0/24 -o eth0 -j MASQUERADE
- Allow forwarding between physical
iptables -A FORWARD -i eth0 -o eth1v -j ACCEPT iptables -A FORWARD -o eth0 -i eth1v -j ACCEPT
- Allow all output traffic:
iptables -P OUTPUT ACCEPT
DNS configuration in
vpn namespace can be different from default. For example, let's use Quad9 DNS servers
mkdir -p /etc/netns/vpn echo "nameserver 18.104.22.168" > /etc/netns/vpn/resolv.conf echo "nameserver 22.214.171.124" >> /etc/netns/vpn/resolv.conf
Run and hide
Let's run an application inside our namespace. We need to activate Wireguarg connection inside
ip netns exec vpn wg-quick up wg-us-florida
And finally, now it's possible to run our application inside namespace the same way as we did before. From security point of view, let's avoid using the superuser this time:
sudo ip netns exec vpn runuser $USER -c transmission
Let's summarize it all in one Bash script called
#!/bin/bash ip netns add vpn ip link add eth1v type veth peer name peer1 ip link set peer1 netns vpn ip addr add 10.0.1.1/24 dev eth1v ip link set eth1v up ip netns exec vpn ip addr add 10.0.1.2/24 dev peer1 ip -n vpn link set peer1 up ip -n vpn link set lo up ip -n vpn route add default via 10.0.1.1 echo 1 > /proc/sys/net/ipv4/ip_forward echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf iptables -P FORWARD DROP iptables -F FORWARD iptables -t nat -F iptables -t nat -A POSTROUTING -s 10.0.1.0/24 -o eth0 -j MASQUERADE iptables -A FORWARD -i eth0 -o eth1v -j ACCEPT iptables -A FORWARD -o eth0 -i eth1v -j ACCEPT iptables -P OUTPUT ACCEPT mkdir -p /etc/netns/vpn echo "nameserver 126.96.36.199" > /etc/netns/vpn/resolv.conf echo "nameserver 188.8.131.52" >> /etc/netns/vpn/resolv.conf ip netns exec vpn wg-quick up wg-us-florida sudo ip netns exec vpn runuser $USER -c "$1"
Now we can use it for many applications too:
sudo vpn.sh firefox sudo vpn.sh chrome
Another script called
reset.sh for removing the namespace and undo all changes:
#!/bin/bash ip netns exec vpn wg-quick down wg-us-florida rm -rf /etc/netns ip netns delete vpn ip addr del 10.0.1.1/24 dev eth1v ip link delete eth1v ip link delete peer1 echo 0 > /proc/sys/net/ipv4/ip_forward echo "net.ipv4.ip_forward = 0" >> /etc/sysctl.conf iptables -F
Usage is super simple:
Congrats! Stay secure.