OpenVPN has a method to authenticate to an external script or via plugins. This example shows how to use an external shell script to authenticate to LDAP. The other method of plugins is preferred due to speed & security.

Configuring auth-user-pass-verify

The OpenVPN server needs to be pointed to the script and have some security options set.

auth-user-pass-verify auth-user.sh via-env
script-security 3 execve

The auth-user-pass-verify is executed from the directory that OpenVPN is configured to run in via the cd configuration parameter.

The script-security level must be set to 3 execve so the password will be handed off to the script.

--script-security level [method]

This directive offers policy-level control over OpenVPN's usage of external programs and scripts. Lower level values are more restrictive, higher values are more permissive. Settings for level:

0 -- Strictly no calling of external programs.
1 -- (Default) Only call built-in executables such as ifconfig, ip, route, or netsh.
2 -- Allow calling of built-in executables and user-defined scripts.
3 -- Allow passwords to be passed to scripts via environmental variables (potentially unsafe).

The method parameter indicates how OpenVPN should call external commands and scripts. Settings for method:

execve -- (default) Use execve() function on Unix family OSes and CreateProcess() on Windows.
system -- Use system() function (deprecated and less safe since the external program command line is subject to shell expansion).

The --script-security option was introduced in OpenVPN 2.1_rc9. For configuration file compatibility with previous OpenVPN versions, use: --script-security 3 system

Configuring OpenVPN Client

The client configuration must be told to collect the username and password simply add auth-user-pass to the configuration.

auth-user-pass

Example Auth to LDAP via ldapsearch

#!/bin/bash
# :mode=shellscript
#
# Gets environment from OpenVPN and Auth to LDAP Server

# set > /tmp/auth-user.env

ldap_base="ou=People,dc=domain,dc=com"
ldap_host="ldap.domain.com"

#
# Bind As and Search For Self
ldapsearch \
    -h "${ldap_host} \
    -b "${ldap_base}" \
    -D "uid=${username}" \
    -w "${password}" \
    "uid=${username}" >/dev/null 2>&1

#
# Return Success (0) or Not Success
R="$?"
# echo "$R" > /tmp/auth-user.res
exit $R

See Also

ChangeLog