Linux routing and HMA

If you only want your specific software to use the VPN connection, then you may use network namespaces.

basically, the command ip netns add vpn will create another namespace for network devices, routing tables, firewall rules and so on, so it's like running two network stacks.

A network device can only be in one namespace, so you will need a virtual device, acting as a bridge between your two namespaces.

That's exactly what virtual network interfaces are for:

ip link add veth0 type veth peer name veth1

everything that goes in veth0 will go out of veth1, and so on. Now you only need to move one of the virtual interfaces to the other network namespace :

ip link set veth0 netns vpn

Now you have a situation similar to this network topology :

                   .----------.              .------.
[intertubes] ------|   Host   |--------------|  vpn |
               eth0`----------`veth1    veth0`------`

You can apply whatever method you want to share the internet connection. Either do masquerading (if the vpn supports traversing NAT), routing/bridging (you will need another IP address or serious configurations) or whatever method you like.

When you want to 'access' vpn, run ip netns exec vpn bash and you will end up in the vpn namespace. You will see that this namespace only have the veth0 network interface, as well as an unconfigured lo interface that you may want to configure using ip addr add 127.0.0.1/8 dev lo && ip link set lo up. Now just configure your veth0 interface so you can connect to the internet, then launch your VPN so it can reconfigure the network to go through the VPN. You will see that the main namespace will not use the VPN, while the vpn namespace will.