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. |