Auth ldap configuration error url key is unknown

Hi, I am trying to build openvpn with LDAP and google authenticator, both of which will need a correct authentication to let people in.

Altheus

OpenVpn Newbie
Posts: 6
Joined: Thu Jul 15, 2021 12:22 pm

LDAP server letting anything in

Hi, I am trying to build openvpn with LDAP and google authenticator, both of which will need a correct authentication to let people in.

I’m trying to work through this, step by step and I’m getting problems with the LDAP configuration.

Somehow, this server will let me on irrespective of what I type as the password in the client.

Code: Select all

<LDAP>
        URL             "ldaps://ldaps.########.###"
        BindDN          "openvpnldap@#######.###"
         Password       "##############"
        Timeout         60
        TLSEnable       no
        FollowReferrals yes
        TLSCACertDir    /etc/ssl/certs
</LDAP>
<Authorization>
        PasswordIsCR true
        BaseDN          "OU=AADDC Users,DC=olmgroup,DC=com"
        SearchFilter    "(mail=%u)"
        RequireGroup    false
</Authorization>

My server.conf file looks like this:

Code: Select all

port 1194
proto udp
dev tun
ca /etc/openvpn/keys/ca.crt
cert /etc/openvpn/keys/server.crt
key /etc/openvpn/keys/server.key
dh /etc/openvpn/keys/dh.pem
cipher AES-256-CBC
auth SHA512
server 10.8.0.0 255.255.255.0
push "route 10.160.0.0 255.255.0.0"
#push "route 10.160.1.0 255.255.255.0"
ifconfig-pool-persist ipp.txt
keepalive 10 120
comp-lzo
persist-key
persist-tun
status openvpn-status.log
status-version 2
verb 4
reneg-sec 36000
tls-server
tmp-dir "/etc/openvpn/tmp/"
plugin /usr/lib/openvpn/openvpn-auth-ldap.so ldap.config
plugin /usr/lib/openvpn/openvpn-otp.so "debug=1 password_is_cr=1 otp_secrets=/etc/openvpn/auth/otp-secrets"
log-append /var/log/openvpn/openvpn.log
#duplicate-cn
ifconfig-pool-persist "/etc/openvpn/ipp.txt"
management localhost 5555
username-as-common-name

I’m sure I’m missing something silly, but none of the documentation I can find will tell me what I should be doing in this situation.


Altheus

OpenVpn Newbie
Posts: 6
Joined: Thu Jul 15, 2021 12:22 pm

Re: LDAP server letting anything in

Post

by Altheus » Tue Jul 20, 2021 8:10 am

I’ve found something important while going through the logs:

Auth-LDAP Configuration Error: PasswordIsCR key is unknown

So, it looks like that line from ldap.conf is where the problem is. With that commented out the server will let anything in, but the server doesn’t know what it does.

I’d guess this has been superseded by something else in the current version of the openvpn-ldap-auth package but can anyone tell me how to require a password for ldap authentication?


Altheus

OpenVpn Newbie
Posts: 6
Joined: Thu Jul 15, 2021 12:22 pm

Re: LDAP server letting anything in

Post

by Altheus » Tue Jul 20, 2021 11:20 am

The answer to this one was

verify-client-cert none

added to the server.conf file, I was trying to use a depreciated bit of config.

Also, PasswordIsCR true is obsolete and shouldn’t be used anymore.


