Skip to main content

Tutorial: How to Set Up Client-side Scripting in Access Server

Abstract

How to write Python scripts for client-side scripting for OpenVPN Connect with Access Server.

Overview

Access Server supports client-side scripting, which uses executable scripts with OpenVPN Connect.

For more specifics about client-side scripting, refer to this topic: Access Server Supports Client-side Scripting

This tutorial covers two ways you can set up client-side scripting:

  1. By user group via the Admin Web UI.

  2. At global, user group, or user levels via the command-line interface (CLI).

Follow the steps below to use the Admin Web UI or the CLI.

Important

The end-user must approve scripts pushed by the VPN server to the VPN client. The first time the script runs, the end-user must allow it. The end-user can click the checkbox present to remember the answer given, so they don’t need to grant the script permission to run each time.

  • An installed Access Server.

  • A use case for client-side scripting. (Examples here)

  • Admin Web UI access or console access with root privileges.

  • Python script capabilities.

Scripting languages

OpenVPN Connect supports script execution using locally-installed script interpreters such as cmd.exe or PowerShell on Windows.

OpenVPN Connect version 3.x can support Python scripts on Windows and macOS platforms if you install a Python interpreter separately.

  • To use Powershell, add these lines at the start of a script:

    #!"C:\windows\System32\WindowsPowerShell\v1.0\powershell.exe" -ExecutionPolicy ByPass -File
    #EXT ps1
  • To 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

Access Server supports the following features for client-side scripting for groups:

  1. Scripts defined for Windows and macOS.

  2. Scripts requiring user or admin-level privileges.

  3. Scripts defined with environmental variables.

To turn on client-side scripting:

  1. Sign in to the Admin Web UI.

  2. Click User Management > Group Permissions.

  3. Click the edit icon for More Settings for the preferred group.

  4. Click Yes for Use Client Scripting?

    • Additional information displays for environment variables, windows script, and mac script.

  5. Click on each available link to set variables, values, and scripts.

  6. Enter the script into the text box that opens upon click.

    Tip

    Various options display to set scripts for Windows, Mac, and Linux. For each, you can set scripts for on-connect and on-disconnect. On-connect client-side scripts run when the client establishes a VPN connection. On-disconnect client-side scripts run when the user gives the command to disconnect. OpenVPN Connect will not wait for the client-side scripting to execute before disconnecting the VPN tunnel.

  7. Note

    Ensure you assign the users to your group that you want to execute the client-side script. You can do this from User Management > User Permissions.

Define environment variables

When you click the Windows or Mac environment variables, fields open to define a variable and a value. Here are three variables you could define:

  1. PREPATH: If defined, will be prepended to the client's PATH before the script is executed.

  2. N_RECONNECTS: The number of reconnects that have occured thus far in the connection session.

  3. GRACEFUL_DISCONNECT: Set to '1' if the disconnect was requested by the user, as opposed to '0' when the disconnect was unexpected.

N_RECONNECTS and GRACEFUL_DISCONNECT are two special environment variables set by the OpenVPN Connect backend before scripts execute.

In the Admin Web UI, you're limited to specifying a client-side script on a group and then assigning users to those groups. There is no more granularity than that for client-side scripting in the Admin Web UI. However, on the command line, you can set a script on a usergroup, or the __DEFAULT__ special keyword from which the default properties for users and groups are inherited.

  1. Connect to the console with root privilege.

  2. Switch to the scripts directory:

    cd /usr/local/openvpn_as/scripts/
  3. Use the following commands for specifying client-side script options:

    • Load an on-connect client-side script for Windows:

      ./sacli --user <USER_OR_GROUP> --key "prop_cli.script.win.user.connect" --value_file "./windows-on-connect.txt" UserPropPut
    • Load an on-connect client-side script for macOS:

      ./sacli --user <USER_OR_GROUP> --key "prop_cli.script.mac.user.connect" --value_file "./macintosh-on-connect.txt" UserPropPut
    • Load an on-connect client-side script for Linux:

      ./sacli --user <USER_OR_GROUP> --key "prop_cli.script.linux.user.connect" --value_file "./linux-on-connect.txt" UserPropPut
    • Load an on-connect client-side script for all three platforms:

      ./sacli --user <USER_OR_GROUP> --key "prop_cli.script.all.user.connect" --value_file "./all-on-connect.txt" UserPropPut
    • Remove an on-connect client-side script of the four types shown above—note that this does not stop inheriting scripts from a higher level:

      ./sacli --user <USER_OR_GROUP> --key "prop_cli.script.win.user.connect" UserPropDel
      ./sacli --user <USER_OR_GROUP> --key "prop_cli.script.mac.user.connect" UserPropDel
      ./sacli --user <USER_OR_GROUP> --key "prop_cli.script.linux.user.connect" UserPropDel
      ./sacli --user <USER_OR_GROUP> --key "prop_cli.script.all.user.connect" UserPropDel
    • Load an on-disconnect client-side script for Windows:

      ./sacli --user <USER_OR_GROUP> --key "prop_cli.script.win.user.disconnect" --value_file "./windows-on-disconnect.txt" UserPropPut
    • Load an on-disconnect client-side script for macOS:

      ./sacli --user <USER_OR_GROUP> --key "prop_cli.script.mac.user.disconnect" --value_file "./macintosh-on-disconnect.txt" UserPropPut
    • Load an on-disconnect client-side script for Linux:

      ./sacli --user <USER_OR_GROUP> --key "prop_cli.script.linux.user.disconnect" --value_file "./linux-on-disconnect.txt" UserPropPut
    • Load an on-disconnect client-side script for all three platforms:

      ./sacli --user <USER_OR_GROUP> --key "prop_cli.script.all.user.disconnect" --value_file "./all-on-disconnect.txt" UserPropPut
    • Remove an on-disconnect client-side script of the four types shown above—note that this does not stop inheriting scripts from a higher level:

      ./sacli --user <USER_OR_GROUP> --key "prop_cli.script.win.user.disconnect" UserPropDel
      ./sacli --user <USER_OR_GROUP> --key "prop_cli.script.mac.user.disconnect" UserPropDel
      ./sacli --user <USER_OR_GROUP> --key "prop_cli.script.linux.user.disconnect" UserPropDel
      ./sacli --user <USER_OR_GROUP> --key "prop_cli.script.all.user.disconnect" UserPropDel

