OpenVPN - Control what goes via VPN

Hi.

I have got a worrking OpenVPN client configration running on my RPi2 that starts automatically at boot.
With the current setup all traffic goes via the tunnel.
Instead I’d like only traffic to a certain adress to go via the tunnel and all the rest of the traffic to not go via VPN.

I beleive this is done with the route command.
Will this work on Osmc? Will the route -settings stay or do we need to put a script somewhere
to autostart?

1 Like

+1
I’m also interested in achieving this.
Currently waiting for Vero2 and so far I just read that you can create an additional IP adress as alias and bind the applications you want to go through vpn tunnel to this IP alias.
And then I guess use the IP alias in the openvpn command to establish vpn tunnel.
This way all specified applications should go through tunnel, rest via normal eth0.
But I don’t know how to bind applications to an ip adress…

You can also bind the user that is running those applications (normally user ‘osmc’) to a specific tunnel. For example create a user ‘vpn-only’). There are guides and I was planning to set this up, still a plan…

Sounds more convenient and easier to me. Is it also possible to bind more than one user to a specific tunnel?
Is it as simple as adding such option to the command that starts vpn tunnel or editing a config file?

I have no idea, I am a true noob when it comes to VPN.

It would be great to set this up once and if you ever need to add an app to the “vpn only” list, all you would have to do is edit the service files to make sure it is started by the vpn-only user. Not sure if it is really possible like this.

Unfortunately I can’t seem to find that guide explaining it. When I do find it I will post the link. But I am hoping someone else can figure this out.

I’m not a big fan of running multiple applications/programs with the same user. I think it’s more clear and permissions can be handled more detailed if there’s one user for each application. With groups I would like it better.

I think I found what I was talking about:
https://www.niftiestsoftware.com/2011/08/28/making-all-network-traffic-for-a-linux-user-use-a-specific-network-interface/

What I love about this guide: no per-app configuration required! But I am not sure if this is more resource intensive (marking packets individually).

Though the next guide seems easier (it’s based on the one above). I first thought this guide did have per-app configuration, but if you read closely ‘debian-transmission’ is a user, not an application if I am correct. Which means this guide also explains how to do it on a user basis. Though it requires an extra script (up.sh) which is not necessary with the first guide:
https://docs.raccoon.io/automated-tv-series-torrent-over-vpn-downloader/

Of course if VPN goes down, Transmission (and Flexget in my case) should not be allowed to fallback on eth0. Not sure if that is taken care of with any of these guides. Any recommendation would be welcome!

I also did a quick search, I found another approach to this: Using a network namespace.
In this reddit the last but one comment states it’s “designed” for this:

Here’s a tutorial: /dev/schnouki – OpenVPN for a single application on Linux
They all refer to using a single application but I guess you can run multiple applications in one namespace…(basically in the tut he’s running 2 applications: openvpn and popcorntime)

Yep Network namespace is the ‘default’ way to do it, what I did not like in the past (before OSMC was released): I had to modify the .conf files that manage start/stopping Transmission, since you now have to fire up apps with that specific command at the end of the tutorial.

With the first guide I provided, you don’t have to mess with those files (which could be overwritten after a system update?). I wanted a method that would have minimum impact on OSMC’s app related files.

Now I am not sure which is the best way to go, namespaces or marking packets or that second guide I posted?

I get your point.
But which .conf files do you mean? The .service files?
Do you think it would work to change the excecstart line like this to start openvpn tunnel in namespace?

ExecStart=/usr/bin/ip netns exec “networknamespace” /usr/bin/openvpn --config /etc/openvpn/client.conf

So I got 9 replies on my thread, none with a single answer to my question. Hey I wasn’t asking
how to control which application should use the VPN-tunnel to connect to internet and which shouldn’t, all I am asking is to be able to route traffic to certain networks to go via the tunnel and that all the other traffic continues to use the default path (outside the tunnel).

The problem is when OpenVPN is connected there is automatically a route (on top of the list) that
sends all traffic via the tunnel, and I can’t remove it. After some googling I understand that this route is set up by something called Connmon or something similar. I can’t find any documentation how to turn that off or how to edit the routes.

Also I am getting crazy about the firewall rule to drop all SSH-incoming traffic that comes from outside the router. I tried to remove this stupidiness by editing the /etc/firewall.conf file but it seems it is not enough. I simple on/off option for this in the GUI had been quite good, or a similar command that needs to be run only once to turn it off.

Sry if I spammed your thread, maybe I missunderstood the question, I thought you want to Control what goes via VPN like your thread title said.
Seems like there are plenty of ways to do so. The previous tutorial I linked didn’t work for me.
Next I’ll try this one: Running an OpenVPN tunnel inside a network namespace …it’s a script that gets executed with the openvpn command and starts openvpn in a network namespace.

I still misunderstand, how do you distinguish the traffic that needs to go via OpenVPN from all other traffic? I am very curious about the use case here.

If it is about reaching a certain, specific IP address only via VPN, which app will do that exactly? Isn’t it always about a service/app that needs to be restricted to VPN? If so we have suggested three ways now. One of them (namespace) would allow you to only use the network namespace when you need it, for example to reach a specific IP.

But I am very interested in your use case :slight_smile:

I want to do this:

Default all traffic goes outside the tunnel.

route add -net 0.0.0.0 netmask 0.0.0.0 gw 192.168.0.1 eth0

Only traffic to the network 159.20.0.0/16 and 80.239.0.0/16 should go via the tunnel:

route add -net 159.20.0.0 netmask 255.255.0.0 gw 192.168.0.1 tun0
route add -net 80.239.0.0 netmask 255.255.0.0 gw 192.168.0.1 tun0

The problem is that there already is a default rule on top of the route list which makes all traffic goa via tunnel, and I cant remove it.

https://community.openvpn.net/openvpn/wiki/IgnoreRedirectGateway

1 Like

Thanks, that looked promising but still no result; here is a part of the log from openvpn;

`
Thu Feb 18 20:17:36 2016 /sbin/ip route add 64.0.0.0/2 via 192.168.0.1 metric 101
RTNETLINK answers: File exists
Thu Feb 18 20:17:36 2016 ERROR: Linux route add command failed: external program exited with error status: 2
Thu Feb 18 20:17:36 2016 /sbin/ip route add 128.0.0.0/2 via 192.168.0.1 metric 101
RTNETLINK answers: File exists
Thu Feb 18 20:17:36 2016 ERROR: Linux route add command failed: external program exited with error status: 2
Thu Feb 18 20:17:36 2016 /sbin/ip route add 192.0.0.0/2 via 192.168.0.1 metric 101
RTNETLINK answers: File exists
Thu Feb 18 20:17:36 2016 ERROR: Linux route add command failed: external program exited with error status: 2
Thu Feb 18 20:17:36 2016 Initialization Sequence Completed
^CThu Feb 18 20:18:15 2016 event_wait : Interrupted system call (code=4)
Thu Feb 18 20:18:15 2016 SIGTERM received, sending exit notification to peer
Thu Feb 18 20:18:16 2016 /sbin/ip route del 62.116.194.14/32
Thu Feb 18 20:18:16 2016 /sbin/ip route del 0.0.0.0/1
Thu Feb 18 20:18:16 2016 /sbin/ip route del 128.0.0.0/1
Thu Feb 18 20:18:16 2016 Closing TUN/TAP interface
Thu Feb 18 20:18:16 2016 /sbin/ip addr del dev tun1 172.27.224.218/27
Thu Feb 18 20:18:16 2016 SIGTERM[soft,exit-with-notification] received, process exiting

`