/* * TRAuthLDAPConfig.m vi:ts=4:sw=4:expandtab: * Simple Configuration * * Copyright (c) 2005 — 2007 Landon Fuller <landonf@threerings.net> * Copyright (c) 2006 — 2007 Three Rings Design, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Landon Fuller nor the names of any contributors * may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS «AS IS» * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #import <stdio.h> #import <stdlib.h> #import <string.h> #import <fcntl.h> #import <errno.h> #import <assert.h> #import «TRAuthLDAPConfig.h« #import «TRLog.h« #import «TRHash.h« /* All Variables and Section Types */ typedef enum { /* All Section Types */ LF_NO_SECTION, /* Top-level */ LF_LDAP_SECTION, /* LDAP Server Settings */ LF_AUTH_SECTION, /* LDAP Authorization Settings */ LF_GROUP_SECTION, /* LDAP Group Settings */ /* Generic LDAP Search Variables */ LF_LDAP_BASEDN, /* Base DN for Search */ LF_LDAP_SEARCH_FILTER, /* Search Filter */ /* Generic PF Variables */ LF_AUTH_PFTABLE, /* PF Table Name */ /* LDAP Section Variables */ LF_LDAP_URL, /* LDAP Server URL */ LF_LDAP_TIMEOUT, /* LDAP Server Timeout */ LF_LDAP_BINDDN, /* Bind DN for LDAP Searches */ LF_LDAP_PASSWORD, /* Associated Password */ LF_LDAP_REFERRAL, /* Enable Referrals */ LF_LDAP_TLS, /* Enable TLS */ LF_LDAP_TLS_CA_CERTFILE, /* TLS CA Certificate File */ LF_LDAP_TLS_CA_CERTDIR, /* TLS CA Certificate Dir */ LF_LDAP_TLS_CERTFILE, /* TLS Client Certificate File */ LF_LDAP_TLS_KEYFILE, /* TLS Client Key File */ LF_LDAP_TLS_CIPHER_SUITE, /* TLS Cipher Suite */ /* Authorization Section Variables */ LF_AUTH_REQUIRE_GROUP, /* Require Group Membership */ /* Group Section Variables */ LF_GROUP_MEMBER_ATTRIBUTE, /* Group Membership Attribute */ LF_GROUP_MEMBER_RFC2307BIS, /* Look for full DN for user in attribute */ LF_GROUP_MEMBER_USECOMPAREOPERATION, /* Use LDAP Compare operation instead of Search (Search is faster but doesn’t work in all LDAP environments) */ /* OpenVPN Challenge/Response */ LF_AUTH_PASSWORD_CR, /* Password is in challenge/repsonse format */ /* Misc Shared */ LF_UNKNOWN_OPCODE, /* Unknown Opcode */ } ConfigOpcode; typedef struct OpcodeTable { const char *name; ConfigOpcode opcode; BOOL multi; BOOL required; } OpcodeTable; /* Bad opcode */ static OpcodeTable UnknownOpcode = { .name = ««, .opcode = LF_UNKNOWN_OPCODE, .multi = NO, .required = NO }; /* Section Types */ static OpcodeTable SectionTypes[] = { /* name opcode multi required */ { «LDAP«, LF_LDAP_SECTION, NO, YES }, { «Authorization«, LF_AUTH_SECTION, NO, YES }, { «Group«, LF_GROUP_SECTION, YES, NO }, { NULL, 0 } }; /* Generic LDAP Search Variables */ static OpcodeTable GenericLDAPVariables[] = { /* name opcode multi required */ { «BaseDN«, LF_LDAP_BASEDN, NO, YES }, { «SearchFilter«, LF_LDAP_SEARCH_FILTER, NO, YES }, { NULL, 0 } }; /* Generic PF Table Variables */ static OpcodeTable GenericPFVariables[] = { #ifdef HAVE_PF /* name opcode multi required */ { «PFTable«, LF_AUTH_PFTABLE, NO, NO }, #endif { NULL, 0 } }; /* LDAP Section Variables */ static OpcodeTable LDAPSectionVariables[] = { /* name opcode multi required */ { «URL«, LF_LDAP_URL, NO, YES }, { «Timeout«, LF_LDAP_TIMEOUT, NO, NO }, { «BindDN«, LF_LDAP_BINDDN, NO, NO }, { «Password«, LF_LDAP_PASSWORD, NO, NO }, { «FollowReferrals«, LF_LDAP_REFERRAL, NO, NO }, { «TLSEnable«, LF_LDAP_TLS, NO, NO }, { «TLSCACertFile«, LF_LDAP_TLS_CA_CERTFILE, NO, NO }, { «TLSCACertDir«, LF_LDAP_TLS_CA_CERTDIR, NO, NO }, { «TLSCertFile«, LF_LDAP_TLS_CERTFILE, NO, NO }, { «TLSKeyFile«, LF_LDAP_TLS_KEYFILE, NO, NO }, { «TLSCipherSuite«, LF_LDAP_TLS_CIPHER_SUITE, NO, NO }, { NULL, 0 } }; /* Authorization Section Variables */ static OpcodeTable AuthSectionVariables[] = { /* name opcode multi required */ { «RequireGroup«, LF_AUTH_REQUIRE_GROUP, NO, NO }, { NULL, 0} }; /* Group Section Variables */ static OpcodeTable GroupSectionVariables[] = { /* name opcode multi required */ { «MemberAttribute«, LF_GROUP_MEMBER_ATTRIBUTE, NO, NO }, { «RFC2307bis«, LF_GROUP_MEMBER_RFC2307BIS, NO, NO }, { «UseCompareOperation«, LF_GROUP_MEMBER_USECOMPAREOPERATION, NO, NO }, { NULL, 0 } }; /* OpenVPN Challenge/Response */ static OpcodeTable OpenVPNCRVariables[] = { /* name opcode multi required */ { «PasswordIsCR«, LF_AUTH_PASSWORD_CR, NO, NO }, { NULL, 0 } }; /* Section Types */ static OpcodeTable *Sections[] = { SectionTypes, NULL }; /* LDAP Section Definition */ static OpcodeTable *LDAPSection[] = { LDAPSectionVariables, NULL }; /* Auth Section Definition */ static OpcodeTable *AuthSection[] = { AuthSectionVariables, GenericLDAPVariables, GenericPFVariables, OpenVPNCRVariables, NULL }; /* Group Section Definition */ static OpcodeTable *GroupSection[] = { GroupSectionVariables, GenericLDAPVariables, GenericPFVariables, NULL }; /* Parse a string, returning the associated entry from the supplied table */ static OpcodeTable *parse_opcode (TRConfigToken *token, OpcodeTable **tables) { const char *cp = [token cString]; OpcodeTable *table, **p; unsigned int i; for (p = tables; *p; p++) { table = *p; for (i = 0; table[i].name; i++) if (strcasecmp(cp, table[i].name) == 0) return (&table[i]); } /* Unknown opcode */ return (&UnknownOpcode); } /* Parse a string, returning the associated opcode from the supplied table */ static const char *string_for_opcode(ConfigOpcode opcode, OpcodeTable *tables[]) { OpcodeTable *table, **p; unsigned int i; for (p = tables; *p; p++) { table = *p; for (i = 0; table[i].name; i++) if (table[i].opcode == opcode) return (table[i].name); } /* Unknown opcode */ return («?«); } /* * Simple object that maintains section parsing state */ @interface SectionState : TRObject { ConfigOpcode _opcode; TRHash *_hash; id _context; } @end @implementation SectionState — (void) dealloc { [_hash release]; if (_context) [_context release]; [super dealloc]; } — (id) init { self = [super init]; if (!self) return self; _opcode = LF_UNKNOWN_OPCODE; _hash = [[TRHash alloc] initWithCapacity: HASHCOUNT_T_MAX]; return self; } — (id) initWithOpcode: (ConfigOpcode) anOpcode { if ([self init]) _opcode = anOpcode; return self; } — (ConfigOpcode) opcode { return _opcode; } — (TRHash *) hashTable { return _hash; } — (void) setContext: (id) context { if (_context) [_context release]; _context = [context retain]; } — (id) context { return _context; } @end /** * Handles parsing of the plugin configuration file. */ @implementation TRAuthLDAPConfig — (void) dealloc { if (_url) [_url release]; if (_bindDN) [_bindDN release]; if (_bindPassword) [_bindPassword release]; if (_tlsCACertFile) [_tlsCACertFile release]; if (_tlsCACertDir) [_tlsCACertDir release]; if (_tlsCertFile) [_tlsCertFile release]; if (_tlsKeyFile) [_tlsKeyFile release]; if (_tlsCipherSuite) [_tlsCipherSuite release]; if (_baseDN) [_baseDN release]; if (_searchFilter) [_searchFilter release]; if (_ldapGroups) [_ldapGroups release]; if (_pfTable) [_pfTable release]; [super dealloc]; } /** * Initialize with the provided configuration file path. * The file will be parsed, and if an error occurs, * NULL returned. */ — (id) initWithConfigFile: (const char *) fileName { SectionState *section; int configFD; /* Initialize */ self = [self init]; if (self == NULL) return (self); /* Initialize the section stack */ _sectionStack = [[TRArray alloc] init]; section = [[SectionState alloc] initWithOpcode: LF_NO_SECTION]; [_sectionStack addObject: section]; [section release]; /* Open our configuration file */ _configFileName = [[TRString alloc] initWithCString: fileName]; configFD = open(fileName, O_RDONLY); if (configFD == —1) { [TRLog error: «Failed to open «%s« for reading«, [_configFileName cString]]; goto error; } /* Initialize the config parser */ _configDriver = [[TRConfig alloc] initWithFD: configFD configDelegate: self]; if (_configDriver == NULL) goto error; /* Parse the configuration file */ if (![_configDriver parseConfig]) goto error; [_configDriver release]; [_sectionStack release]; [_configFileName release]; return self; error: if (_configDriver) [_configDriver release]; if (_sectionStack) [_sectionStack release]; if (_configFileName) [_configFileName release]; [self release]; return (NULL); } /** * Return the current section opcode from the top * of the section stack. */ — (ConfigOpcode) currentSectionOpcode { return [[_sectionStack lastObject] opcode]; } /** * Return the current section’s hash table. */ — (TRHash *) currentSectionHashTable { return [[_sectionStack lastObject] hashTable]; } /** * Return the current section’s context. */ — (id) currentSectionContext { return [[_sectionStack lastObject] context]; } /** * Set the current section’s context. */ — (void) setCurrentSectionContext: (id) context { [[_sectionStack lastObject] setContext: context]; } /** * Allocate a SectionState object and push it onto the * section stack. */ — (void) pushSection: (ConfigOpcode) opcode { SectionState *section; section = [[SectionState alloc] initWithOpcode: opcode]; [_sectionStack addObject: section]; [section release]; } /** * Report a named section that should not be named to the user. */ — (void) errorNamedSection: (TRConfigToken *) section withName: (TRConfigToken *) name { [TRLog error: «Auth-LDAP Configuration Error: %s section types must be unnamed (%s:%u).«, [section cString], [_configFileName cString], [name lineNumber]]; [_configDriver errorStop]; } /** * Report an unknown key to the user. */ — (void) errorUnknownKey: (TRConfigToken *) key { [TRLog error: «Auth-LDAP Configuration Error: %s key is unknown (%s:%u).«, [key cString], [_configFileName cString], [key lineNumber]]; [_configDriver errorStop]; } /** * Report a duplicate key to the user. */ — (void) errorMultiKey: (TRConfigToken *) key { [TRLog error: «Auth-LDAP Configuration Error: multiple occurances of key %s (%s:%u).«, [key cString], [_configFileName cString], [key lineNumber]]; [_configDriver errorStop]; } /** * Report an invalid integer value to the user. */ — (void) errorIntValue: (TRConfigToken *) value { [TRLog error: «Auth-LDAP Configuration Error: %s value is not an integer (%s:%u).«, [value cString], [_configFileName cString], [value lineNumber]]; [_configDriver errorStop]; } /** * Report an invalid boolean value to the user. */ — (void) errorBoolValue: (TRConfigToken *) value { [TRLog error: «Auth-LDAP Configuration Error: %s value is not a boolean value — use either ‘True’ or ‘False’ (%s:%u).«, [value cString], [_configFileName cString], [value lineNumber]]; [_configDriver errorStop]; } /** * Report an unknown section type to the user. */ — (void) errorUnknownSection: (TRConfigToken *) section { [TRLog error: «Auth-LDAP Configuration Error: %s is not a known section type within this context (%s:%u).«, [section cString], [_configFileName cString], [section lineNumber]]; [_configDriver errorStop]; } /** * Report mismatched section closure to the user. */ — (void) errorMismatchedSection: (TRConfigToken *) section { [TRLog error: «Auth-LDAP Configuration Error: ‘</%s>’ is a mismatched section closure. Expected «</%s>« (%s:%u).«, [section cString], string_for_opcode([self currentSectionOpcode], Sections), [_configFileName cString], [section lineNumber]]; [_configDriver errorStop]; } /** * Check for any missing required variables and report them to the user. * @return YES on success, NO on failure. */ — (BOOL) validateRequiredVariables: (OpcodeTable **) tables withSectionEnd: (TRConfigToken *) section { OpcodeTable *table, **p; unsigned int i; for (p = tables; *p; p++) { table = *p; for (i = 0; table[i].name; i++) { if (table[i].required) { TRString *key = [[TRString alloc] initWithCString: table[i].name]; if ([[self currentSectionHashTable] valueForKey: key] == nil) { [TRLog error: «Auth-LDAP Configuration Error: Section %s is a missing required key ‘%s‘ (%s:%u).«, string_for_opcode([self currentSectionOpcode], Sections), table[i].name, [_configFileName cString], [section lineNumber]]; [key release]; [_configDriver errorStop]; return NO; } [key release]; } } } return YES; } /** * Called by the lemon generated parser when a new section is found. */ — (void) startSection: (TRConfigToken *) sectionType sectionName: (TRConfigToken *) name { OpcodeTable *opcodeEntry; /* Parse the section opcode */ opcodeEntry = parse_opcode(sectionType, Sections); /* Enter handler for the current state */ switch([self currentSectionOpcode]) { /* Top-level sections supported: * — LDAP (unnamed) * — Group (named) */ case LF_NO_SECTION: switch (opcodeEntry->opcode) { case LF_LDAP_SECTION: if (name) { [self errorNamedSection: sectionType withName: name]; return; } [self pushSection: opcodeEntry->opcode]; break; case LF_AUTH_SECTION: if (name) { [self errorNamedSection: sectionType withName: name]; return; } [self pushSection: opcodeEntry->opcode]; break; default: [self errorUnknownSection: sectionType]; return; } break; case LF_AUTH_SECTION: /* Currently, no named sections are supported */ if (name) { [self errorNamedSection: sectionType withName: name]; return; } /* Validate the section type */ switch (opcodeEntry->opcode) { TRLDAPGroupConfig *groupConfig; case LF_GROUP_SECTION: groupConfig = [[TRLDAPGroupConfig alloc] init]; [self pushSection: opcodeEntry->opcode]; [self setCurrentSectionContext: groupConfig]; if (!_ldapGroups) { _ldapGroups = [[TRArray alloc] init]; } /* Let the SectionContext own groupConfig */ [groupConfig release]; break; default: [self errorUnknownSection: sectionType]; return; } break; default: [self errorUnknownSection: sectionType]; return; } return; } /** * Called by the lemon-generated parser when a key value pair is found. */ — (void) setKey: (TRConfigToken *) key value: (TRConfigToken *) value { /* Handle key value pairs */ OpcodeTable *opcodeEntry; TRHash *hashTable = [self currentSectionHashTable]; switch ([self currentSectionOpcode]) { case LF_NO_SECTION: /* No keys are permitted in the top-level */ [self errorUnknownKey: key]; return; case LF_LDAP_SECTION: opcodeEntry = parse_opcode(key, LDAPSection); if (!opcodeEntry) { [self errorUnknownKey: key]; return; } switch (opcodeEntry->opcode) { int timeout; BOOL enableTLS; BOOL enableReferral; /* LDAP URL */ case LF_LDAP_URL: [self setURL: [value string]]; break; /* LDAP Bind DN */ case LF_LDAP_BINDDN: [self setBindDN: [value string]]; break; /* LDAP Bind Password */ case LF_LDAP_PASSWORD: [self setBindPassword: [value string]]; break; /* LDAP Connection Timeout */ case LF_LDAP_TIMEOUT: if (![value intValue: &timeout]) { [self errorIntValue: value]; return; } [self setTimeout: timeout]; break; /* LDAP Referrals Enabled */ case LF_LDAP_REFERRAL: if (![value boolValue: &enableReferral]) { [self errorBoolValue: value]; return; } [self setReferralEnabled: enableReferral]; break; /* LDAP TLS Enabled */ case LF_LDAP_TLS: if (![value boolValue: &enableTLS]) { [self errorBoolValue: value]; return; } [self setTLSEnabled: enableTLS]; break; /* LDAP CA Certificate */ case LF_LDAP_TLS_CA_CERTFILE: [self setTLSCACertFile: [value string]]; break; /* LDAP CA Certificate Directory */ case LF_LDAP_TLS_CA_CERTDIR: [self setTLSCACertDir: [value string]]; break; /* LDAP Certificate File */ case LF_LDAP_TLS_CERTFILE: [self setTLSCertFile: [value string]]; break; /* LDAP Key File */ case LF_LDAP_TLS_KEYFILE: [self setTLSKeyFile: [value string]]; break; /* TLS Cipher Suite */ case LF_LDAP_TLS_CIPHER_SUITE: [self setTLSCipherSuite: [value string]]; break; /* Unknown Setting */ default: [self errorUnknownKey: key]; return; } break; case LF_AUTH_SECTION: opcodeEntry = parse_opcode(key, AuthSection); if (!opcodeEntry) { [self errorUnknownKey: key]; return; } switch(opcodeEntry->opcode) { BOOL requireGroup; BOOL passWordCR; case LF_AUTH_REQUIRE_GROUP: if (![value boolValue: &requireGroup]) { [self errorBoolValue: value]; return; } [self setRequireGroup: requireGroup]; break; case LF_LDAP_BASEDN: [self setBaseDN: [value string]]; break; case LF_LDAP_SEARCH_FILTER: [self setSearchFilter: [value string]]; break; case LF_AUTH_PFTABLE: [self setPFTable: [value string]]; [self setPFEnabled: YES]; break; case LF_AUTH_PASSWORD_CR: if (![value boolValue: &passWordCR]) { [self errorBoolValue: value]; return; } [self setPassWordIsCR: passWordCR]; break; /* Unknown Setting */ default: [self errorUnknownKey: key]; return; } break; case LF_GROUP_SECTION: opcodeEntry = parse_opcode(key, GroupSection); if (!opcodeEntry) { [self errorUnknownKey: key]; return; } switch(opcodeEntry->opcode) { TRLDAPGroupConfig *config; BOOL memberRFC2307BIS; BOOL useCompareOperation; case LF_GROUP_MEMBER_ATTRIBUTE: config = [self currentSectionContext]; [config setMemberAttribute: [value string]]; break; case LF_GROUP_MEMBER_RFC2307BIS: config = [self currentSectionContext]; if (![value boolValue: &memberRFC2307BIS]) { [self errorBoolValue: value]; return; } [config setMemberRFC2307BIS: memberRFC2307BIS]; break; case LF_GROUP_MEMBER_USECOMPAREOPERATION: config = [self currentSectionContext]; if (![value boolValue: &useCompareOperation]) { [self errorBoolValue: value]; return; } [config setUseCompareOperation: useCompareOperation]; break; case LF_LDAP_BASEDN: config = [self currentSectionContext]; [config setBaseDN: [value string]]; break; case LF_LDAP_SEARCH_FILTER: config = [self currentSectionContext]; [config setSearchFilter: [value string]]; break; case LF_AUTH_PFTABLE: config = [self currentSectionContext]; [config setPFTable: [value string]]; [self setPFEnabled: YES]; break; /* Unknown Setting */ default: [self errorUnknownKey: key]; } break; default: /* Must be unreachable! */ [TRLog error: «Unhandled section type in setKey!n«]; abort(); break; } /* Lastly, prevent multiple occurances of a single-use key */ if (!opcodeEntry->multi) { if ([hashTable valueForKey: [key string]]) { [self errorMultiKey: key]; return; } [hashTable setObject: value forKey: [key string]]; } } /** * Verify that the now closed section isn’t mismatched, and then pop it off * the section stack. */ — (void) endSection: (TRConfigToken *) sectionEnd { OpcodeTable *opcodeEntry; opcodeEntry = parse_opcode(sectionEnd, Sections); /* Mismatched section? */ if (!opcodeEntry || opcodeEntry->opcode != [self currentSectionOpcode]) { [self errorMismatchedSection: sectionEnd]; return; } switch (opcodeEntry->opcode) { case LF_LDAP_SECTION: [self validateRequiredVariables: LDAPSection withSectionEnd: sectionEnd]; break; case LF_AUTH_SECTION: [self validateRequiredVariables: AuthSection withSectionEnd: sectionEnd]; break; case LF_GROUP_SECTION: /* Add the group config to the array */ if (![self validateRequiredVariables: GroupSection withSectionEnd: sectionEnd]) break; [_ldapGroups addObject: [self currentSectionContext]]; break; default: /* Must be unreachable! */ [TRLog error: «Unhandled section type in endSection!n«]; abort(); return; } [_sectionStack removeObject]; } — (void) parseError: (TRConfigToken *) badToken { if (badToken) [TRLog error: «A parse error occured while attempting to comprehend %s, on line %u.«, [badToken cString], [badToken lineNumber]]; else [TRLog error: «A parse error occured while attempting to read your configuration file.«]; [_configDriver errorStop]; } /* Accessors */ — (BOOL) tlsEnabled { return (_tlsEnabled); } — (void) setTLSEnabled: (BOOL) newTLSSetting { _tlsEnabled = newTLSSetting; } — (TRString *) url { return (_url); } — (TRString *) bindDN { return (_bindDN); } — (void) setBindDN: (TRString *) bindDN { if (_bindDN) [_bindDN release]; _bindDN = [bindDN retain]; } — (TRString *) bindPassword { return (_bindPassword); } — (void) setBindPassword: (TRString *) bindPassword { if (_bindPassword) [_bindPassword release]; _bindPassword = [bindPassword retain]; } — (void) setURL: (TRString *) newURL { if (_url) [_url release]; _url = [newURL retain]; } — (TRString *) baseDN { return (_baseDN); } — (void) setBaseDN: (TRString *) baseDN { if (_baseDN) [_baseDN release]; _baseDN = [baseDN retain]; } — (TRString *) searchFilter { return (_searchFilter); } — (BOOL) requireGroup { return (_requireGroup); } — (void) setRequireGroup: (BOOL) requireGroup { _requireGroup = requireGroup; } — (void) setSearchFilter: (TRString *) searchFilter { if (_searchFilter) [_searchFilter release]; _searchFilter = [searchFilter retain]; } — (BOOL) referralEnabled { return (_referralEnabled); } — (void) setReferralEnabled: (BOOL) newReferralSetting { _referralEnabled = newReferralSetting; } — (int) timeout { return (_timeout); } — (void) setTimeout: (int) newTimeout { _timeout = newTimeout; } — (TRString *) tlsCACertFile { return (_tlsCACertFile); } — (void) setTLSCACertFile: (TRString *) fileName { if (_tlsCACertFile) [_tlsCACertFile release]; _tlsCACertFile = [fileName retain]; } — (TRString *) tlsCACertDir { return (_tlsCACertDir); } — (void) setTLSCACertDir: (TRString *) directoryName { if (_tlsCACertDir) [_tlsCACertDir release]; _tlsCACertDir = [directoryName retain]; } — (TRString *) tlsCertFile { return (_tlsCertFile); } — (void) setTLSCertFile: (TRString *) fileName { if (_tlsCertFile) [_tlsCertFile release]; _tlsCertFile = [fileName retain]; } — (TRString *) tlsKeyFile { return (_tlsKeyFile); } — (void) setTLSKeyFile: (TRString *) fileName { if (_tlsKeyFile) [_tlsKeyFile release]; _tlsKeyFile = [fileName retain]; } — (TRString *) tlsCipherSuite { return (_tlsCipherSuite); } — (void) setTLSCipherSuite: (TRString *) cipherSuite { if (_tlsCipherSuite) [_tlsCipherSuite release]; _tlsCipherSuite = [cipherSuite retain]; } — (void) setPFTable: (TRString *) tableName { if (_pfTable) [_pfTable release]; _pfTable = [tableName retain]; } — (TRString *) pfTable { return (_pfTable); } — (BOOL) pfEnabled { return (_pfEnabled); } — (void) setPFEnabled: (BOOL) newPFSetting { _pfEnabled = newPFSetting; } — (TRArray *) ldapGroups { return _ldapGroups; } — (BOOL) passWordIsCR { return (_passwordISCR); } — (void) setPassWordIsCR: (BOOL) newCRSetting { _passwordISCR = newCRSetting; } @end

I’m trying to configure OpenVPN with openvpn-auth-ldap plugin to authorize users via Active Directory LDAP. When I use the same server config without plugin option, and add client config with generated client key and cert, connection is successful, so problem is in the plugin.

server.conf:

plugin /usr/lib/openvpn/openvpn-auth-ldap.so "/etc/openvpn-test/openvpn-auth-ldap.conf"
port 1194
proto tcp
dev tun
keepalive 10 60
topology subnet
server 10.0.2.0 255.255.255.0
tls-server
ca ca.crt
dh dh1024.pem
cert server.crt
key server.key
#crl-verify crl.pem
persist-key
persist-tun
user nobody
group nogroup
verb 3
mute 20

openvpn-auth-ldap.conf:

<LDAP>
    URL             ldap://dc1.domain:389
    TLSEnable       no
    BindDN          cn=bot_auth,cn=Users,dc=domain
    Password        bot_auth
    Timeout         15
    FollowReferrals yes
</LDAP>

<Authorization>
        BaseDN          "cn=Users,dc=domain"
        SearchFilter    "(sAMAccountName=%u)"
        RequireGroup    false
#        <Group>
#                BaseDN          "ou=groups,dc=mycompany,dc=local"
#                SearchFilter    "(|(cn=developers)(cn=artists))"
#                MemberAttribute uniqueMember
#        </Group>
</Authorization>

Top-level domain in AD is used by historical reasons. Analogue configuration is working for Apache 2.2 in mod-authzn-ldap. User and password are correct.

client.conf:

remote server_name
port 1194
proto tcp
client
pull
remote-cert-tls server
dev tun
resolv-retry infinite
nobind
ca ca.crt
; with keys - works fine
#cert test.crt
#key test.key
; without keys - by password
auth-user-pass
persist-tun
verb 3
mute 20

In server log there is string PLUGIN_INIT: POST /usr/lib/openvpn/openvpn-auth-ldap.so '[/usr/lib/openvpn/openvpn-auth-ldap.so] [/etc/openvpn-test/openvpn-auth-ldap.conf]' which indicates, that plugin failed. I can telnet to dc1.domain:389, so this is not network/firewall problem. Later server says TLS Error: TLS object -> incoming plaintext read error TLS handshake failed — without plugin it tryes to do usal key authentification.

server log:

Tue Nov 22 03:06:20 2011 OpenVPN 2.1.3 i486-pc-linux-gnu [SSL] [LZO2] [EPOLL] [PKCS11] [MH] [PF_INET6] [eurephia] built on Oct 21 2010
Tue Nov 22 03:06:20 2011 NOTE: OpenVPN 2.1 requires '--script-security 2' or higher to call user-defined scripts or executables
Tue Nov 22 03:06:20 2011 PLUGIN_INIT: POST /usr/lib/openvpn/openvpn-auth-ldap.so '[/usr/lib/openvpn/openvpn-auth-ldap.so] [/etc/openvpn-test/openvpn-auth-ldap.conf]' intercepted=PLUGIN_AUTH_USER_PASS_VERIFY|PLUGIN_CLIENT_CONNECT|PLUGIN_CLIENT_DISCONNECT
Tue Nov 22 03:06:20 2011 Diffie-Hellman initialized with 1024 bit key
Tue Nov 22 03:06:20 2011 /usr/bin/openssl-vulnkey -q -b 1024 -m <modulus omitted>
Tue Nov 22 03:06:20 2011 Control Channel Authentication: using 'ta.key' as a OpenVPN static key file
Tue Nov 22 03:06:20 2011 Outgoing Control Channel Authentication: Using 160 bit message hash 'SHA1' for HMAC authentication
Tue Nov 22 03:06:20 2011 Incoming Control Channel Authentication: Using 160 bit message hash 'SHA1' for HMAC authentication
Tue Nov 22 03:06:20 2011 TLS-Auth MTU parms [ L:1543 D:168 EF:68 EB:0 ET:0 EL:0 ]
Tue Nov 22 03:06:20 2011 Socket Buffers: R=[87380->131072] S=[16384->131072]
Tue Nov 22 03:06:20 2011 TUN/TAP device tun1 opened
Tue Nov 22 03:06:20 2011 TUN/TAP TX queue length set to 100
Tue Nov 22 03:06:20 2011 /sbin/ifconfig tun1 10.0.2.1 netmask 255.255.255.0 mtu 1500 broadcast 10.0.2.255
Tue Nov 22 03:06:20 2011 Data Channel MTU parms [ L:1543 D:1450 EF:43 EB:4 ET:0 EL:0 ]
Tue Nov 22 03:06:20 2011 GID set to nogroup
Tue Nov 22 03:06:20 2011 UID set to nobody
Tue Nov 22 03:06:20 2011 Listening for incoming TCP connection on [undef]
Tue Nov 22 03:06:20 2011 TCPv4_SERVER link local (bound): [undef]
Tue Nov 22 03:06:20 2011 TCPv4_SERVER link remote: [undef]
Tue Nov 22 03:06:20 2011 MULTI: multi_init called, r=256 v=256
Tue Nov 22 03:06:20 2011 IFCONFIG POOL: base=10.0.2.2 size=252
Tue Nov 22 03:06:20 2011 MULTI: TCP INIT maxclients=1024 maxevents=1028
Tue Nov 22 03:06:20 2011 Initialization Sequence Completed
Tue Nov 22 03:07:10 2011 MULTI: multi_create_instance called
Tue Nov 22 03:07:10 2011 Re-using SSL/TLS context
Tue Nov 22 03:07:10 2011 Control Channel MTU parms [ L:1543 D:168 EF:68 EB:0 ET:0 EL:0 ]
Tue Nov 22 03:07:10 2011 Data Channel MTU parms [ L:1543 D:1450 EF:43 EB:4 ET:0 EL:0 ]
Tue Nov 22 03:07:10 2011 Local Options hash (VER=V4): 'c413e92e'
Tue Nov 22 03:07:10 2011 Expected Remote Options hash (VER=V4): 'd8421bb0'
Tue Nov 22 03:07:10 2011 TCP connection established with [AF_INET]10.0.0.9:47808
Tue Nov 22 03:07:10 2011 TCPv4_SERVER link local: [undef]
Tue Nov 22 03:07:10 2011 TCPv4_SERVER link remote: [AF_INET]10.0.0.9:47808
Tue Nov 22 03:07:11 2011 10.0.0.9:47808 TLS: Initial packet from [AF_INET]10.0.0.9:47808, sid=a2cd4052 84b47108
Tue Nov 22 03:07:11 2011 10.0.0.9:47808 TLS_ERROR: BIO read tls_read_plaintext error: error:140890C7:SSL routines:SSL3_GET_CLIENT_CERTIFICATE:peer did not return a certificate
Tue Nov 22 03:07:11 2011 10.0.0.9:47808 TLS Error: TLS object -> incoming plaintext read error
Tue Nov 22 03:07:11 2011 10.0.0.9:47808 TLS Error: TLS handshake failed
Tue Nov 22 03:07:11 2011 10.0.0.9:47808 Fatal TLS error (check_tls_errors_co), restarting
Tue Nov 22 03:07:11 2011 10.0.0.9:47808 SIGUSR1[soft,tls-error] received, client-instance restarting
Tue Nov 22 03:07:11 2011 TCP/UDP: Closing socket

client log:

Tue Nov 22 03:06:18 2011 OpenVPN 2.1.3 x86_64-pc-linux-gnu [SSL] [LZO2] [EPOLL] [PKCS11] [MH] [PF_INET6] [eurephia] built on Oct 22 2010
Enter Auth Username:user
Enter Auth Password:
Tue Nov 22 03:06:25 2011 NOTE: OpenVPN 2.1 requires '--script-security 2' or higher to call user-defined scripts or executables
Tue Nov 22 03:06:25 2011 Control Channel Authentication: using 'ta.key' as a OpenVPN static key file
Tue Nov 22 03:06:25 2011 Outgoing Control Channel Authentication: Using 160 bit message hash 'SHA1' for HMAC authentication
Tue Nov 22 03:06:25 2011 Incoming Control Channel Authentication: Using 160 bit message hash 'SHA1' for HMAC authentication
Tue Nov 22 03:06:25 2011 Control Channel MTU parms [ L:1543 D:168 EF:68 EB:0 ET:0 EL:0 ]
Tue Nov 22 03:06:25 2011 Socket Buffers: R=[87380->131072] S=[16384->131072]
Tue Nov 22 03:06:25 2011 Data Channel MTU parms [ L:1543 D:1450 EF:43 EB:4 ET:0 EL:0 ]
Tue Nov 22 03:06:25 2011 Local Options hash (VER=V4): 'd8421bb0'
Tue Nov 22 03:06:25 2011 Expected Remote Options hash (VER=V4): 'c413e92e'
Tue Nov 22 03:06:25 2011 Attempting to establish TCP connection with [AF_INET]10.0.0.2:1194 [nonblock]
Tue Nov 22 03:06:26 2011 TCP connection established with [AF_INET]10.0.0.2:1194
Tue Nov 22 03:06:26 2011 TCPv4_CLIENT link local: [undef]
Tue Nov 22 03:06:26 2011 TCPv4_CLIENT link remote: [AF_INET]10.0.0.2:1194
Tue Nov 22 03:06:26 2011 TLS: Initial packet from [AF_INET]10.0.0.2:1194, sid=7a3c2a0f bd35bca7
Tue Nov 22 03:06:26 2011 WARNING: this configuration may cache passwords in memory -- use the auth-nocache option to prevent this
Tue Nov 22 03:06:26 2011 VERIFY OK: depth=1, /C=US/ST=CA/L=SanFrancisco/O=Fort-Funston/CN=Fort-Funston_CA/emailAddress=me@myhost.mydomain
Tue Nov 22 03:06:26 2011 Validating certificate key usage
Tue Nov 22 03:06:26 2011 ++ Certificate has key usage  00a0, expects 00a0
Tue Nov 22 03:06:26 2011 VERIFY KU OK
Tue Nov 22 03:06:26 2011 Validating certificate extended key usage
Tue Nov 22 03:06:26 2011 ++ Certificate has EKU (str) TLS Web Server Authentication, expects TLS Web Server Authentication
Tue Nov 22 03:06:26 2011 VERIFY EKU OK
Tue Nov 22 03:06:26 2011 VERIFY OK: depth=0, /C=US/ST=CA/L=SanFrancisco/O=Fort-Funston/CN=server/emailAddress=me@myhost.mydomain
Tue Nov 22 03:06:26 2011 Connection reset, restarting [0]
Tue Nov 22 03:06:26 2011 TCP/UDP: Closing socket
Tue Nov 22 03:06:26 2011 SIGUSR1[soft,connection-reset] received, process restarting
Tue Nov 22 03:06:26 2011 Restart pause, 5 second(s)
^CTue Nov 22 03:06:27 2011 SIGINT[hard,init_instance] received, process exiting

Does anybody know how to get openvpn-auth-ldap wirking?

  • #1

Hi all,
I tested this in FreeBSD 9.1, 9.2 and 10 x64 versions.

Already upgraded ports.

Installed ports:

security/openvpn

(version — 2.3.4)

security/openvpn-auth-ldap

(version — 2.0.3)

My

openvpn.conf

file content:

Code:

plugin /usr/local/lib/openvpn-auth-ldap.so "/usr/local/etc/openvpn/openvpn-auth-ldap.conf"
proto udp
port 1194
dev tun
server 192.168.150.0 255.255.255.0

ca /usr/local/etc/openvpn/keys/keys/ca.crt
cert /usr/local/etc/openvpn/keys/keys/openvpnserver.crt
key /usr/local/etc/openvpn/keys/keys/openvpnserver.key
client-cert-not-required
dh /usr/local/etc/openvpn/keys/keys/dh2048.pem
tls-auth /usr/local/etc/openvpn/keys/keys/ta.key 0

persist-key
persist-tun
keepalive 10 60

push "route 10.41.0.0 255.255.255.0"
topology subnet

user root
group wheel

daemon
log-append /var/log/openvpn.log

My

/usr/local/etc/openvpn/openvpn-auth-ldap.conf file

content:

Code:

<LDAP>
        URL             ldap://xxx.xx:389
        BindDN          XXX@XXX.XXX
        Password       XXXXXXXXXX
        Timeout         15
</LDAP>
<Authorization>
           BaseDN          "DC=atl,DC=lan"
           SearchFilter    "(&(sAMAccountName=%u)(memberOf=CN=mercurial,OU=mercurial,DC=xxx,DC=xx))"
</Authorization>

With

ldapsearch

I tested the LDAP configuration and it is successful.

When I tried to start OpenVPN from the command line with the command openvpn --config ad-auth.conf, I found the error in my log file below:

Code:

cat /var/log/openvpn.log
Sat Jun 21 14:36:37 2014 OpenVPN 2.3.4 amd64-portbld-freebsd9.2 [SSL (OpenSSL)] [LZO] [PKCS11] [MH] [IPv6] built on Jun 21 2014
Sat Jun 21 14:36:37 2014 library versions: OpenSSL 0.9.8y 5 Feb 2013, LZO 2.06
Sat Jun 21 14:36:37 2014 PLUGIN_INIT: plugin initialization function failed: /usr/local/lib/openvpn-auth-ldap.so
Sat Jun 21 14:36:37 2014 Exiting due to fatal error

After that I searched the error

Code:

plugin initialization function failed: openvpn-auth-ldap.so

on Google and found bug about this: http://lists.freebsd.org/pipermail/free … 56360.html

And I want to know if anybody found how I can fix this?
Thank you for answers.

Last edited by a moderator: Jan 9, 2015

Данная небольшая статья поведает как настроить openvpn, да не просто так, а с авторизацией через LDAP. Раз уж я рассказывал до этого как настраивать LDAP, то пришла пора его для чего-то применить. Вот одно их полезных моментов куда его можно применить в целях организации закрытой инфраструктуры изолированной от попадания того кого не нужно. OpenVpn в этом деле незаменимая вещь, позволяющая давать доступ тому кому надо, а кого не надо оставлять за бортом. Ну а LDAP предельно упрощает предоставление таких прав нужным людям.

Для начала приведу общий конфиг для openvpn остановивлюсь на тех вещах которые нужны именно для нормальной работы opnevpn+ldap

tmp-dir /tmp
local 142.2.44.55
port 2000
proto tcp-server
tcp-queue-limit 256
bcast-buffers 4096
duplicate-cn
dev tun0
ca /etc/openvpn/keys/ca.crt
cert /etc/openvpn/keys/local.crt
client-cert-not-required
username-as-common-name
key /etc/openvpn/keys/local.key
dh /etc/openvpn/keys/dh2048.pem
server 10.30.0.0 255.255.255.0
push "route 10.11.0.0 255.255.0.0"
push "dhcp-option DNS 10.11.0.1"
push "dhcp-option DOMAIN example.local"
push "sndbuf 393216"
push "rcvbuf 393216"
tls-server
tls-auth /etc/openvpn/keys/ta.key 0
tls-timeout 120
auth MD5
cipher AES-256-CBC
keepalive 10 120
max-clients 100
user nobody
group nogroup
persist-key
persist-tun
script-security 3 execve
status /var/log/openvpn/openvpn-status.log
log /var/log/openvpn/openvpn.log
verb 4
plugin /usr/lib/openvpn/openvpn-auth-ldap.so "auth-ldap.conf"

В целом все как при обычном конфигурировании openvpn, есть небольшие только отличия

username-as-common-name – меняет авторизацию по common name из сертификата на авторизацию по логину и паролю, то что именно нам и надо.

plugin /usr/lib/openvpn/openvpn-auth-ldap.so “auth-ldap.conf” – подключает в качестве плагина openvpn-auth-ldap.so, который даест возможность вытаскивать из LDAP данные пользователя и использовать их для прохождения авторизации. На дебиане он ставиться довольно просто:

apt-get install openvpn-auth-ldap

В основном конфиге все, более добавлять ничего не надо. Есть еще дополнительный конфиг auth-ldap.conf где и осуществляется вся магия авторизации через LDAP.

URL ldap://10.11.0.2
BindDN cn=user,dc=example
Password pass
Timeout 15

BaseDN “ou=people,dc=example”
SearchFilter “(&(uid=%u)(attr1=vpn))”
RequireGroup false

Тут указаны данные к какому LDAP серверу подсоединяться

URL ldap://10.11.0.2

с какими правами работать

BindDN cn=user,dc=example , Password pass

и в какой директории искать

BaseDN “ou=people,dc=example”

Так же указан фильтр по которому будет производиться выборка

SearchFilter “(&(uid=%u)(attr1=vpn))”

это значит что будет проводиться поиск по указанному пользователю и если у него есть атрибут attr1=vpn, что позволяет ограничить в директории пользователей на тех кому нужен доступ по VPN и кому нет, так же можно разграничить доступ по разным VPN.

Данный конфиг не позволяет работать с группами, что в целом довольно неудобно, потому что добавлять и удалять атрибуты в целом неудобно, особенно когда есть группы, которыми гораздо проще управлять. Для работы с группами конфиг будет следующий

URL ldap://10.11.0.2
BindDN cn=user,dc=example
Password pass
Timeout 15

BaseDN “ou=people,dc=example”
SearchFilter “(uid=%u)”
RequireGroup true

BaseDN “cn=openvpn,ou=groups,dc=example”
SearchFilter “(cn=openvpn)”
MemberAttribute memberUid

Добавляется секция с поиском в группе указанного пользователя. Теперь для предоставления прав на доступ достаточно добавить пользователя в указанную группу или удалить если он там больше не нужен. Вот в общем и все, надеюсь эта статья будет вам полезна.

Похожие записи:

I read all post in forum to make mi openvpn authenticate with ldap (AD W2K3).

  • pfSense1.2.3-PRERELEASE-TESTING-VERSION vmware appliance
  • Openvpn working (tested and connect ok without problem)

Ip of pfSense: 192.168.168.143
Ip of AD: 192.168.0.1

I follow the next steps (http://forum.pfsense.org/index.php/topic,14946.0.html):

#setenv PACKAGESITE ftp://ftp.freebsd.org/pub/FreeBSD/ports/i386/packages-7-stable/Latest/
#pkg_add -r openvpn-auth-ldap (install ok)
#pkg_add -r gcc43 (warnings with install)
#pkg_add -r gmake (say that exist a lower version)
#pkg_add -r texinfo (say that exist a lower version)

This symlink not work for me, well let me create, but is incorrect because no exist gcc-4.3.4:

#ln -s /usr/local/lib/gcc-4.3.4/libobjc.so.2 /usr/local/lib/libobjc.so.3

i have to modified to:

#ln -s /usr/local/lib/gcc43/libobjc.so.2 /usr/local/lib/libobjc.so.3

Then, i create the /usr/local/etc/openvpn-auth-ldap.conf and put my conf in this

 <ldap># LDAP server URL
        URL             ldap://ar.local:389

        # Bind DN (If your LDAP server doesn't support anonymous binds)
        BindDN         CN=userTest,CN=Users,DC=ar,DC=local

        # Bind Password
        Password      userTestPassword

        # Network timeout (in seconds)
        Timeout         15

        # Enable Start TLS
        # TLSEnable       no

        # Follow LDAP Referrals (anonymously)
        FollowReferrals no

        # 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          "CN=Users,DC=ar,DC=local"

        # User Search Filter
        SearchFilter    "sAMAccountName=%u"

        # Require Group Membership
        RequireGroup    true

        # Add non-group members to a PF table (disabled)
        #PFTable        ips_vpn_users

        <group>BaseDN          "CN=Users,DC=ar,DC=local"
               SearchFilter    "CN=Users"
                MemberAttribute Member
                # Add group members to a PF table (disabled)
                #PFTable        ips_vpn_eng</group></authorization> 

Finally, put this line in openvpn server:

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

Save configuration, and see the log

Nov 19 11:48:44 	openvpn[2151]: OpenVPN 2.0.6 i386-portbld-freebsd7.0 [SSL] [LZO] built on Feb 10 2009

I guess the vpn start correct.

Client cfg:


float
port 1194
dev tun
dev-node Ovpn
proto tcp-client
remote 192.168.168.143 1194
auth-user-pass
auth-nocache
ping 10
persist-tun
persist-key
tls-client
ca ca.crt
cert xxx.crt
key xxx.key
ns-cert-type server
comp-lzo
pull
verb 4

When connect with the client, start with all those lines, and put a username and password, then
continue and get this:

Thu Nov 19 11:05:54 2009 us=218000 Attempting to establish TCP connection with 1
92.168.168.143:1194
Thu Nov 19 11:06:15 2009 us=296000 TCP: connect to 192.168.168.143:1194 failed,
will try again in 5 seconds: Connection timed out (WSAETIMEDOUT)

In pfsense log > openvpn > no new row add

Ok, i have a problem, but dont know what problem.

1. use

ldapsearch -h 192.168.0.1 -p 389 -D ‘cn=userTest,cn=users,dc=ar,dc=local’ -W -x -b ‘dc=ar,dc=local’

and get connect succesfull to AD


# numResponses: 444
# numEntries: 440
# numReferences: 3

Some search in google, get something like testplugin in src of the openvpn-auth-ldap, this can use to test the connection to vpn without openvpn.
But, i dont know to much of bsd and get this:

# cd /root/
# cd auth-ldap-2.0.3
# cd /sbin/
# cd /root/auth-ldap-2.0.3/src/
# ./testplugin.c /usr/local/etc/openvpn-auth-ldap.cfg
./testplugin.c: /COPYRIGHT: Permission denied
LFAuthLDAPConfig.h: not found
LFAuthLDAPConfig.h: not found
LFAuthLDAPConfig.h: not found
./testplugin.c: 5: Syntax error: "(" unexpected

Well, is a problem cannot test the connection, and worst if a dont know to much of bsd, so, if you get me some clue or start to investigate, will be appreciate.

Regards.

По умолчанию в OpenVPN используется аутентификация пользователей по сертификатам. Это означает, что любой пользователь, у которого есть *.ovpn файл с настройками подключения и сертификатами может подключиться к вашем OpenVPN серверу без пароля. В OpenVPN вы можете включить и настроить аутентификацию пользователей через LDAP сервер (Active Directory или FreeIPA).

Рассмотрим два сценария подключения к LDAP для проверки учетных данных пользователей:

  • Плагин openvpn-auth-ldap
  • Внешние скрипты

    Содержание:

  • Настройка LDAP аутентификации OpenVPN с помощью openvpn-auth-ldap
  • Active Directory аутентификации OpenVPN с помощью скриптов

Настройка LDAP аутентификации OpenVPN с помощью openvpn-auth-ldap

Установите на OpenVPN сервере пакет openvpn-auth-ldap. Например, на Ubuntu/Debian для установки нужно выполнить команду:

# apt-get install openvpn-auth-ldap –y

Внесите изменения в файл server.conf:

# nano /etc/openvpn/server.conf

username-as-common-name
plugin /usr/lib/openvpn/openvpn-auth-ldap.so /etc/openvpn/auth/ldap.conf

Создайте в домене Active Directory нового пользователя openvpnsvc с паролем 01ru1bpRas. Эта учетная запись будет использоваться сервером OpenVPN для доступа к LDAP каталогу.

Затем создайте доменную группу безопасности VPN_users. Добавьте в нее аккаунты пользователей, которым разрешено выполнять аутентификацию через OpenVPN.

Теперь создайте каталог /etc/openvpn/auth и файл ldap.conf:

# mkdir /etc/openvpn/auth && nano /etc/openvpn/auth/ldap.conf

URL             ldap://mskdc01.vmblog.ru
BindDN          CN=openvpnsvc,CN=Users,DC=vmblog,DC=ru
Password        01ru1bpRas
Timeout         15
TLSEnable       no
BaseDN          "DC=vmblog,DC=ru"
SearchFilter    "(&(sAMAccountName=%u)(memberOf=CN=VPN_ users,CN=Users,DC=vmblog,DC=ru))"

Замените в файле парамаетры подключения к вашему контроллеру домена и DN (Distinguished Name).

Перезапустите openvpn:

# service openvpn restart

Осталось на клиентах OpenVPN добавьте в конфигурационный файл .ovpn строку:

auth-user-pass

Теперь при подключении к серверу у пользователя будет появляться запрос на ввод учетных данных.

Active Directory аутентификации OpenVPN с помощью скриптов

Если вы используете OpenVPN сервер на Windows, вы не сможете установить в нем плагин openvpn-auth-ldap. В этом случае для аутентификации пользователей OpenVPN через Active Directory можно использовать набор скриптов.

Предполагаем, что вы создали в AD группу VPN_users и добавили в нее пользователей, которым разрешено подключаться к OpenVPN.

На сервере OpenVPN добавьте следующие параметры в файл server.conf:

script-security 3
auth-user-pass-verify OpenVPNAuthWrapper.cmd via-env

Теперь создайте в каталоге с конфиг файлом server.conf следующие файлы:

  • AuthOpenVPN.ini
  • Auth4OpenVPN.vbs
  • AuthOpenVPNWrapper.cmd

AuthOpenVPN.ini

Server = "192.168.15.20"
Domain = "VMBLOG"
DN = "OU=Users,DC=vmblog,DC=ru"
Group = "VPN_users"
Logging = "On"

Код файла Auth4OpenVPN.vbs доступен здесь https://sites.google.com/site/amigo4life2/openvpn

AuthOpenVPNWrapper.cmd

set LOCALAPPDATA=C:Users%USERNAME%AppDataLocal
set CommonProgramFiles=C:Program FilesCommon Files
set CommonProgramFiles(x86)=C:Program Files (x86)Common Files
set CommonProgramW6432=C:Program FilesCommon Files
C:WindowsSystem32cscript.exe "C:Program FilesOpenVPNconfigAuth4OpenVPN.vbs"
exit %errorlevel%

Перезапустите службу OpenVPNService с помощью PowerShell:

Get-Service OpenVPNService| Restart-Service

Добавьте в конфигурационный файл клиента *.ovpn строки:

auth-user-pass
auth-retry interact

Теперь при подключении клиента ваш OpenVPN сервер на Windows будет проверять учетные данные пользователя в Active Directory.

Обновлено Обновлено: 26.08.2021
Опубликовано Опубликовано: 2016 год или раньше

В данном примере настройка сервера выполняется с использованием дистрибутива Linux — Ubuntu Server. Клиент настраивается под Microsoft Windows. В качестве LDAP-сервера мною используется Microsoft Active Directory.

Статью можно использовать как основу для настройки OpenVPN на любой операционной системе семейства UNIX.

Готовим сервер

Заходим в систему под суперпользователем:

sudo su

Устанавливаем часовой пояс (у меня московское время) и синхронизируем его с сервером времени:

cp /usr/share/zoneinfo/Europe/Moscow /etc/localtime; ntpdate ru.pool.ntp.org

Настраиваем задание в cron для автоматической синхронизации времени каждый день в 00:00:

mkdir -p /var/cron/tabs && echo ‘0 0 * * * /usr/sbin/ntpdate ru.pool.ntp.org’ >> /var/cron/tabs/crontab && crontab /var/cron/tabs/crontab && crontab -l

Обновляем пакеты:

apt-get update && apt-get upgrade

Устанавливаем OpenVPN и создаем сертификаты

Устанавливаем пакеты openvpn и easy-rsa:

# apt-get install openvpn easy-rsa -y

Создаем каталог easy-rsa, переходим в него и копируем рабочие файлы:

# mkdir /etc/openvpn/easy-rsa
# cd /etc/openvpn/easy-rsa
# cp -r /usr/share/easy-rsa/* .

Открываем на редактирование скрипт vars и выставляем подходящие значения для своего сертификата:

export KEY_COUNTRY=»RU»

export KEY_PROVINCE=»Leningrad»

export KEY_CITY=»Sankt-Petersburg»

export KEY_ORG=»DMOSK COMPANY»

export KEY_EMAIL=»master@dmosk.ru»

export KEY_CN=DMOSK

export KEY_OU=DMOSK

export KEY_NAME=name-openvpn-server.dmosk.ru

export KEY_ALTNAMES=»name-openvpn-server»

#export PKCS11_MODULE_PATH=changeme

#export PKCS11_PIN=1234

Запускаем на исполнение отредактированный скрипт:

На всякий случай, чистим каталоги от старых сертификатов:

Генерируем первый сертификат:

На все запросы просто нажимаем Enter, так как мы все настроили в переменных с помощью файла vars.

Создаем ключ для сервера:

# ./build-key-server server

В конце подтверждаем подписание сертификата ([Y]).

Формируем ключ Диффи-Хеллмана:

Теперь создаем ключ для клиента:

В конце подтверждаем подписание сертификата ([Y]).

Ну и на последок, TLS-ключ:

# openvpn —genkey —secret keys/ta.key

Копируем каталог с созданными сертификатами и ключами в /etc/openvpn:

# cp -r keys /etc/openvpn/

Настраиваем сервер и клиента

Настройка сервера

Создаем конфигурационный файл и вставляем в него следующее содержимое:

# nano /etc/openvpn/server.conf

local 192.168.166.155

port 443

proto udp

dev tun

ca keys/ca.crt

cert keys/server.crt

key keys/server.key

dh keys/dh2048.pem

tls-auth keys/ta.key 0

server 172.16.10.0 255.255.255.0

ifconfig-pool-persist ipp.txt

keepalive 10 120

max-clients 32

client-to-client

persist-key

persist-tun

status /var/log/openvpn/openvpn-status.log

log-append /var/log/openvpn/openvpn.log

# 0 is silent, except for fatal errors

# 4 is reasonable for general usage

# 5 and 6 can help to debug connection problems

# 9 is extremely verbose

verb 4

mute 20

daemon

mode server

tls-server

comp-lzo

* 192.168.166.155 — IP-адрес, на котором сервер будет устанавливать VPN-соединение. 172.16.10.0 255.255.255.0 — адресация для виртуальной сети. 32 — количество клиентов для одновременного подключения.

Создаем каталог для логов и запускаем службу сервера openvpn:

mkdir /var/log/openvpn
# service openvpn start

Проверить работоспособность службы можно командой:

Настройка клиента

Заходим на официальный сайт openvpn и скачиваем клиента для Windows:

https://openvpn.net/index.php/open-source/downloads.html

Загрузка клиента openvpn

Запускаем скачанный файл и устанавливаем программу, нажимая «Далее».

Переходим в папку C:Program FilesOpenVPNconfig. И копируем в нее файлы ca.crt, client.crt, client.key, dh2048.pem, ta.key из каталога /etc/openvpn/keys на сервере.

** Самый простой способ скопировать файлы с сервера UNIX — воспользоваться программой WinSCP.

У вас, скорее всего, возникнет проблема при открытии папки keys — ошибка permission denied (не хватает прав). Для обхода этой проблемы на сервере Ubuntu скопируйте необходимые ключи во временную папку и предоставьте к ним полный доступ:

mkdir /tmp/keys
# cd /etc/openvpn/keys
# cp ca.crt client.crt client.key dh2048.pem ta.key /tmp/keys
# chmod -R 777 /tmp/keys

По завершении копирования не забываем удалить папку /tmp/keys:

Теперь возвращаемся к компьютеру с Windows, открываем блокнот от имени администратора и вставляем следующие строки:

client

resolv-retry infinite

nobind

remote 192.168.166.155 443

proto udp

dev tun

comp-lzo

ca ca.crt

cert client.crt

key client.key

dh dh2048.pem

tls-client

tls-auth ta.key 1

float

keepalive 10 120

persist-key

persist-tun

verb 0

*** 192.168.166.155 — IP-адрес сервера VPN.

Сохраняем файл с именем config.ovpn в папке C:Program FilesOpenVPNconfig.

Запускаем с рабочего стола программу «OpenVPN GUI» от имени администратора (это важно).

Нажимаем правой кнопкой по появившемуся в трее значку и выбираем «Подключиться»:

Запуск подключения openvpn-клиента к серверу

Если все настроено правильно, произойдет подключение и значок поменяет цвет с серого на зеленый.

Настраиваем аутентификацию через LDAP

На сервере OpenVPN

Устанавливаем пакет openvpn-auth-ldap:

# apt-get install openvpn-auth-ldap -y

Редактируем конфигурационный файл openvpn (добавляем две строки):

# nano /etc/openvpn/server.conf

username-as-common-name

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

В директории /etc/openvpn создаем каталог auth и в нем конфигурационный файл ldap.conf. В последний добавляем следующие строки:

# mkdir /etc/openvpn/auth && nano /etc/openvpn/auth/ldap.conf

     URL             ldap://dc1.dmosk.local

     BindDN          CN=openvpn,CN=Users,DC=dmosk,DC=local

     Password        openvpn

     Timeout         15

     TLSEnable       no

       BaseDN          «DC=dmosk,DC=local»

       SearchFilter    «(&(sAMAccountName=%u)(memberOf=CN=VPN users,CN=Users,DC=dmosk,DC=local))»

**** ldap://dc1.dmosk.local — контроллер домена. CN=openvpn,CN=Users,DC=dmosk,DC=local — учетная запись для связывания с контроллером домена. openvpn — пароль для учетной записи openvpn. DC=dmosk,DC=local — корень в домене, с которого начнется поиск учетной записи для аутентификации. CN=VPN users,CN=Users,DC=dmosk,DC=local — группа безопасности, в которую должна входить учетная запись для успешной аутентификации.

Перезагружаем демон openvpn:

# service openvpn restart

На сервере Active Directory

Запускаем оснастку для управления пользователями и компьютерами.

В контейнере «Users» создаем учетную запись openvpn с паролем openvpn. Никаких дополнительных прав ей не даем.

***** Данные контейнер, имя и пароль используются для примера. Само собой, вы можете использовать любые значения. Только не забывайте также редактировать конфигурационный файл ldap.conf на сервере.

В том же контейнере создаем группу безопасности «VPN users». В нее добавляем учетные записи всех пользователей, которым хотим предоставить возможность подключаться к VPN.

****** Если в компании сложная структура Active Directory с множеством сайтов, возможно, стоит сделать паузу на 15 минут и подождать окончания репликации.

На клиенте Windows

Запускаем блокнот от имени администратора и открываем конфигурационный файл клиента openvpn (C:Program FilesOpenVPNconfigconfig.ovpn).

Добавляем в него одну строку:

Сохраняем файл и проверяем работоспособность. При включении клиента появится окно для ввода логина и пароля.

Аутентификация openvpn через LDAP

Вводим логин и пароль для учетной записи, которую мы добавили в группу «VPN users» — произойдет подключение и значок поменяет цвет с серого на зеленый.

Понравилась статья? Поделить с друзьями:
  • Aui teso ошибка интерфейса
  • Auepuc exe системная ошибка
  • Auepmaster exe ошибка приложения
  • Audmig no audio endpoint migration settings found 0x2 как исправить
  • Audition has encountered an error reading or writing to disk