You can set a client-side environment variable in the Admin Web UI on a group via the Group Permissions page. But, in the command line, you can set it per group or user individually. You can push variables to the client program available to the client-side script as specified in the section above.

  1. Connect to the console with root privilege.

  2. Switch to the scripts directory:

    cd /usr/local/openvpn_as/scripts/
  3. Set a client-side environment variable:

    ./sacli --user <USER_OR_GROUP> --key "prop_cli.script_env.win.username"1 --value "john"2 UserPropPut

    1

    In this example, we're setting the "username" variable.

    2

    We set the "username" to "john" on the client.

    Tip

    As with client-side scripting, you can adjust the "win" to "mac", "linux", or "all", to specify if this should apply to Windows, macOS, Linux, or all three of them. In the above example, the key name contains the variable's name. So if you want to specify a variable name "myvariable" then change "username" to "myvariable" in the above example.

  4. Remove the variable setting shown above:

    ./sacli --user <USER_OR_GROUP> --key "prop_cli.script_env.win.username" UserPropDel

To open a web page with client-side scripting, you specify the command for the OS and the URL you want to open. Windows uses the command, ‘start’ to open the local web browser. Mac uses the command, ‘open’.

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

    • macOS: open https://www.openvpn.net/

    • Windows: start https://www.openvpn.net/

    • Using Python:

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

To open files from a network share, you use the same ‘start’ command in Windows, and specify the network location. In the examples we're assuming that guest access is allowed to a 'setup' file share on a server at 192.0.2.252, and that it's a standard samba file share.

Note

In our documentation, we use example IPv4 addresses and subnets reserved for documentation, such as 192.0.2.0/24, 198.51.100.0/24, and 203.0.113.0/24.

Ensure you replace them with valid IPv4 addresses and subnets for your network(s).

  • To open installer.exe in an on-connect script for Windows:

    start \\192.168.70.251\setup\installer.exe

To open installer.exe in an on-connect script for macOS:

  1. Run the following to mount the network share to a local folder, open the file in hdiutil (a tool used to open .dmg files, what most installers come wrapped in), then run an installer:

    mkdir ~/setup
    mount -t smbfs //GUEST@192.168.47.252/setup ~/setup
    hdiutil attach ~/level0/installer.dmg
    open "/Volumes/dmg label name here/"
  2. You can clean up later with:

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

Launch a URL

#!/usr/bin/env python
# On VPN connection initiation, launch a URL in the default browser.
# Works on all client platforms (Windows, Mac, Linux).
# Environmental Variables:
# LAUNCH_URL -- URL to launch
import os, webbrowser
if os.environ['N_RECONNECTS'] == '0':
webbrowser.open_new(os.environ['LAUNCH_URL'])

Download and install an application on Windows

#!/usr/bin/env python
# Download and install an MSI-based application on Windows. Leave a marker
# file behind, so that we only install the application once per local user.
# Environmental Variables:
# MSI_URL -- URL of MSI file
# MSI_HASH -- sha1 hash of MSI file, for security verification
# MSI_OPT (optional) -- extra MSI arguments, such as /q for quiet install
import os, urllib, scripthelper as sh
url = os.environ['MSI_URL']
local = os.path.basename(url)
hash = os.environ['MSI_HASH']
if not os.path.exists(hash):
urllib.urlretrieve(url, local)
if sh.digest_file(local, 'sha1') != hash:
raise ValueError("downloaded file has incorrect hash")
os.system("msiexec /i %s %s /l* msi.log" % (local, os.environ.get('MSI_OPT', '')))
file(hash, 'w').write('')

Script shebang usage for Windows (on unix, shebangs are processed by the OS)

The "shebang" is a unix construct for designating the interpreter that should process a script, by including a specially coded line beginning with "#!" as the first line of the script. When OpenVPN Connect runs on unix, the OS handles the shebang usage. However since Windows doesn't natively recognize shebang usage, OpenVPN Connect interprets the shebang line and uses it to determine how to execute the script, using the following rules:

  • [script content] — defaults to cmd.exe processing

  • #!foo.exe

    [script content...—- find foo.exe in path]

  • #!foo.exe -a somearg

    [script content... — pass options (the last option is the implicit script filename)]

  • #!"c:\Program Files\Foo Corp\foo.exe" -a somearg

    [script content... — quote the program exe]

  • #!foo.exe

    #EXT foo

    [script content... — script will be written to a .foo file before execution]

  • #PYTHON

    [python code — execute python script using OpenVPN Client built-in python interpreter]

  • #!/usr/bin/env python

    [python code — execute python script using OpenVPN Client built-in python interpreter on Windows, and using default python install on unix.]