Good morning Team!
Server: Win10 Pro 1904 - OpenVPN 2.5
Client: Win10 Pro 1904 - OpenVPN 2.5
Both machines are members of a Windows AD Domain.
I got a L2 tap working between the two using certs for authentication, however I'm not clear how to manage machine vs user certs or how to deploy those effectively for 100+ users. This brought me to possibly using LDAP or Radius, however my attempts at getting authentication working have failed.
Would anyone have a recommendation on how to move forward; cert deployment or correct the LDAP config issue?
If LDAP is the suggestion, I may need some additional help getting that working. I'm stuck on:
SERVER LOG:
2020-11-18 10:53:44 us=290506 1.2.3.4:52546 openvpn_execve: CreateProcess C:\Program Files\OpenVPN\config\Auth4OpenVPN.vbs failed: Unknown error (errno=193)
2020-11-18 10:53:44 us=290506 1.2.3.4:52546 WARNING: Failed running command (--auth-user-pass-verify): external program did not execute -- returned error code -1
2020-11-18 10:53:44 us=290506 1.2.3.4:52546 TLS Auth Error: Auth Username/Password verification failed for peer
local 10.16.255.5
port 1194
proto udp
dev tap
ca "C:\\Program Files\\OpenVPN\\config\\ca.crt"
cert "C:\\Program Files\\OpenVPN\\config\\OPENVPN-SERVER-KEY.crt"
key "C:\\Program Files\\OpenVPN\\config\\OPENVPN-SERVER-KEY.key"
script-security 3
auth-user-pass-verify Auth4OpenVPN.vbs via-env
auth-user-pass-verify "C:\\Program Files\\OpenVPN\\config\\Auth4OpenVPN.vbs" via-file
dh "C:\\Program Files\\OpenVPN\\config\\dh2048.pem"
server-bridge 10.64.255.5 255.255.255.0 10.64.255.21 10.64.255.99
push "route 10.64.0.0 255.255.0.0 10.16.255.1"
push "route 10.80.0.0 255.255.0.0 10.16.255.1"
push "route 10.128.0.0 255.255.0.0 10.16.255.1"
push "route 192.168.111.0 255.255.255.0 10.16.255.1"
push "dhcp-option DNS 10.64.0.21"
push "dhcp-option DNS 10.64.0.22"
keepalive 10 120
tls-auth ta.key 0
cipher AES-256-CBC
comp-lzo
persist-key
persist-tun
status "C:\\Program Files\\OpenVPN\\config\\openvpn-status.log"
verb 7
explicit-exit-notify 1
client
dev tap
proto udp
remote mypublic.ip 1194
resolv-retry infinite
nobind
persist-key
persist-tun
ca "C:\\Program Files\\OpenVPN\\config\\ca.crt"
cert "C:\\Program Files\\OpenVPN\\config\\PCNAME-KEY.crt"
key "C:\\Program Files\\OpenVPN\\config\\PCNAME-KEY.key"
# force login prompt
auth-user-pass
auth-retry interact
remote-cert-tls server
tls-auth ta.key 1
cipher AES-256-CBC
comp-lzo
verb 6
<ca>
-----BEGIN CERTIFICATE-----
Cert Removed
-----END CERTIFICATE-----
</ca>
<cert>
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 2 (0x2)
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=US, ST=FL, L=TAMPA, O=acme, OU=acme.local, CN=PCNAME/name=PCNAME/emailAddress=
it-team@acmeinc.com
Validity
Not Before: Sep 9 01:10:03 2020 GMT
Not After : Sep 7 01:10:03 2030 GMT
Subject: C=US, ST=FL, L=TAMPA, O=acme, OU=acme.local, CN=PCNAME/name=PCNAME/emailAddress=
it-team@acmeinc.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (4096 bit)
Modulus:
key removed
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
Netscape Comment:
Easy-RSA Generated Certificate
X509v3 Subject Key Identifier:
key removed
X509v3 Authority Key Identifier:
keyid:key removed
DirName:/C=US/ST=FL/L=TAMPA/O=acme/OU=acme.local/CN=PCNAME/name=PCNAME/emailAddress=
it-team@acmeinc.com
serial:removed
X509v3 Extended Key Usage:
TLS Web Client Authentication
X509v3 Key Usage:
Digital Signature
Signature Algorithm: sha256WithRSAEncryption
Signature removed
-----BEGIN CERTIFICATE-----
keyremoved
-----END CERTIFICATE-----
</cert>
<key>
-----BEGIN PRIVATE KEY-----
keyremoved
</key>
VBScript: AuthOpenVPN.vbs
'.............................................................................
' Auth4OpenVPN.vbs
' Jose Ortega,
' (C)2007.
' http://amigo4life.googlepages.com/openvpn
'
'.............................................................................
Option Explicit
Const SEVERITY_INFO = &H00
Const SEVERITY_ERROR = &H01
Const SEVERITY_WARNING = &H02
Const ADS_SECURE_AUTHENTICATION = &H01
Const ADS_USE_ENCRYPTION = &H02
Const ADS_SERVER_BIND = &H0200
Const ADS_SCOPE_SUBTREE = &H02
Const cfgFilePath = "auth4openvpn.ini"
Dim fileContent, parameters,ovUser, ovPass
'.............................................................................
sub LogEvent(EventDescription, EventType)
Dim objShell
Set objShell = Wscript.CreateObject("Wscript.Shell")
objShell.LogEvent EventType, EventDescription
Set objShell = nothing
end sub
'.............................................................................
Sub Prn(textToPrint)
wscript.echo textToPrint
end sub
'.............................................................................
Function LogError (byVal ErrNumber)
if errnumber = 0 then
LogError = FALSE
exit function
end if
Select Case ErrNumber
case -2147217911, -2147023570
LogEvent "Auth4OpenVPN: Incorrect credentials." & _
vbNewline & _
"Username: " & Ucase(ovUser), SEVERITY_WARNING
case -2147217865
LogEvent "Auth4OpenVPN: Cannot find server" & _
" or LDAP path supplied.", SEVERITY_ERROR
case else
LogEvent "Auth4OpenVPN: " & errnumber & ", " & _
err.description, SEVERITY_ERROR
end Select
LogError = TRUE
end Function
'.............................................................................
Function IsAuthOK()
Dim adoConn, AdoCmd, rsUserDN, rsGroupDN, userDN, groupDN, adUser
Dim userGroupsArray, group
Dim oDSP, myDSP, root
Dim server, domain, ldapPath, adGroup, logging
server = parameters(0) : domain = parameters(1)
ldapPath = parameters(2) : adGroup = parameters(3)
logging = parameters(4)
'------------------------------------------------------------------------
'check credentials
Set myDSP = GetObject("LDAP:")
On Error Resume Next
Set root = myDSP.OpenDSObject("LDAP://" & server & "/" & _
"RootDSE", domain & "\" & ovUser, _
ovPass, ADS_SERVER_BIND AND _
ADS_USE_ENCRYPTION)
if LogError(err.number) then
on error goto 0 'disable on error resume
IsAuthOK = FALSE
Exit Function
end if
Set root = nothing
'------------------------------------------------------------------------
Set adoConn = CreateObject("ADODB.Connection")
Set adoCmd = CreateObject("ADODB.Command")
with adoConn
.Provider = "ADsDSOObject"
.Properties("User ID") = domain & "\" & ovUser
.Properties("Password") = ovPass
.Properties("Encrypt Password") = TRUE
.Properties("ADSI Flag") = &H01
.Properties("Timeout") = 10
.Open "Active Directory Provider"
end with
with adoCmd
Set .ActiveConnection = adoConn
.Properties("Page Size") = 10
.Properties("Cache Results") = FALSE
.Properties("Searchscope") = ADS_SCOPE_SUBTREE
'----------------------------------------------------------------
.CommandText = "SELECT distinguishedName FROM 'LDAP://" & _
server & "/" & ldapPath & "' " & _
"WHERE objectClass='user' " & _
"AND saMaccountName='" & ovUser & "'"
on error resume next
Set rsUserDN = .Execute
if LogError(err.number) then
on error goto 0 'disable on error resume
adoConn.Close
Set adoConn = nothing
Set AdoCmd = nothing
IsAuthOK = FALSE
Exit Function
end if
if rsUserDn.EOF then
IsAuthOK = FALSE
LogEvent "Auth4OpenVPN: Cannot find user under LDAP path" & _
" set in Auth4OpenVPN.ini file.", SEVERITY_ERROR
adoConn.Close
Set adoConn = nothing
Set AdoCmd = nothing
Exit Function
end if
userDN = rsUserDN.Fields(0)
'----------------------------------------------------------------
.CommandText = "SELECT distinguishedName " & _
"FROM 'LDAP://" & _
server & "/" & ldapPath & "' " & _
"WHERE objectClass='group' " & _
"AND name='" & adGroup & "'"
Set rsGroupDN = .Execute
if rsGroupDN.EOF then
IsAuthOK = FALSE
LogEvent "Auth4OpenVPN: Cannot find Group under LDAP path" & _
" set in Auth4OpenVPN.ini file.", SEVERITY_ERROR
adoConn.Close
Set adoConn = nothing
Set AdoCmd = nothing
Exit Function
end if
groupDN=rsGroupDN.fields(0)
.CommandText = "SELECT distinguishedName " & _
"FROM 'LDAP://" & _
server & "/" & ldapPath & "' " & _
"WHERE objectClass='group' " & _
"AND name='" & adGroup & "'" & _
"AND member='" & userDN & "'"
Set rsGroupDN = .Execute
if not rsGroupDN.EOF then
if Ucase(logging) = "ON" then
LogEvent "Auth4OpenVPN: " & _
"Authentication successful." & vbNewline & _
"Username: " & Ucase(ovUser), SEVERITY_INFO
end if
IsAuthOK = TRUE
adoConn.Close
Set adoConn = nothing
Set AdoCmd = nothing
Exit Function
end if
End With
'--------------------------------------------------------------------
IsAuthOK = FALSE
LogEvent "Auth4OpenVPN: User is not a member of the group: " & _
Ucase(adGroup) & vbNewline & "Username: " & _
Ucase(ovUser), SEVERITY_WARNING
Set adUser = nothing
Set oDSP = nothing
end Function
'.............................................................................
Function IsSettingsFileOK()
Dim objFSO, openFile
Set objFSO = CreateObject("Scripting.FileSystemObject")
If objFSO.FileExists(cfgFilePath) Then
On Error Resume Next
set openFile = objFSO.OpenTexTFile(cfgFilePath)
if err.number then
IsSettingsFileOK = FALSE
LogEvent "Auth4OpenVPN: Cannot read Auth4OpenVPN.ini file.", _
SEVERITY_ERROR
On Error Goto 0 'disable On Error Resume
Set objFSO = nothing
Exit Function
end if
fileContent = openFile.ReadAll
openFile.Close
Else
IsSettingsFileOK = FALSE
LogEvent "Auth4OpenVPN: The Auth4OpenVPN.ini file is missing.", _
SEVERITY_ERROR
Set objFSO = nothing
Exit Function
End If
Set objFSO = nothing
IsSettingsFileOK = TRUE
end Function
'.............................................................................
Function GetFirstMatch(PatternToMatch, StringToSearch)
Dim regEx, CurrentMatch, CurrentMatches
Set regEx = New RegExp
with regEx
.Pattern = PatternToMatch
.IgnoreCase = TRUE
.Global = TRUE
.MultiLine = TRUE
Set CurrentMatches = .Execute(StringToSearch)
end with
GetFirstMatch = ""
If CurrentMatches.Count >= 1 Then
Set CurrentMatch = CurrentMatches(0)
If CurrentMatch.SubMatches.Count >= 1 Then
GetFirstMatch = CurrentMatch.SubMatches (0)
End If
End If
Set regEx = Nothing
End Function
'.............................................................................
Function AreSettingsOK()
Dim pattern
Dim i
parameters = Array ("SERVER", "DOMAIN", "DN", "GROUP", "LOGGING")
For i = 0 to 4
pattern = ".*\r\n\s*" & parameters(i) & "\s*\=\s*\""(.*)\"""
parameters(i) = Trim(getFirstMatch(pattern, fileContent))
if Len(parameters(i)) = 0 then
AreSettingsOK = FALSE
LogEvent "Auth4OpenVPN: Missing settings in Auth4OpenVPN.ini" & _
" file.", SEVERITY_ERROR
Exit Function
end if
Next
AreSettingsOK = TRUE
End Function
'.............................................................................
Function AreCredentialsOK()
if Wscript.Arguments.Count = 0 then
'no cmd args, read OpenVPN supplied credentials
Dim myObj
Set myObj = Wscript.CreateObject("Wscript.Shell")
ovUser = myObj.ExpandEnvironmentStrings("%username%")
ovPass = myObj.ExpandEnvironmentStrings("%password%")
Set myObj = nothing
if Len(ovUser)=0 or Len(ovPass)=0 then
AreCredentialsOK = FALSE
LogEvent "Auth4OpenVPN: Empty username or password " & _
"are not allowed.", SEVERITY_ERROR
Exit Function
end if
AreCredentialsOK = TRUE
Exit Function
'-------------------------------------------------------------------
Elseif Wscript.Arguments.Count = 2 then
'cmd args present, read user and pass provided for testing.
ovUser = Trim(Wscript.Arguments(0))
OvPass = Trim(Wscript.Arguments(1))
if Len(ovUser)=0 or Len(ovPass)=0 then
AreCredentialsOK = FALSE
LogEvent "Auth4OpenVPN: Empty username or password " & _
"are not allowed.", SEVERITY_ERROR
Exit Function
end if
AreCredentialsOK = TRUE
Exit Function
Else
LogEvent "Auth4OpenVPN: Invalid number of arguments.", _
SEVERITY_ERROR
AreCredentialsOK = FALSE
End If
End Function
'.............................................................................
Sub Main
If AreCredentialsOk then
if IsSettingsFileOK then
if AreSettingsOK then
if IsAuthOk then
if Wscript.Arguments.Count = 0 then
wscript.quit(0)
else
Prn "Authentication successful." & vbNewline
wscript.quit(0)
end if
end if
end if
end if
end if
if Wscript.Arguments.Count = 0 then
wscript.quit(1)
else
Prn "Authentication failed." & vbNewline & _
"Check the Application logs for details." & vbNewline
wscript.quit(1)
end if
end sub
'.............................................................................
Main
'.............................................................................
Auth4OpenVPN.ini
# Auth4OpenVPN.ini
# Jose Ortega,
# 2007.
# http://amigo4life.googlepages.com/openvpn
# All parameters must be set with quotation marks (" ").
#--------------------------------------------------------------------
# Server: Specifies the host name or IP address for the Active
# Directory server.
Server = "dc1.acme.local"
#--------------------------------------------------------------------
# Domain: Specifies the domain to be used when authenticating to
# access the Active Directory server.
Domain = "acme"
#--------------------------------------------------------------------
# DN: Specifies the distinguished name in Active Directory under
# which the user and group objects are located. (LDAP path).
DN = "CN=OpenVPN-Users,OU=Security Groups,OU=Groups,OU=acmeinc,DC=acme,DC=local"
#--------------------------------------------------------------------
# Group: Sets the security group in Active Directory to which
# users must be members to pass authentication.
Group = "OpenVPN-Users"
#--------------------------------------------------------------------
# When set to "ON" this setting will log successful user logins.
# Errors and Warnings are always logged. Use the Even Viewer in
# Windows to see the logs.
Logging = "On"