OpenVPN user authentication with Active Directory

0 Comments

This is a continuation of the previous post “OpenVPN Installation”. Here I would like to go through the configuration process of OpenVPN Server so that the credentials authorisation will be done with active directory on a separate server.

In the previous post we had gone through the configuration process of the openvpen server and creating an .ovpn file. Now let us extend it so that when connecting to a vpnserver we will be prompted to enter user name and password which will be checked against the windows active directory server.

It is essential that you have basic kowledge of active directory management.

In this tutorial we are going to:

  1. Install openvpn-auth-ldap tools
  2. Add Users to Active Directory
  3. Configure auth.ldap.conf file
  4. Adjust openvpn configuration file

Firstly, let us jump over to our OpenVPN server and install necessary packages and libraries.

§ sudo apt install openvpn-auth-ldap

After the installation has been completed we will jump into usr/share/doc/openvpn-auth-ldap/examples/ and copy an example config file auth-ldap.conf into /etc/openvpn/. This file is the main configuration for our authentication.

$ sudo cp /usr/share/doc/openvpn-auth-ldap/examples/auth-ldap.conf /etc/openvpn/

Additionally let us note the location of the authentication module /usr/lib/openvpn/openvpn-auth-ldap.so. We are going to need this path for configuration later on.

Adding Users to Active Directory

In order to authenticate users against AD we are going to need to create a user just for the vpnserver, so that auth-ldap module can read the content of the Active directory users, groups and organisational units (OU):

In this case I create a user : VPNUser who resides inside an OU called MyUsers and is a part of a Group called VPNGroup. The VPNGroup is inside an OU called MyGroups. Any other AD user will also be inside OU:MyUsers and will be a part of the group called VPNGroup (in our scenario the users inside this group will be allowed to connect to our vpnserver)

Let us summarize:

Domain: example.local
OU: MyUsers          CN: VPNUser
OU: MyGroups         CN: VPNGroup

Configuring auth.ldap.conf file

The default file which we have just copied into /etc/openvpn/ looks like this:

<LDAP>
# LDAP server URL
URL ldap://ldap1.example.org
# Bind DN (If your LDAP server doesn't support anonymous binds) 
# BindDN uid=Manager,ou=People,dc=example,dc=com 
# Bind Password 
# Password SecretPassword 
# Network timeout (in seconds) Timeout 15 # Enable Start TLS TLSEnable yes 
# Follow LDAP Referrals (anonymously) 
FollowReferrals yes 
# TLS CA Certificate File TLSCACertFile /usr/local/etc/ssl/ca.pem 
# TLS CA Certificate Directory TLSCACertDir /etc/ssl/certs 
# Client Certificate and key 
# If TLS client authentication is required TLSCertFile /usr/local/etc/ssl/client-cert.pem TLSKeyFile /usr/local/etc/ssl/client-key.pem 
# Cipher Suite # The defaults are usually fine here 
# TLSCipherSuite ALL:!ADH:@STRENGTH
</LDAP

<Authorization>
# Base DN
BaseDN "ou=People,dc=example,dc=com"
# User Search Filter 
SearchFilter "(&(uid=%u)(accountStatus=active))" 
# Require Group Membership RequireGroup false # Add non-group members to a PF table (disabled) #PFTable ips_vpn_users 
# Uncomment and set to true to support OpenVPN Challenge/Response #PasswordIsCR false <Group> 
# Default is true. Match full user DN if true, uid only if false. 
# RFC2307bis true 
# Default is true. Uncomment and set to false if you want to use a Search operation to determine group 
# membership instead of Compare. Lower performance, so Compare should generally be used, but Search is # required in certain LDAP environments. 
# UseCompareOperation true 
BaseDN "ou=Groups,dc=example,dc=com" 
SearchFilter "(|(cn=developers)(cn=artists))" 
MemberAttribute uniqueMember 
# Add group members to a PF table (disabled) 
#PFTable ips_vpn_eng </Group>

</Authorisation

According to the Active Directory users and groups we set up previously we are going to change the red marked lines of the config file. The new configuration should look as follows:

