This tutorial will show how to route all the traffic belonging to particular user account through an OpenVPN tunnel. This can be done through iptables rules that 'mark' the user's packets, which in turn allow the kernel to apply a different routing table for marked traffic
As a practical example, suppose you had Transmission daemon Bitorrent client installed. This service usually runs as the debian-transmission
user. Only debian-transmission
traffic will be routed through the VPN.
Step one - Disable OpenVPN Client from changing default gateway
In most configurations, the OpenVPN server pushes the redirect-gateway
to the clients. We don't want the VPN as the system wide default gateway.
Add the following to your client.ovpn file
pull-filter ignore redirect-gateway
Step two - Change rp_filter kernel setting
The kernel uses reverse path filtering (rp_filtering) to detect spoofed traffic. This setting must be changed for the tun0 interface
sysctl net.ipv4.conf.tun0.rp_filter = 2
Step three - Create the iptables rules
In this example, I'm using firewalld, which manages an iptables backend.
firewall-cmd --direct --permanent \
--add-rule ipv4 mangle OUTPUT 1 -m owner --uid-owner 106 -j MARK --set-mark 0xa
firewall-cmd --direct --permanent \
--add-rule ipv4 nat POSTROUTING 1 -o tun0 -j MASQUERADE
firewall-cmd --reload
Step four - Create the routing rules
Begin by creating a new routing table, and populating it with a default route
ip route add to default via $vpn_gateway_address dev tun0 table 10
ip rule add fwmark 0xa table 10
ip route flush cache
Step five - Test it's working
Your VPN origin address should appear below
sudo -u debian-transmission curl ipecho.net/plain
1.2.3.4