Explanation of client-side scripting with simple examples

What client side scripting can do

OpenVPN Access Server supports pushing scripts to the VPN clients. By default OpenVPN Connect Client for Windows and Macintosh will ask the user once to confirm if scripts should be executed or not. If the user approves then the script will be run from that point on whenever the user connects or disconnects. For security reasons the commands that client side scripts can do are relatively limited to the user context, although it is possible to step outside of that and apply system-wide configuration changes if you call a program that asks the user for privilege escalation. Client side scripting is meant for simple tasks. If you want to do complicated tasks, have the client side script call a program that does the work you need done. Client side scripting by itself is limited in functionality mostly because of the limited privileges context (user context) the scripts run in. By calling an external program that can do a privilege escalation request to the user, full system level access can be gained instead and that program can then do any task that any installation file with administrative privileges can do.

With client side scripts alone you can for example open a web page automatically after the user has connected, or open a network drive in Explorer or Finder automatically. You can put up a message on the computer screen indicating that you have connected (more clearly than the popup window that Connect Client shows or with additional information. You can run a separate program to for example remove any temporary files or close any programs that were left open that only work over the VPN connection. The language used can be shell language like batch scripting or sh/bash scripting or even Python. You can configure environment variables that are set on the client operating system.

Scripting works on Windows, Macintosh, and Linux, if the client program permits execution of scripts and if it runs them. For example on Windows and Macintosh if you use OpenVPN Connect Client then by default it will ask the user if it's okay to run the script, and then does it. On Linux by default it just flat out ignores it unless you implement the parameter script-security 2 in the client connection profile.

Currently server-side scripting is not supported, only client-side scripting. However server-side scripting is possible with some limitations and caveats by using a post-auth script. A post-auth script runs right after a user has successfully authenticated, but just before the user is allowed to establish a connection fully. This offer the ability to add additional criteria before allowing the user to connect, and it also allows to run additional commands like sending out an email or such notifying the administrator that someone has connected. However, auto-login type profiles bypass post-auth entirely. For more details see the post-auth page.

How to set up a script on Access Server

If you do this from the Admin UI, you need a group first. This must be created in the Admin UI under Group Permissions. Once the group exists you can enable client-side scripting on it. This limitation of requiring a group doesn't exist if you use the command line tools to set a client-side script for a user or group. In the admin UI however you have to use a group. Then various options become available to set scripts for Linux, Windows, or Macintosh. And for each it's possible to set an on-connect script and an on-disconnect script. The purpose of course is obvious; the on-connect client side script runs on the client when the user has just established a working VPN connection, and the on-disconnect runs just after the user gives the command to disconnect. The program will however not wait for execution of the client-side scripting before disconnecting the VPN tunnel. With a user assigned to this group, the user will now be given the client-side script to execute the next time they connect.

It is however also possible to set a script per user or per group or for the entire server using the special __DEFAULT__ keyword. But then this must be done through the command line.

Which languages are supported

That depends on what languages are installed on the client. On Windows for example it will use the command line interpreter cmd.exe by default but if you specifically indicate you want to use Powershell, it can use that instead. We use the shebang method of specifying which language you want to use, and if the interpreter is present and installed, you can use it to run client side scripting.

For example, these lines at the start of the script will make the script suitable for working with Powershell:

#!"C:\windows\System32\WindowsPowerShell\v1.0\powershell.exe" -ExecutionPolicy ByPass -File
#EXT ps1

And this uses the integrated Python interpreter that comes with Connect Client for Windows or Macintosh, or the Linux Python interpreter:

#!/usr/bin/env python

This uses only the integrated Python interpreter that comes with Connect Client for Windows or Macintosh:

#PYTHON

Or pass the script as a file to an interpreter (last argument is the implicit script filename):

#!"C:\Program Files\Foo Corp\interpreter.exe" -a somearg

On Linux, bash scripting is supported by default, and if the OS has Python or another interpreter language installed, you can use that too by specifying which interpreter to use with the shebang method that is commonly used on the Linux OS to specify which language the script should be run in, and as shown in the examples above.

OpenVPN Connect Client for Windows and Macintosh also comes bundled with a slimmed down version of Python. It's slimmed down because it doesn't have all of the libraries that a standard Python installation comes with, in order to cut down on the size of the installation program. You can for example use Python to open a web browser and open a specific page, although that task can also easily be achieved without using Python.

Open web page on Windows or Mac

For Windows the command start is all you need to have the local web browser start up and open a specified file or URL. On Mac the equivalent command is open, which is also fairly easy to understand and use.

Open https://www.openvpn.net/ in an on-connect script for Windows:

start https://www.openvpn.net/

Open https://www.openvpn.net/ in an on-connect script for Macintosh:

open https://www.openvpn.net/

It's also possible to do this with Python:

#!/usr/bin/env python
import os, webbrowser
if os.environ['N_RECONNECTS'] == '0':
    webbrowser.open_new("http://openvpn.net/")

Open an installation file from a network share

For Windows the command start is all you need to have the local web browser start up and open a specified file or URL. On Mac the equivalent command is open, which is also fairly easy to understand and use. However, while this applies to URLs, unfortunately it does not apply to network files on Macintosh. So we have an alternative for that. In the examples we're assuming that guest access is allowed to a 'setup' file share on a server at 192.168.47.252, and that it's a standard samba file share.

Open installer.exe in an on-connect script for Windows:

start \\192.168.70.251\setup\installer.exe

Macintosh unfortunately doesn't make life this easy. However you can mount the network share to a local folder, then open the file in hdiutil (a tool used to open .dmg files which is what most installers come wrapped in on Macintosh) after which you can then run an installer.

Mount network share in Macintosh and access a .dmg installer file on Macintosh:

mkdir ~/setup
mount -t smbfs //GUEST@192.168.47.252/setup ~/setup
hdiutil attach ~/level0/installer.dmg
open "/Volumes/dmg label name here/"

You can cleanup later with:

hdiutil detach "/Volumes/dmg label name here/"
umount ~/setup
rmdir ~/setup

Set environment variables on the client system

There's a special option in the group permissions section where client-side scripts can be specified, to specify environment variables as well. These are set before the client-side script executes. These environmental variables may be defined on the server, and will be pushed to the client, and made available to the script. Using this in the command line to load scripts you could for example set a different environment variable for each user, which can then be used in the script to do something specifically for that user, like open their home folder on a server. This option can set environment variables per user or group specifically via the command line tools.

There's a special environment variable that may be set on the Access Server:

  • PREPATH - if defined, will be prepended to client's PATH before the script is executed.

And there's 2 special environment variables that are set by the OpenVPN Connect Client backend before scripts are executed:

  • N_RECONNECTS - the number of reconnects that have occurred thus far in this connection session.
  • GRACEFUL_DISCONNECT - set to '1' if the disconnect was requested by the user, as opposed to '0' when the disconnect was unexpected.