What's new

A couple of questions regarding the implementation of RGW:No and Exclusive DNS (386.4)

  • 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!

up4k

New Around Here
Hi!

First I will describe my config, and then the problems that I encountered when upgraded from version 386.2_2 to 386.4

The router is used as a gateway to my work network. The connection is made using OpenVPN, here is a part of the client config:

Code:
client
proto udp
dev tun
remote ovpn.example.net # for example, the address resolves to 11.22.33.44
nobind
persist-key
persist-tun
comp-lzo
setenv opt block-outside-dns

When connected, the server pushes routes to private and public subnets. The default route remains my ISP. Among the public routes that the server pushes, there are 11.22.33.0/24 (that is, the subnet that owns the public address of the openvpn server itself). Since (in the 2_2 firmware) the openvpn client creates a direct route to /32 to my ISP for this situation, there are no routing problems, since smaller masks take precedence.
Also, the server pushes the DNS addresses that should be used for resolving when using a work network.

On the old firmware, where the network settings were controlled by the openvpn client, I used the following settings:
Code:
Redirect Internet traffic through tunnel: No
Accept DNS Configuration: Exclusive (see the option in the config provided)

When trying to use the same settings with the new firmware, I ran into two problems:

1. The public route that includes the address 11.22.33.44 goes through the tunnel interface. A separate route for /32 is not created. The logs show that the openvpn client is pushing:
Code:
PUSH: Received control message: 'PUSH_REPLY,route-gateway 10.250.0.1,topology subnet,ping 5,ping-restart 30,dhcp-option DOMAIN ~.,dhcp-option DNS 172.16.4.7,dhcp-option DNS 172.16.4.30,route 11.22.33.44 255.255.255.255 net_gateway, etc...
But when these routes are processed by the openvpn-routing handler, the route is assigned to dev tun:
Code:
Add pushed route: /usr/sbin/ip route add 11.22.33.44/255.255.255.255 via 192.168.10.1 dev tun11 table ovpnc1
The kernel discards this route because it is on the wrong interface.

After that, the connection with the server is lost and openvpn-client goes into a loop of attempts to connect to the server. The route to which is wrapped in a tunnel.

In src/router/libovpn/openvpn_control.c (current branch, commit 598756e) there is code on line 391 for (Force traffic to remote VPN server to go through local GW), but it only works if (rgw != OVPN_RGW_NONE).

It seems to me that there will be nothing wrong if, for each ovpn-client table in the routes, the route to the server through localgw is unconditionally defined, even in the case of RGW: No. Offhand, this may interfere with VPN chaining, but I'm not sure that in the current implementation it is even possible.

2. Exclusive DNS configuration with RGW:No is not respected, the /tmp/resolv.dnsmasq config contains the address of the local (ISP) DNS server (with and without local domain) in addition to the addresses that the openvpn server pushes. In this case, I did not parse the source code and cannot suggest where it would be worth correcting. I assume that exclusive DNS only works with VPN Director, and in RGW:No mode, Relaxed/Strict always used.

At the moment (as a temporary solution) I have written a dirty openvpn-event script that I use along with the RGW:All mode:
Bash:
#!/bin/sh

###
# Removing all default routes from all RGW ovpn clients (cuz non-RGW works incorrect).
###

_log()
{
    /usr/bin/logger -t openvpn-event -p 6 $@
}

case "$script_type" in

    "route-up")
        table="$(/usr/sbin/ip route list table all | /bin/grep default | /bin/grep "$dev" | /usr/bin/awk '{print $NF}')"
        _log "Removing RGW default route from iface $dev table $table."
        /usr/sbin/ip route delete default table $table
    ;;

    "route-pre-down")
#       _log "Reverting removed RGW default route."
###     Nothing to do here: handler removes whole routing table.
    ;;

    "*")
        _log "Unknown event!"

esac

This solves my first and second problems: the default route is my ISP, and the DNS servers for global resolution are pulled from the work server. But in general config remains inconsistent and, as mentioned, dirty.

I would like to know if improvements are planned on both points? The libovpn code regarding routing has not changed for half a year, and at the moment it is WIP with IPv6, if I understand correctly. As for the DNS configuration, the answer to the question is even more obscure, because (I think) there may be conflicts with the current VPN Director implementation (or non-obvious priority rules will have to be applied).

Nevertheless, I would be grateful if I hear explanations for my questions. Thanks!
 
 
Thank you, but I think it's unrelated (or slightly related) to my original topic questions.
Again:
1. In the site-to-site scenario (RGW:No), openvpn server/client may push some routes (as in my case), that includes wide (>/32) subnet containing public IP of remote VPN endpoint. libovpn wrapper handles this routes, adds it to system routing table, but does not add direct (/32) route to the VPN server IP over the WAN interface. As a result, no traffic at all.
There is code in openvpn_control.c that adds direct route through WAN interface, but this code executed only if RGW:Yes. Question is, what is the reason to not adding this route unconditionally in any situation (both RGW and non_RGW)? Just one direct route for every ovpn_client. This should not break anything.
2. Any reason to not respect the Exclusive DNS option when RGW:No (and to add WAN nameservers to dnsmasq config in any case)? In the case of, say, multiple non_RGW ovpn_clients, Client1 could take precedence over Client2 etc (i.e. dnsmasq could use only Exclusive nameservers from active ovpn_client with lower number; but of course RGW client must take precedence over all).

