FEATURE REQUEST: UI option to use "external" openvpn binary with LibreSSL

37 views
Skip to first unread message

ga...@scurr.me

unread,
Jul 25, 2016, 12:10:46 PM7/25/16
to tunnelbli...@googlegroups.com
Hi,
I've built OpenVPN against LibreSSL using Macports.  Anytime I try to modify anything under ./Tunnelblick.app/Contents/Resources/openvpn/... to try to symlink back to my version of OpenVPN the code signing verification rightly throws a fit.

Would you consider adding an option to the "OpenVPN version" list box for "other..." which pops up a file chooser?  Or is there a way to do this in a config file?

I also found this text in the output of "openvpnstart"
"openvpnVersion is a string with the name of the subfolder of /Library/Application Support/Tunnelblick/bin/openvpn that contains the openvpn and openvpn-down-root.so binaries to be used for the connection. The string may contain only lower-case letters, hyphen, underscore, period, and the digits 0-9.  If not present, the lowest (in lexicographical order) subfolder of .../bin/openvpn will be used."

But again there doesn't appear to be any way to push that string down to exec().

Many thanks.

Tunnelblick developer

unread,
Jul 25, 2016, 1:33:01 PM7/25/16
to tunnelblick-discuss
The output from openvpnstart is just wrong. The copies of OpenVPN that Tunnelblick uses are in /Applications/Tunnelblick.app/Contents/Resources/openvpn, not /Library/Application Support/Tunnelblick/bin/openvpn. I have just committed a fix to the source code to reflect this.

You should be able to replace an existing copy of OpenVPN inside of Tunnelblick.app with your own version. It will make the signature invalid and that has some effects, but you might be able to live with them, depending on how you use Tunnelblick. If you use the down-root plugin, it probably should be replaced, too. Replacing the binary with a symlink may not work, though, because that may be seen as a "symlink attack" and rejected.

openvpnstart runs as root to perform its functions (not directly; it uses the tunnelblickd daemon to do that in effect). It is critical that a user not be allowed to invoke arbitrary programs when Tunnelblick is invoking OpenVPN. So it isn't as simple as adding an option to have openvpnstart accept an arbitrary path because that would allow a non-privileged user to execute arbitrary code as root. We could put a symlink in /Library/Application Support/Tunnelblick that would point to the version of OpenVPN to use, and invoke openvpnstart with a flag or other indication to use that symlink. But then what if you want several different versions of OpenVPN? It starts to get messy.

I would much rather have Tunnelblick itself include versions of OpenVPN that use the LibreSSL libraries, perhaps replacing the existing OpenSSL versions or perhaps adding the LibreSSL versions in addition to the existing OpenSSL versions.

I would welcome a GitHub PR to do build OpenVPN with LibreSSL, as long as it
  • Adds an option or options (in Tunnelblick's "third_party/Makefile-common) that is/are easily controlled, so that we could build versions of OpenVPN with OpenSSL, or LibreSSL, or both; and
  • The building is done in the same manner as the OpenSSL is build now (Tunnelblick source includes a .tar.gz of OpenSSL, and optionally patches it before building it).
A naming convention would need to be established to differentiate OpenVPN with LibreSSL from OpenVPN with OpenSSL, and the GUI would have to be extended so that is shown in a user-friendly manner, but that's easy. It should work to suffix LibreSSL versions with "-L" and thus have "openvpn-2.3.4-L" for OpenVPN 2.3.4 built with the LibreSSL library. (At some point that could then be extended to have an mbedSSL version using a "-M" suffix.)

That would be a great project for someone to do; it doesn't require any familiarity with Tunnelblick itself, just the third-party build process. (I'd be happy to do the GUI part; in fact I might add that the next time I am working on that part of the Tunnelblick source, in the hopes that the rest would be done someday.)

iamGavinJ

unread,
Jul 25, 2016, 3:01:06 PM7/25/16
to tunnelblick-discuss
Many thanks for your detailed and thoughtful response.  I've made some comments inline.


On Monday, 25 July 2016 18:33:01 UTC+1, Tunnelblick developer wrote:
The output from openvpnstart is just wrong. The copies of OpenVPN that Tunnelblick uses are in /Applications/Tunnelblick.app/Contents/Resources/openvpn, not /Library/Application Support/Tunnelblick/bin/openvpn. I have just committed a fix to the source code to reflect this.
Thanks for the commit. 

