| Title: Routing a specific user on a specific network interface on Linux | |
| Author: Solène | |
| Date: 23 April 2022 | |
| Tags: linux networking security | |
| Description: This guide explains how to configure a network interface | |
| to be used by default by a single user without affecting the other | |
| systems users. | |
| # Introduction | |
| I have a special network need on Linux, I must have a single user going | |
| through specific VPN tunnel. This can't be done using a different | |
| metric for the VPN or by telling the program to bind on a specific | |
| interface. | |
| # How does it work | |
| The setup is easy once you find how to proceed on Linux: we define a | |
| new routing table named 42 and add a rule assigning user with uid 1002 | |
| to this routing table. It's important to declare the VPN default route | |
| on the exact same table to make it work. | |
| ```shell script | |
| #!/bin/sh | |
| REMOTEGW=YOUR_VPN_REMOTE_GATEWAY_IP | |
| LOCALIP=YOUR_VPN_LOCAL_IP | |
| INTERFACE=tun0 | |
| ip route add table 42 $REMOTEGW dev tun0 | |
| ip route add table 42 default via $REMOTEGW dev tun0 src $LOCALIP | |
| ip rule add pref 500 uidrange 1002-1002 lookup 42 | |
| ip rule add from $LOCALIP table 42 | |
| ``` | |
| # Conclusion | |
| It's quite complicated to achieve this on Linux because there are many | |
| ways to proceed like netns (network namespace), iptables or vrf but the | |
| routing solution is quite elegant, and the documentation are never | |
| obvious for this use case. | |
| I'd like to thank @[email protected] from the Fediverse for | |
| giving me the first bits about ip rules and using a different route | |
| table. |