0

I'm running a VPN client on Ubuntu, and I'm looking for guidance on how to exclude certain ports from being routed through the VPN client (OpenVPN).

For example, how would one go about excluding ports 22 and 80 from being routed through the VPN?

I'm not an expert on networking, but I understand this would be called policy-based routing, and is possible on a Linux machine. However I couldn't find any clear guidance on how to achieve this.

EDIT: I have found a working solution here.

With the help of Piotr P. Karwasz, the following excludes traffic from being routed via VPN on the desired ports only (in this example, ports 22 and 80 of the machine running the VPN client):

# run with sudo
ip rule add sport 22 table 128
ip rule add sport 80 table 128
ip route add table 128 to y.y.y.y/y dev ethX
ip route add table 128 default via z.z.z.z

Where y.y.y.y/y should be the subnet of your [machine's] public IP address, ethX should be your [machine's] public Ethernet interface, and z.z.z.z should be the default gateway.

For example:

ip rule add sport 22 table 128
ip rule add sport 80 table 128
ip route add table 128 to 172.16.9.0/24 dev eth0
ip route add table 128 default via 172.16.9.1

Traffic on those ports (in particular outgoing) will go through the main interface [eth0 or whatever is relevant] instead of the VPN interface, which solves the following problem as explained in the above link:

this is a classic problem: when you connect to the [machine] by its public IP address, the return packets get routed over the VPN. You need to force these packets to be routed over the public eth interface.

Note that ip rule add sport (or dport for that matter) requires iproute2 version higher than 4.15 (otherwise one gets Error: argument "sport" is wrong: Failed to parse rule type).

In my cases I used Ubuntu's backports channel to get version 4.18 which works: apt install iproute2/bionic-backports

Jean Monet
  • 121
  • 6
  • There a lot of tutorials on policy based routing (e.g. [this one](https://blog.scottlowe.org/2013/05/29/a-quick-introduction-to-linux-policy-routing/)), which together with [ip-rule manpage](http://man7.org/linux/man-pages/man8/ip-rule.8.html) show how to achieve the effect you want. Can you focus your question on what you've tried so far and what seems the main problem? – Piotr P. Karwasz Apr 13 '20 at 21:38
  • Thank you I will read those in more detail. I seem to have found a simple working solution [cf edit], but will look to further understand the implications, how to include it in a script or make it persistent (avoid being locked-out of the server when starting the VPN) or bring the rules down (when stopping the VPN). – Jean Monet Apr 13 '20 at 21:52
  • The rules you posted should work as wished, except you should replace replace the `ip rule` line with `ip rule add dport 22 table 128` and `ip rule add dport 80 table 128`. Since the table `128` does not depend on the VPN connection being on, you can add these rules whenever your **main** interface is up. How to do that depends on what you use to setup your main interface. – Piotr P. Karwasz Apr 14 '20 at 05:03
  • hmm, when trying `ip rule add dport 22 table 128`, I'm getting error `Error: argument "dport" is wrong: Failed to parse rule type`, which I don't understand since the syntax seems right :( – Jean Monet Apr 14 '20 at 19:29
  • It works with version `iproute2-ss191125` (cf. `ip -V`). It was added about one year before (cf. [commit message](https://git.kernel.org/pub/scm/network/iproute2/iproute2.git/commit/ip/iprule.c?id=b2e8bf158460568ec5b48cba69f657f95891c901)) into version `4.20.0`. – Piotr P. Karwasz Apr 14 '20 at 20:12
  • ah thank you! I was just about to post my version number (`ss180129`) - will update – Jean Monet Apr 14 '20 at 20:14
  • 1
    for the record, I used `apt install iproute2/bionic-backports` to get version `4.18` on `Ubuntu 18.04`, which has `dport` selector as opposed to `4.15` which does not – Jean Monet Apr 14 '20 at 20:37
  • interestingly, I had to use `sport` instead of `dport` to get it working. I assume the logic is that packets arrive at the machine's initial IP correctly but responses are routed back via VPN which causes IP mismatch (and the security protocol is for the recipient to discart those packets). Thus `sport` tells packets coming *from* port 80 (ie the machine's response) to be routed via the main gateway instead of the VPN's gateway – Jean Monet Apr 14 '20 at 21:01

0 Answers0