What you want is called "Policy Routing" where you define rules (a "policy") for what gets routed to specific routing tables. This of course requires that you create a non-default routing table as well in order to handle this newly matched traffic.
The
LARTC Howto is the de-facto guide to policy routing on Linux (and much of iproute2 as well) so I strongly suggest you read that document. Chapter 4 deals with policy routing, although non-experts generally should start at the beginning for important prerequisite information.
To allow traffic to the VPN server to use the VPN tunnel for transport (excluding the VPN transport traffic itself, of course) you need to modify what
--redirect-gateway is doing. Instead of performing step #1 described in the manpage using a /32 route, define a policy routing rule and table instead. This of course requires that you do
not use
--redirect-gateway and if you are pushing it from the server, you must ignore it (see
--route-nopull in the manpage, and remember you'll need to add in the routes you
do want if you use this directive.)
In place of the first step, you do the following:
- Use netfilter to fwmark traffic to your VPN server
- Add a rule matching on this fwmark referencing a dedicated table
- On this table, add a route via your physical interface
These steps have the same effect, without also swiping
all other IP traffic to this host.
And of course then you add in the usual two /1 routes to "override" the default gateway, routing via your VPN peer; OpenVPN's
--route directive works well, so I won't include that in the "external" actions you need to do either.
A quick practical example that I leave up to you to script into your startup (maybe with an --up script.) Let's assume your remote VPN server lives at 203.0.113.17 listening on udp/1194 and your LAN gateway is 10.0.0.1.
Also note that I
strongly recommend any netfilter (aka "iptables") rules you use be loaded at startup using your distro frontend to iptables-restore(8). For the sake of brevity I've used an iptables command here, but this is bad form unless the rule will be dynamically added
and removed with the VPN.
iptables -t mangle -A OUTPUT -d 203.0.113.17 -p udp --dport 1194 -j MARK --set-mark 128
ip rule add fwmark 128 table 100
ip route add default via 10.0.0.1 table 100
Here the first line applies an fwmark to matching packets, the 2nd one looks up routing of matched packets and sends them to table 100 to be processed, and table 100 gets a default entry to send them via your physical gateway.