Other than certificates and private keys, OpenVPN also offers the option to use a username and password mechanism for verifying client access. In this recipe, we will demonstrate how to set up an auth-user-pass-verify
script, which is executed on the server side when a client connects. This script can be used to look up a user in a database or file and can also be used to verify that the right password was specified.
Install OpenVPN 2.3 or higher on two computers. Make sure that the computers are connected over a network. Set up the client and server certificates using the first recipe from Chapter 2, Client-server IP-only Networks. For this recipe, the server computer was running CentOS 6 Linux and OpenVPN 2.3.10, and the client was running Fedora 22 and OpenVPN 2.3.10. For the server, keep the server configuration file, basic-udp-server.conf
, from the Server-side routing recipe, from Chapter 2, Client-server IP-only Networks.
basic-udp-server.conf
:script-security 2 auth-user-pass-verify /etc/openvpn/cookbook/example5-5-aupv.sh via-file
Note that the last line is a single line. Save it as example5-5-server.conf
.
auth-user-pass-verify
script:#!/bin/bash # the username+password is stored in a temporary file # pointed to by $1 username=`head -1 $1` password=`tail -1 $1` if grep "$username:$password" $0.passwd > /dev/null 2>&1 then exit 0 else if grep "$username" $0.passwd > /dev/null 2>&1 then echo "auth-user-pass-verify: Wrong password entered for user '$username'" else echo "auth-user-pass-verify: Unknown user '$username'" fi exit 1 fi
example5-5-aupv.sh
.[server]$ cd /etc/openvpn/cookbook [server]$ echo "cookbook:koobcook" > example5-5- aupv.sh.passwd
auth-user-pass-verify
script is executable, then start the server:[root@server]#$ chmod 755 example5-5-aupv.sh [root@server]# openvpn --config example5-5-server.conf
client proto udp remote openvpnserver.example.com port 1194 dev tun nobind ca /etc/openvpn/cookbook/ca.crt cert /etc/openvpn/cookbook/client1.crt key /etc/openvpn/cookbook/client1.key tls-auth /etc/openvpn/cookbook/ta.key 1 remote-cert-tls server auth-user-pass
example5-5-client.conf
.[root@client]# openvpn --config example5-5-client.conf
Enter Auth Username: cookbook Enter Auth Password: koobcook
Enter Auth Username: janjust Enter Auth Password: whatever
auth-user-pass-verify: Unknown user 'janjust' ... openvpnclient:50834 TLS Auth Error: Auth Username/Password verification failed for peer
And the client is now refused access.
The OpenVPN client first prompts the user for the Auth username and password. Note that the password is sent to the server over a secure channel, but the password itself is not hashed or encrypted. The server-side auth-user-pass-verify
script is passed the username and password in a file on two lines. The script then looks up the username in its password file and verifies whether the right password was specified. If so, then the script exits with exit code 0, indicating success. Otherwise, the exit code of 1 is returned, causing the server to abort the client connection.
In the following section, we'll see some details about how a password can be specified and can be passed from the server to the auth-user-pass-verify
script.
OpenVPN has the option to specify the username and password in a file on the client. For this, OpenVPN needs to be compiled with a special flag, which is enabled by default starting with OpenVPN 2.3.
Note that it is unsafe to allow the password to be stored on the client (in plaintext format!).
In this recipe, we used the following:
auth-user-pass-verify example5-5-aupv.sh via-file
This configured the OpenVPN server to pass the client-supplied username and password via a temporary file. This temporary file is accessible only to the server process, and hence, this is a safe mechanism to pass the encrypted password to the auth-user-pass-verify
script.
It is also possible to pass the username and password to the auth-user-pass-verify
script via environment variables:
auth-user-pass-verify example5-5-aupv.sh via-env
The advantage of this is that no extra files need to be created. The downside is that passing a password via plaintext and via the environment is slightly less secure: it is easier (but not easy!) to snoop the environment of another process than it is to read a secure file owned by another user.
3.135.192.141