What's new

Policy Based Routing Puzzle

  • SNBForums Code of Conduct

    SNBForums is a community for everyone, no matter what their level of experience.

    Please be tolerant and patient of others, especially newcomers. We are all here to share and learn!

    The rules are simple: Be patient, be nice, be helpful or be gone!

PhilipA

New Around Here
I have an issue with VPN policy based routing I'm hoping some of the wiser forum members who have played around with this in the past can shed some light on.

I have a fairly specific need - tunnel all traffic from a specific MAC address through tun(11) unless it matches a specific ip range or top level domain. I've seen similar threads here with similar setups regarding Netflix etc, but I've tried to port the setup I used successfully on OpenWRT to my new AC86U running latest Merlin beta as it was essentially the same.

The setup uses various ipsets, iptable x-marks and a route up script in the openvpn conf file to manually add routes to a vpn routing table. I had to make some adjustments to make it fit in with the Merlin setup but all seems relatively consistent.

The problem is that, if the VPN is established without policy based routing enabled ('Force Internet traffic through tunnel > Policy Rules') then it appears no traffic can flow through tun11 - I cannot ping/reach any destination that is routed through tun11.

Weirdly, if I then enable policy base routing (even with no rules listed), the setup starts to work. Even stranger, if I then disable policy based routing, it still works!

I've looked at the routing tables and the iptables setup both pre, post and post reversion of the setting - I can't seem to find any changes that would explain why tun11 routing is not working originally, starts to work after enabling PBR and then keeps working when it is turned off again. I guess I am either looking in the wrong place or PBR is making another change I cannot locate.

The only difference I can find is that on router start, the VPN connection is reporting no public IP address - this changes when the VPN reconnects after enabling PBR.

Does anyone have any ideas, or can someone point me towards the location of the code that enacts PBR so I can see exactly what changes it makes (and does not fully unmake)?
 
I have an issue with VPN policy based routing I'm hoping some of the wiser forum members who have played around with this in the past can shed some light on.

I have a fairly specific need - tunnel all traffic from a specific MAC address through tun(11) unless it matches a specific ip range or top level domain. I've seen similar threads here with similar setups regarding Netflix etc, but I've tried to port the setup I used successfully on OpenWRT to my new AC86U running latest Merlin beta as it was essentially the same.

The setup uses various ipsets, iptable x-marks and a route up script in the openvpn conf file to manually add routes to a vpn routing table. I had to make some adjustments to make it fit in with the Merlin setup but all seems relatively consistent.

The problem is that, if the VPN is established without policy based routing enabled ('Force Internet traffic through tunnel > Policy Rules') then it appears no traffic can flow through tun11 - I cannot ping/reach any destination that is routed through tun11.

Weirdly, if I then enable policy base routing (even with no rules listed), the setup starts to work. Even stranger, if I then disable policy based routing, it still works!

I've looked at the routing tables and the iptables setup both pre, post and post reversion of the setting - I can't seem to find any changes that would explain why tun11 routing is not working originally, starts to work after enabling PBR and then keeps working when it is turned off again. I guess I am either looking in the wrong place or PBR is making another change I cannot locate.

The only difference I can find is that on router start, the VPN connection is reporting no public IP address - this changes when the VPN reconnects after enabling PBR.

Does anyone have any ideas, or can someone point me towards the location of the code that enacts PBR so I can see exactly what changes it makes (and does not fully unmake)?
RMerlin uses internal OpenVPN event scripts located in '/usr/sbin/'

e.g. config.ovpn excerpt
Code:
route-up vpnrouting.sh
route-pre-down vpnrouting.sh
up updown.sh       
down updown.sh
NOTE: vpnrouting.sh handles the RPDB rule creation/deletion and VPN routing tables.
EDIT: updown.sh is alias to 'updown-client.sh' or 'updown-server' depending on context.

So I suggest you don't override the above directives in 'config.ovpn'

Instead, simply clone '/jffs/scripts/openvpn-event' from @john9527's openvpn-event script template so you can explicitly choose which openvpn-event trigger code is actually used by each individual Server/Client.
NOTE: @Xentrk hosts a tweaked version see Xentrk's openvpn-event script template

Now you can create unique trigger event custom scripts for each client/server instance.

e.g. Create script 'vpnclient1-route-up' to add your custom iptables rules only for VPN Client 1, and delete them in an appropriate event script e.g. 'vpnclient1-route-pre-down' or 'vpnclient1-down'