You should be able to replace an existing copy of OpenVPN inside of Tunnelblick.app with your own version. It will make the signature invalid and that has some effects, but you might be able to live with them, depending on how you use Tunnelblick. If you use the down-root plugin, it probably should be replaced, too. Replacing the binary with a symlink may not work, though, because that may be seen as a "symlink attack" and rejected.
I'll give this a try.  I had only tried symlinking so far. 

openvpnstart runs as root to perform its functions (not directly; it uses the tunnelblickd daemon to do that in effect). It is critical that a user not be allowed to invoke arbitrary programs when Tunnelblick is invoking OpenVPN. So it isn't as simple as adding an option to have openvpnstart accept an arbitrary path because that would allow a non-privileged user to execute arbitrary code as root.
I figured there might be an issue here with privilege escalation.  Thanks for the confirmation.
 
We could put a symlink in /Library/Application Support/Tunnelblick that would point to the version of OpenVPN to use, and invoke openvpnstart with a flag or other indication to use that symlink. But then what if you want several different versions of OpenVPN? It starts to get messy.
Agreed that gets messy.  How about enumerating all files and symlinks in /Library/Application Support/Tunnelblick/openvpn with execute bits set and present them in the UI list?  That entire directory structure is owned by 'root:wheel' on install so there would be no worry of unprivileged users redirecting symlinks, adding scripts or otherwise executable code. 

I would much rather have Tunnelblick itself include versions of OpenVPN that use the LibreSSL libraries, perhaps replacing the existing OpenSSL versions or perhaps adding the LibreSSL versions in addition to the existing OpenSSL versions.
Agreed... my feature request is really just an option to expand functionality ahead of mainstream adoption...  but it is a handy option :) Pushing the ovpn builds back into your bundle and code signing is more appropriate.

I would welcome a GitHub PR to do build OpenVPN with LibreSSL, as long as it
  • Adds an option or options (in Tunnelblick's "third_party/Makefile-common) that is/are easily controlled, so that we could build versions of OpenVPN with OpenSSL, or LibreSSL, or both; and
  • The building is done in the same manner as the OpenSSL is build now (Tunnelblick source includes a .tar.gz of OpenSSL, and optionally patches it before building it).
Sure I have some time, I could look into this.  I'm not a dev though, just an aspiring one, so please be patient with me and feel free to enlighten me on the right and wrong way.
  
A naming convention would need to be established to differentiate OpenVPN with LibreSSL from OpenVPN with OpenSSL, and the GUI would have to be extended so that is shown in a user-friendly manner, but that's easy. It should work to suffix LibreSSL versions with "-L" and thus have "openvpn-2.3.4-L" for OpenVPN 2.3.4 built with the LibreSSL library. (At some point that could then be extended to have an mbedSSL version using a "-M" suffix.)
and -B for BoringSSL. 

That would be a great project for someone to do; it doesn't require any familiarity with Tunnelblick itself, just the third-party build process. (I'd be happy to do the GUI part; in fact I might add that the next time I am working on that part of the Tunnelblick source, in the hopes that the rest would be done someday.)
Will look into it. 

Tunnelblick developer

unread,
Jul 25, 2016, 4:11:43 PM7/25/16
to tunnelblick-discuss


On Monday, July 25, 2016 at 3:01:06 PM UTC-4, iamGavinJ wrote:
We could put a symlink in /Library/Application Support/Tunnelblick that would point to the version of OpenVPN to use, and invoke openvpnstart with a flag or other indication to use that symlink. But then what if you want several different versions of OpenVPN? It starts to get messy.
Agreed that gets messy.  How about enumerating all files and symlinks in /Library/Application Support/Tunnelblick/openvpn with execute bits set and present them in the UI list?  That entire directory structure is owned by 'root:wheel' on install so there would be no worry of unprivileged users redirecting symlinks, adding scripts or otherwise executable code.

A problem (admittedly minor) with that is that it is one more folder of stuff to keep track of and verify/fix ownership and permissions. Another is that there would have to be a convention for openvpnstart to look in that folder, too.


I would much rather have Tunnelblick itself include versions of OpenVPN that use the LibreSSL libraries, perhaps replacing the existing OpenSSL versions or perhaps adding the LibreSSL versions in addition to the existing OpenSSL versions.
Agreed... my feature request is really just an option to expand functionality ahead of mainstream adoption...  but it is a handy option :) Pushing the ovpn builds back into your bundle and code signing is more appropriate.

