OpenVPN LDAP Auth

This document describes the process of Authenticating Users in OpenVPN against LDAP.

How does this extension work?

The extension is a script that is called by the openVPN Server which starts a query towards LDAP asking if the given user is is the specified group and if the server-name/passwords are correct.

  • User inserts the LoginData
  • OVPNServer calls ovpnAuth.sh
  • ovpnauth.sh calls the php script
  • the php scripts queries the LDAP Server and returns the reply

Prerequisites

  • A group in AD where the OVPN Users are in
  • A User to search the Active Directory
  • Shell Access to ipFire

openvpn-server configuration

#add this line to authenticate
auth-user-pass-verify /var/ipfire/ovpnldapauth.sh via-env

openvpn-client configuration

# add this line
auth-user-pass

OVPN Authentication

php /root/ovpnldapauth.php "$username" "$password"
exit $?

PHP-Authentication File

filename = ovpnldapauth.php

#!/usr/bin/php5
#<?php
/*
 * ovpnldapauth.php
 * (C) 2014 Robert Langenkamp
 *
 * created: 31.07.2014
 * last Change: 31.08.2014
 *
 */
$errLogDest = "/tmp/ovpnauth.log";

//LDAP Search user
$ldapuser = "tux\\username";
$ldappass = "password";

//Server /domain to query
$ldaphost = "ldap://tux.ipfire.local";

//Search dn and LDAP Path of allowed usergroup
$ldapbase_dn = "OU=Users-Administration,DC=contoso,DC=ipfire,DC=local";
$ldapallowgroup = "CN=AD_groupname,OU=groups,DC=contoso,DC=ipfire,DC=local";
//this is a classic LDAP Filter - figure it out via LDAP browser
$ldapfilter = "(&(objectClass=person)(!(description=ServiceAccount))(!(UserAccountControl:1.2.840.113556.1.4.803:=2)))";

  $user = "contoso\\".$argv['1'];
  $compareuser = $argv['1'];
  $pass = $argv['2'];
$info = array();
$datum = date('Y.m.d-H:i:s'). ' - ';

error_log( "(".$user.") => ", 3, $errLogDest);
if($connect=@ldap_connect($ldaphost)) {
    // Diese Parameter sind nötig für Zugriff auf ein Active Directory:
    ldap_set_option($connect, LDAP_OPT_PROTOCOL_VERSION, 3);
    ldap_set_option($connect, LDAP_OPT_REFERRALS, 0);
    if ($bind=@ldap_bind($connect, $user, $pass)) {
if ($ldapsearch=@ldap_search($connect,$ldapbase_dn,$ldapfilter)){
#   error_log($query."\n", 3, $errLogDest);
    $res = ldap_count_entries($connect,$ldapsearch);
    // query failed
    if(!$res) {
        error_log($datum."LDAP-query failed::Reject\n", 3, $errLogDest);
        echo "Reject-LDAP\n";
        return 1;
        }
    else {
        $info = ldap_get_entries($connect, $ldapsearch);
        for ($i=0;$i<$res;$i++){
                    switch ($info[$i]['samaccountname'][0]){
            case $compareuser:
                        $gruppen= $info[$i]['memberof'];
                        for ($j=0;$j<$gruppen['count'];$j++){
                            if ($ldapallowgroup == $gruppen[$j]){
                        //All checks are ok :)
                        error_log($datum."username: ".$compareuser."::Accept\n", 3, $errLogDest);
                        echo "Accept\n";
                        unset($gruppen);
                        return 0;
                    }
                }
                error_log($datum."User: ". $compareuser. " not in Group => Reject\n", 3, $errLogDest);
                echo "Reject\n";
                return 1;
                break;
                default: //do nothing
            }
        }
        // All checks are nok :(
        error_log($datum."User: ". $compareuser. " not found => Reject\n", 3, $errLogDest);
        echo "Reject\n";
        return 1;
    }
}
    } else{
error_log($datum."LDAP-Bind failed::Reject\n", 3, $errLogDest);
exit(1);
#return 1;
}
} else {
 error_log($datum."LDAP-connect failed::Reject\n", 3, $errLogDest);
 return 1;
}
?>


Edit Page ‐ Yes, you can edit!

Older Revisions • January 19 at 3:40 am • Jon