Use the following to see how 'vpnrouting.sh' builds the infrastructure to allow Selective Routing
Code:
ip rule

for I in 1 2 3 4 5;do echo VPN Client ovpn$I;ip route show table 11$I;echo;done

Also see Example 5 as a guide to Selectively Routing by MAC using fwmarks.

Hopefully it will be easier to assist your current issue.
 
Last edited:
RMerlin uses internal OpenVPN event scripts located in '/usr/sbin/'

e.g. config.ovpn excerpt
Code:
route-up vpnrouting.sh
route-pre-down vpnrouting.sh
up updown.sh
down updown.sh
NOTE: vpnrouting.sh handles the RPDB rule creation/deletion.

So I suggest you don't override the above directives in 'config.ovpn'

Instead, simply clone '/jffs/scripts/openvpn-event' from @john9527's openvpn-event script template so you can explicitly choose which openvpn-event trigger code is actually used by each individual Server/Client.
NOTE: @Xentrk hosts a tweaked version see Xentrk's openvpn-event script template

Now you can create unique trigger event custom scripts for each client/server instance.

e.g. Create script 'vpnclient1-route-up' to add your custom iptables rules only for VPN Client 1, and delete them in an appropriate event script e.g. 'vpnclient1-route-pre-down' or 'vpnclient1-down'

Also see Example 5 as a guide to Selectively Routing by MAC using fwmarks.

Hopefully it will be easier to assist your current issue.

Thanks for this. I made the adjustments suggested, moving the ip route and iptables directives into the specific vpnclient script as suggested. Unfortunately this still doesn't work. I can't help but think this is somehow an openvpn connection issue rather than an issue with the setup of the firewall/routing (at least after the connection is established correctly) - the lack of a public IP address for the VPN until I toggle the policy routing option seems to be the defining aspect.

Looking through /usr/sbin/vpnrouting.sh doesn't seem to point to anything that would obviously alter the vpn connection state either - it is simply copying routes between main and ovpnc1 it would appear. That table (ovpnc1) doesn't even have a function if you have no entries in the rules table.

I guess this may come down to the question - why does an ovpn configuration with a route-nopull directive fail when policy based routing is disabled, but work after it is enabled and still work when it is disabled again? Is vpnrouting.sh creating (and leaving) a route/rule that is making things work?
 
The lack of a public IP address for the VPN until I toggle the policy routing option seems to be the defining aspect.
I have found that the STUN process (see 'gettunnelip.sh') may possibly be unreliable, i.e. the FREE VPN VPNBook never displays a 'Public' end-point but the tunnel works.o_O

upload_2019-11-14_20-30-4.png


Also apparently the router itself needs to have access to the WAN for STUN to function....

e.g. to take advantage of the VPN KILL-switch, rather than use 'Force Internet traffic through tunnel=Yes', users judiciously enable Selective Routing using 'Force Internet traffic through tunnel=Policy Rules' and naively add a single Selective Routing entry
Code:
ALL_LAN   192.168.1.0/24   0.0.0.0   VPN
omitting the crucial STUN rule
Code:
Router   192.168.1.1   0.0.0.0   WAN
[I want to] tunnel all traffic from a specific MAC address through tun(11) unless it matches a specific ip range or top level domain

Why does an ovpn configuration with a route-nopull directive fail when policy based routing is disabled, but work after it is enabled and still work when it is disabled again?
Not being argumentative but does it matter? - surely why not simply enable Selective Routing permanently (essentially that is what you want to do based on MACs) and move on?

i.e. Not having seen how you are currently achieving your goal, I would simply enable Selective Routing in the GUI, ensure 'nat-start' has added the RPDB fwmark rules, then only need to add rule
Code:
iptables -t mangle -A PREROUTING -i br0 -m mac --mac-source xx:xx:xx:xx:xx:xx -m set ! --match-set MAC_BYPASSVPN_IP dst -j MARK --set-mark 0x1000/0x1000
assuming that the IPSET MAC_BYPASSVPN_IP has been populated correctly, thereby eliminating the need for 'route-nopull' etc.

Apologies if I appear to be unsympathetic to your issue but if 'route-nopull' isn't the culprit, then perhaps there is a subtle DNS issue that only manifests itself in your edge case scripting?
 

Support SNBForums w/ Amazon

If you'd like to support SNBForums, just use this link and buy anything on Amazon. Thanks!

Sign Up For SNBForums Daily Digest

Get an update of what's new every day delivered to your mailbox. Sign up here!
Top