Opened 7 years ago

Closed 4 years ago

Last modified 2 years ago

#284 closed Feature Wish (wontfix)

Add --up-pre with the same functionality as --down-pre

Reported by: Simon Matter Owned by: JoshC
Priority: minor Milestone:
Component: Generic / unclassified Version: OpenVPN 2.3.1 (Community Ed)
Severity: Not set (select this one, unless your'e a OpenVPN developer) Keywords:


In our situation we have the requirement to run scripts before tun/tap is opened, not after. While this could be hacked into the init script, the proper way seems to add it to openvpn as --up-pre option.
Attached patch works for us.


Attachments (4)

openvpn-2.3.1-up-pre.patch (4.7 KB) - added by Simon Matter 7 years ago.
openvpn-2.3.2-up-pre.patch (4.2 KB) - added by Simon Matter 7 years ago.
Updated patch for 2.3.2
openvpn-2.4.0-up-pre.patch (4.9 KB) - added by Simon Matter 2 years ago.
Updated patch for 2.4.x
ovpn-management-sanitized (1.2 KB) - added by lavacano201014 2 years ago.

Download all attachments as: .zip

Change History (21)

Changed 7 years ago by Simon Matter

Attachment: openvpn-2.3.1-up-pre.patch added

comment:1 Changed 7 years ago by David Sommerseth

Resolution: wontfix
Status: newclosed

Please see ticket #173. This has been proposed before and I have NACKed it due to security issues related to this approach.

I firmly believe the right place to fix this is in the init script, or have /usr/sbin/openvpn be a wrapper script for an openvpn binary renamed to openvpn.bin. Then you have full control over what's going on.

But feel free to disagree! I'm open to discuss this topic.

comment:2 Changed 7 years ago by Simon Matter

I do understand your concerns but I disagree here :)

I don't see why --up-pre makes scripting in openvpn more dangerous than all the existing scripting functionality?

The wrapper hack is not a clean solution from my point of view because is does not allow the scripts to be run from inside openvpn. That means that if openvpn reestablishes a connection it can run the down-script pre or post tun/tap close but can not run the up-script pre tun/tap open, only post.

That's really missing, isn't it?

comment:3 Changed 7 years ago by Simon Matter

Resolution: wontfix
Status: closedreopened

comment:4 Changed 7 years ago by JoshC

Owner: set to JoshC
Status: reopenedassigned

What's the use-case here that can't be solved by calling a command before invoking OpenVPN?

A couple things about this approach concerns me after reading the referenced earlier bug and the existing comments. First, running the "same" script once on first-invocation as root and again on restarts (with the --up-restart option) as a different user, and this can lead to interesting cases where "unexpected" things happen due to this kind of changing behavior.

The intent of #173 was to provide a way to "pause" before program start. Today the management interface can already be launched in a "hold" state with --management-hold command. Between the ability to do whatever is necessary before invoking OpenVPN the first time and this feature, I'm struggling to see how this allows a user to perform tasks that couldn't be otherwise performed.

Is there a valid case we're perhaps not considering?

comment:5 Changed 7 years ago by Simon Matter

My proposal was not to introduce a new script hook but just to allow you to specify if the existing up hook is executed before or after tun/tap opening.
I don't see how this approach changes any security concerns because the --up script already exists and is executed the way it is now.
The only thing I see is that --down-pre exists and --up-pre was forgotten - it's an inconsistency I found when I needed it.
The question in #173 was to introduce a new script hook but my patch simply adds the possibility to define when to execute the existing --up hook.

We have a quite complex use case where doing the same with the init script would be a dirty hack while the small openvpn patch seems like a clean and secure solution.

Changed 7 years ago by Simon Matter

Attachment: openvpn-2.3.2-up-pre.patch added

Updated patch for 2.3.2

comment:6 Changed 5 years ago by Samuli Seppänen

JoshC, dazo: so what to do with this?

comment:7 Changed 4 years ago by David Sommerseth

Resolution: wontfix
Status: assignedclosed