<LDPA>
# LDAP server URL
URL ldap://xxx.xxx.xx.xx:389 #Your IP here with Port number

# Bind DN (If your LDAP server doesn't support anonymous binds) 
BindDN cn=VPNUser,ou=MYUsers,dc=example,dc=local 
#Bind Password 
Password "YourPasswordforVPNUser" 
# Network timeout (in seconds) Timeout 15 
# Enable Start TLS
TLSEnable no 
# Follow LDAP Referrals (anonymously) 
FollowReferrals yes 
# TLS CA Certificate File TLSCACertFile /usr/local/etc/ssl/ca.pem # TLS CA Certificate Directory TLSCACertDir /etc/ssl/certs # Client Certificate and key 
# If TLS client authentication is required TLSCertFile /usr/local/etc/ssl/client-cert.pem TLSKeyFile /usr/local/etc/ssl/client-key.pem 
# Cipher Suite 
# The defaults are usually fine here 
# TLSCipherSuite ALL:!ADH:@STRENGTH
</LDPA>

<Authorisation>
# Base DN
BaseDN "ou=MYUsers,dc=example,dc=local"
# User Search Filter 
SearchFilter "(samaccountname=%u)" #Replace the default with this function
# Require Group Membership 
RequireGroup true 
# Add non-group members to a PF table (disabled) 
#PFTable ips_vpn_users 
# Uncomment and set to true to support OpenVPN Challenge/Response 
#PasswordIsCR false <Group>

# Default is true. Match full user DN if true, uid only if false.
# RFC2307bis true
# Default is true. Uncomment and set to false if you want to use a Search operation to determine group # membership instead of Compare. Lower performance, so Compare should generally be used, but Search is # required in certain LDAP environments. 
# UseCompareOperation true 
BaseDN "ou=MYGroups,dc=example,dc=local" 
SearchFilter "(cn=VPNGroup)" 
MemberAttribute "Member" 
# Add group members to a PF table (disabled) 
#PFTable ips_vpn_eng 
</Group>
</Authorization>

Son now we have our configuration file adjusted. There is one last step that we must undertake. We are going to tell the VPNServer that it should use the LDPA module and the LDPA configuration file.

Adjust openvpn configuration file

Navigate to our server.conf file

$ sudo nano /etc/openvpn/server.conf

we are going to add this line to the end of the file:

plugin /usr/lib/openvpn/openvpn-auth-ldap.so /etc/openvpn/auth-ldap.conf

This line tells the location of the plugin and specifies the the path to the ldap configuration file.

So now… Thta’s it. Save the config file and just in case restart the VPN server:

$ sudo systemctl restart openvpn

Now try out connecting via client. You should see this mask now:

VPN Client can be downloaded from the openvpn offical website:

https://openvpn.net/community-downloads/

OpenVpn Debugging

The overall configuration of both the server as well as the LDAP service is somewhat long. Due to many configuration steps mistakes can unfortunatelly happan. Here are a few commands that will help rule out some of the mistakes:

1. Journal

The journal can tell a lot and point you directly to where the problem is:

$ sudo journalctl -xe

2. TCPDump

Tracking traffic on particular interfaces and ports can give a good indication if connection is established. If for example you like to check open vpn communication with Active Directory server then simply use:

$ sudo tcpdump -ni eth0 tcp and port 389

‘eth0’ – is my network adapter in this case. Check yours using “ifconfig” command.

3. VPN Logs

Watch realtime logs as you execute client connections. You will get a live feed on any activity on the vpn server

$ sudo tail -f /var/log/openvpn/openvpn.log

4. Filter System Logs

You can filter system logs for any VPN activity

$ grep VPN /var/log/syslog

5. Check Server Configuration File

You can check your main config file. Should any error accure you will be informed.

$ sudo openvpn --config /etc/openvpn/server.conf

6. OpenVPN Processes

It is always good to check if your processes are running and activated

$ systemctl list-units | grep openvpn

and to see the status of any individual process

$ systemctl status openvpn@server.service

Enabling / Disabling a process:

$ systemctl disable openvpn@server.service
$ systemctl enable openvpn@server.service
Categories:

Leave a Reply

Your email address will not be published. Required fields are marked *