I just don't want to put my effort into this.
 
I would welcome a GitHub PR to do build OpenVPN with LibreSSL, as long as it
  • Adds an option or options (in Tunnelblick's "third_party/Makefile-common) that is/are easily controlled, so that we could build versions of OpenVPN with OpenSSL, or LibreSSL, or both; and
  • The building is done in the same manner as the OpenSSL is build now (Tunnelblick source includes a .tar.gz of OpenSSL, and optionally patches it before building it).
Sure I have some time, I could look into this.  I'm not a dev though, just an aspiring one, so please be patient with me and feel free to enlighten me on the right and wrong way.

It requires a familiarity with make and bash and how things are built for OS X, which I assume is learnable (I've never learned much about it myself, though). Most of what needs to be done will probably be copied from the parts of Makefile-common that build OpenSSL and then integrate the OpenSSL libraries into the OpenVPN binaries.

To get you (or anyone else) started:

When Tunnelblick is built, Xcode performs certain "build phases". One early phase named "Build Third Party Items" sets things up and invokes "Make" in the third_party folder. The Makefile that Make uses decides what version of Xcode is being used and then invokes either "Makefile-Xcode3" or "Makefile-Xcode-4andUp", depending. Those set up a couple of variables and then invoke "Makefile-common". It is "Makefile-common" that does all the work of actually building the third party binaries, leaving them in the "third_party/products" folder.

So almost all of the work will consist of
  1. Adding /third_party/sources/libressl-X.Y.Z.tar.gz containing the source code for LibreSSL; and
  2. Modifying Makefile-common to build it; and
  3. Modifying Makefile-common to build OpenVPN with it.
You probably won't need to patch LibreSSL, but if you do, there is code in Makefile-common that patches Sparkle, tuntap, and each individual OpenVPN, so you could probably copy/modify that to patch LibreSSL.


  A naming convention would need to be established to differentiate OpenVPN with LibreSSL from OpenVPN with OpenSSL, and the GUI would have to be extended so that is shown in a user-friendly manner, but that's easy. It should work to suffix LibreSSL versions with "-L" and thus have "openvpn-2.3.4-L" for OpenVPN 2.3.4 built with the LibreSSL library. (At some point that could then be extended to have an mbedSSL version using a "-M" suffix.)
and -B for BoringSSL.

Good point.

Tunnelblick developer

unread,
Jul 25, 2016, 5:00:51 PM7/25/16
to tunnelblick-discuss
One snag with what I have proposed is that as it is coded now, the name of the folder without the "openvpn-" prefix must match what the enclosed OpenVPN binary reports as its version. (That requires patching the OpenVPN source code when we make a "git-master" version of OpenVPN, and so we do that.)

I can easily modify that code to ignore a -L suffix in the folder name (or "-M" or "-B"). Then the OpenVPN object code for the linked-with-OpenSSL could be reused for the linked-with-LibreSSL version; the only difference would be what library OpenVPN was linked with.


On Monday, July 25, 2016 at 4:11:43 PM UTC-4, Tunnelblick developer wrote:
I would much rather have Tunnelblick itself include versions of OpenVPN that use the LibreSSL libraries, perhaps replacing the existing OpenSSL versions or perhaps adding the LibreSSL versions in addition to the existing OpenSSL versions.
... 
I would welcome a GitHub PR to do build OpenVPN with LibreSSL, as long as it
  • Adds an option or options (in Tunnelblick's "third_party/Makefile-common) that is/are easily controlled, so that we could build versions of OpenVPN with OpenSSL, or LibreSSL, or both; and
  • The building is done in the same manner as the OpenSSL is build now (Tunnelblick source includes a .tar.gz of OpenSSL, and optionally patches it before building it) 
  A naming convention would need to be established to differentiate OpenVPN with LibreSSL from OpenVPN with OpenSSL, and the GUI would have to be extended so that is shown in a user-friendly manner, but that's easy. It should work to suffix LibreSSL versions with "-L" and thus have "openvpn-2.3.4-L" for OpenVPN 2.3.4 built with the LibreSSL library. (At some point that could then be extended to have an mbedSSL version using a "-M" suffix.)
and -B for BoringSSL.
Reply all
Reply to author
Forward
0 new messages