Thank you!
 
After looking at this a lot deeper (which is why it took me so long to respond), I believe I better understand the situation.

Regarding the route directive, prior to the VPN Director, the router only handled a portion of the routing, specifically that regarding policy routing. But in more recent builds (iirc, 386.3 and up), the router manages *all* the routing, regardless whether you have "Redirect Internet traffic through tunnel" set to No, Yes, or VPN Director. And it does this by injecting the route-noexec directive into the config and passing responsibility to the route-up script.

Prior to the VPN Director, that push'd route was probably handled by OpenVPN itself. And so it worked as expected. But when the VPN Director was introduced, we ran into an unrelated bug.


In short, because the VPN Director was NOT being explicit wrt the tunnel's network interface when adding VPN routes, it was forcing the routing system to make the decision. And as a result, for all OpenVPN clients that shared the same routing on the IP tunnel (which is NOT all that uncommon when dealing w/ the same commercial OpenVPN provider), it would use the network interface for the first OpenVPN client that established the route, *and* all subsequent OpenVPN clients! Obviously that was a mistake.

To correct that problem, 386.4 was modified to specifically bind those VPN routes to their proper network interface (tun11, tun12, whatever).

So here's what I think is happening.

Because the prior firmware was NOT specific as to the VPN's network interface, your route (11.22.33.44/32) got properly assigned to the WAN/ISP by the system. But once that change was made to fix the above bug, apparently the route-up script is NOT respecting the net_gateway parameter, but just *assuming* any such route needs to be bound to the VPN! So now it's broken your config.

If I'm right, then presumably this is a bug in the routing scripts. It's only become obvious now because of having fixed a prior and different bug.

I say presumably because things are always a bit complicated when it comes to all this stuff, esp. since the router took over all the routing decisions. I don't know precisely all the logic behind when and if certain routes are handled, ignored, whatever. And how much it differs (if at all) depending on the setting for "Redirect Internet traffic through tunnel". I know it hasn't always been 100% consistent. But knowing the history behind at least some of these changes, that's my best guess.

Now granted, if I'm right, the router should correctly handle that push'd directive. And perhaps *always* bind the server's IP to the WAN/ISP, because I've seen cases where routing policy is active, and the OpenVPN provider (wrongly imo) has created an IP network on the tunnel that places the server IP within the scope of that tunnel, resulting in recursive routing!


Notice the "fix" I suggested is essentially what you're doing; adding a static route (i.e., route directive) to bind the server IP to the WAN/ISP, but on the OpenVPN client config, since we can't control the server config.

But all that said, why are you pushing the 11.22.33.0/24 network at all? It's for reasons such as this that we discourage users from creating an IP network on the tunnel based on the *public* IP space, and instead the *private* IP space, or push'ing the public IP network of the server itself over the tunnel.

Again, *technically* this should be possible, but as you can see w/ PureVPN in the above link, they didn't even bother to push the static route! They just *assumed* the OpenVPN client would always bind the server IP to the WAN/ISP. But in the case of routing policy (or w/ Merlin, "Redirect Internet traffic through tunnel" set to No), that's a bad assumption.

At this point, rather than your current fix, what you could probably do is enable routing policy, but just create one rule to bind that same public IP (as the remote-ip) to the WAN.

Code:
<blank> <11.22.33.44> WAN

The net effect should be the same as before. WAN rules always take precedence. And nothing gets routed over the VPN unless a specific reference is made to one of the push'd networks. Note: I'm assuming 11.22.33.0/24 doesn't end up in the main routing table, but only the VPN's routing table (ovpncx). But I don't know that for sure.

As far as using Exclusive when "Redirect Internet traffic through tunnel" is set to No, the problem here is that you've encountered a known bug (at least I consider it bug given what we *now* know about the strict-order directive w/ DNSMasq).


IOW, it was *supposed* to work as /tmp/resolv.dnsmasq is currently configured, under the assumption the servers listed would only be accessed "in order", and lower priority servers would only be accessed in the case of total failure of higher priority servers. But that's NOT how that directive works. And I've requested to the developer that we REMOVE the ISP/WAN DNS servers for this reason, so it behaves as expected. Whether that will come to fruition in the next release, only time will tell.
 
Last edited:
@eibgrad d is there a way with a stock firmware (TUF AX4200) to avoid the software add route-noexec to the openvpn configuration?
Reliably start openvpn avoiding all the shenanigans the web interface add?
Or anything that could give me a rough idea of what VPN Fusion does to "play with it"?
I'm quite surprised whatever ovpn-up and ovpnc-route-up do, they just ignore the routes pushed by the server and there is no switch, configuration or whatever... no documentation either...

I may write some static route, but that's going to be a maintenance nightmare.

thanks
 

Similar threads

Latest threads

Sign Up For SNBForums Daily Digest

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