Opened 4 years ago

Last modified 3 years ago

#412 new Bug / Defect

persist-tun and redirect-gateway def1 don't work together when multiple remotes are defined

Reported by: sthibault Owned by:
Priority: minor Milestone: release 2.4
Component: Networking Version: OpenVPN 2.2.2 (Community Ed)
Severity: Not set (select this one, unless your'e a OpenVPN developer) Keywords:
Cc: plaisthos

Description

Hello,

We have several servers for robustness. Our clients use our server as a total VPN, with the redirect-gateway def1 option. We initially thought about using the persist-tun option, so as to improve robustness whenever a server falls down. However, it actually makes things worse, because of the following scenario:

  • client connects to serveur S1
  • client adds route to S1 via the local gateway
  • client adds 0.0.0.0/1 and 128.0.0.0/1 via the tunnel
  • S1 falls down
  • client tries to connect to serveur S2
  • it fails because trafic to S2 is routed through the tunnel due to the /1 routes.

and it only manages to get back to work after a whole restart.

So in the end, we can not use the persist-tun option. A way to make it to work would be to not only add the route to S1 via the local gateway, but also the routes to all other remotes of the configuration, so that one can switch between any of them without having to re-setup the tun device.

Change History (5)

comment:1 Changed 4 years ago by Gert Döring

Cc: plaisthos added
Milestone: release 2.4

Fixing this would be quite intrusive, so we're unlikely to do so in 2.3.x (and we're definitely not doing it for 2.2.2, which is ancient - seems I said that already today?).

For 2.4.0, we should see whether we can fix this in an elegant way. Plaisthos, any good suggestions? How does the Android client handle this?

comment:2 Changed 4 years ago by plaisthos

For the android client the opentun automatically calls the protect() call. Android does not need the special host route. For other platforms I fear we need special logic for the host route on remote change

comment:3 Changed 4 years ago by Gert Döring

So how do you reconnect on Android? Using the already-protect()ed socket won't work for TCP connects...?

comment:4 Changed 3 years ago by plaisthos

When a new socket is created it is protected(), so new tcp/dup conection means new socket => protected.

As for other platforms: Since routes are only set when the tun device is opnend only the current remote is considered. The code could be changed to add all remotes in that setup but that implies preresolving all IPS (--preresolv) and also is more a bandaid than a fix.

comment:5 Changed 3 years ago by triffid_hunter

This bug affects me. (gentoo linux, openvpn 2.3.6)

Originally I was working around this by adding a /24 route for the ip-range of my VPN servers, however I soon discovered that openvpn would remove it upon reconnect. (See #566)

It seems that the main issue is that openvpn fails to add a route for the newly chosen server IP

I haven't viewed the openvpn codebase, but I can't imagine that it would be particularly hard to fix in configurations where the openvpn client isn't dropping privileges.

What I think should happen on reconnect (using reporter's S1/S2 terms):

  • openvpn picks another ip from the DNS list (this part works fine)
  • openvpn removes the S1 route that it created upon connection (openvpn doesn't do this)
  • openvpn creates the S2 route for the new remote IP (here's the crux of the issue)
  • openvpn initiates connection

Unfortunately I don't know how to avoid redirect-gateway, as it's being pushed to my client by the server and openvpn doesn't seem to like no-redirect-gateway or variants.

Note: See TracTickets for help on using tickets.