So 15 months have gone, and we have a 3 year old patch.

I don't see this being included additionally by distro maintainers in Fedora (which includes RHEL/CentOS/ScientificLinux) nor Debian (which includes Ubuntu indirectly). This tells me that this feature isn't very much sought for, as the sum of all those distros covers a broad range of users.

Given that --up-pre will just change the execution order I am not so rejective as to introducing a new script hook - BUT I do share JoshC's concerns regarding what happens when this is mixed with --up-restart.

As this has been lingering for so long without much more discussions, I'm closing this. If this truly is a wanted feature by more users, it would be good to see that through the mailing list so it can be more widely discussed.

comment:8 Changed 4 years ago by d3xt3r01

I'm interested in having a pre hook. As in, I want it to execute a command before beggining ...

comment:9 Changed 4 years ago by David Sommerseth

Can you please describe what you want to do and what you mean with "before beginning"? Also we need to have a far better understanding what should happen with --up-restart situations, in particular if --user/--group are set?

Also which distribution/OS do you use? For systemd based Linux distros (which is the majority of the larger ones - Fedora/RHEL/CentOS/ScientificLinux/OpenSUSE (RPM ones) and Debian/Ubuntu? (DEB ones) it is incredibly easy to add this feature in the unit file .... copy openvpn-{client,server}@.service file(s) to /etc/systemd/system ... and add ExecStartPre?=$FULL_PATH_TO_YOUR_SCRIPT

I really struggle to see the benefit of this feature. As --up-pre will just run the --up script at an earlier phase of the init. For this to seriously be considered, we do need a very good and convincing use-case which can't be resolved outside OpenVPN.

comment:10 Changed 3 years ago by TCr


I also need this feature. My case is as follows:
I have a script which modifies the dns settings to use the internal dns setup, when vpn tunnel is up. BUT when tunnel is not up I need to query the same domain external, because the tunnel-server dns name use the same domain, which is used internal.

So I have also a down script, which kicks off the internal dns resolution and restart dnsmasq.

Problem is, that some times the script dont run the down script and so I can't reconnect!

Now - when I could have a pre-up-Script I can correct dns settings.

I use LEDE (OpenWRT) which not runs systemd.

comment:11 Changed 2 years ago by lavacano201014

My OpenVPN port is behind a port knock, which is configured to automatically close behind me after approximately ten seconds. While my client is connected, the VPN connection is alive and works fine (though I did need to enable keepalives). But if my client loses connection for some reason, it cannot reconnect on its own unless I'm at the system and manually run the port knock again.

Putting the port knock command in the init script is a workaround, but not a solution, because the init script is not run again if OpenVPN loses connection (i.e. manual intervention is still required, it just changes what command I have to run). Removing the port knock is not a solution either.

So far, the only way I've been able to work around this without manual intervention is by creating a cron job that runs every fifteen minutes, pinging my gateway address and manually restarting the init script if ping fails. This is very error prone, however, and often causes restarts when they aren't really necessary.

comment:12 Changed 2 years ago by David Sommerseth

Thank you @lavacano201014, this is one of the better reasoning I've seen for such a feature. But this change would require the --up script (with --up-pre) to be run _before_ OpenVPN tries to connect. The patch proposed here does not move the --up script that early. OpenVPN first connects, then it opens the tun/tap device. And the --up script is currently run in right after the tun/tap device is opened up. And I believe this behaviour is also influenced by --persist-tun as well.

What you seem to want is a --pre-connect script hook. Which would run before OpenVPN tries to initiate a connection. But I believe this can be better handled using a script/program running in parallel pausing OpenVPN's attempt to connect. This script can then run with the needed privileges, and when the script has done it's job it will just tell OpenVPN "Now you can connect!". This is a bit more work, indeed, but it is far safer and less error prone as you don't need to account for --persist-tun, --user/--group and --chroot.

All you need in your client config is --management localhost 5194 --management-hold. Then your script needs to do is to connect ("telnet") to localhost:5194 and issue the command hold release.
Whenever OpenVPN is awaiting for the hold to be released, it will send a >HOLD:Waiting for hold release: message on the management interface.

As a side remark though ... I honestly do think that port-knocking is not needed at all with OpenVPN if you deploy --tls-crypt or --tls-auth. In fact, combine that with --proto udp and port scanners won't even see your OpenVPN port. And using UDP is what we do recommend users to use as well, as that usually gives the best performance and reliability. To have an equally good TCP experience, you cannot have packet loss and the packet latency needs to be fairly stable. I can acknowledge port-knocking can help somewhat with TCP (DoS attacks exhausting the number of available client connections) - but for the overall tunnel security, port-knocking adds few other benefits compared to --tls-crypt/--tls-auth.

Last edited 2 years ago by David Sommerseth (previous) (diff)

comment:13 Changed 2 years ago by gsimon75

+1 use case for the proposed '--pre-connect'

I'm behind some kind of transparent http proxy, legitimate http traffic gets nice high bandwidth and reliable connections, other tcp traffic is slow and udp in general is very lossy, therefore openvpn alone is also slow (if using tcp) or lossy (if using udp).

There is no non-transparent proxy, so '--http-proxy' is out of play.

What does the trick is having httptunnel (hts/htc) on both sides, on the client it's listening on a local tcp port and on the server connecting to a local tcp port, and setting up openvpn to listen on / connect to these forwarded ports.

But then it would be convenient to manage htc in sync with openvpn: just before openvpn client starts to connect it should start htc, and just after it disconnected, it should kill it.

For manual connect/disconnect I could do it from the init script, but

  1. It is needed only for the vpn I use from work, and not from home, so it would be nice if it could be configured on a per-vpn-setup basis.
  2. When the disconnection is because of a network error (or just resuming my laptop from a suspend), htc should be restarted automatically as openvpn tries to reconnect.

So, for all scenarios where openvpn is not alone in the setup, but works through an external tunnel, setting up that tunnel could use a '--pre-connect' hook.

Changed 2 years ago by Simon Matter

Attachment: openvpn-2.4.0-up-pre.patch added

Updated patch for 2.4.x

comment:14 Changed 2 years ago by Simon Matter

I've just attached an updated patch for OpenVPN 2.4.x. It's a quite simple patch and works well over here for more than five years.

I've posted it here and also asked on openvpn-devel list to no avail.

comment:15 Changed 2 years ago by David Sommerseth

Hey guys. You DO NOT WANT --pre-connect. You want to use --management and --management-hold and have your "pre-connect script" release OpenVPN once you're ready to make OpenVPN start connecting.

This is a dead-end now. Stop insisting re-inventing the wheels which already exists. It's just a different shape, but our is a round shape so far more flexible and useful than the squared --pre-connect wheel.

Quick howto - using nc:

OpenVPN process: openvpn --management /run/user/$UID/preconnect unix --management-hold --config $CONFIG_FILE

And when the pre-connect script is ready to let OpenVPN connect, it needs to do: echo "hold release" | nc -U /run/user/$UID/preconnect

And that's it.

Changed 2 years ago by lavacano201014

Attachment: ovpn-management-sanitized added

comment:16 Changed 2 years ago by lavacano201014

Attached a sanitized version of the management script I'm using for my port knock (Python 3, standard library), as another example of how --management and --management-hold can be used to implement a "pre-connect" hook on your own.

comment:17 in reply to:  16 Changed 2 years ago by David Sommerseth

Replying to lavacano201014:

Attached a sanitized version of the management script I'm using for my port knock (Python 3, standard library)

Thanks a lot! This is good and mostly sane. Just one detail though which we've highlighted better in the man-page lately.

              BEWARE of enabling the management interface over TCP.  In  these
              cases  you should ALWAYS make use of pw-file to password protect
              the management interface. 

I would rather recommend an approach using Unix sockets instead. Or at least password protect the management interface.

Note: See TracTickets for help on using tickets.