[Troubleshooting]Check the CN of the client certificate

Scripts which allow the use of special authentication methods (LDAP, AD, MySQL/PostgreSQL, etc).
Post Reply
voyage146
OpenVpn Newbie
Posts: 7
Joined: Tue May 20, 2014 7:27 am

[Troubleshooting]Check the CN of the client certificate

Post by voyage146 » Tue May 20, 2014 8:14 am

Hi everybody,
I want to execute the script that can check the common name of the client certificate and use the return code to authorize connection. But it failed, please help me troubleshooting this problems, thank you very much :geek:
OpenVPN Server
OS: Ubuntu 12.04.4 LTS (VMWare)
Brigde: eth0 (10.2.32.42), default gateway (10.2.32.1), dns (10.3.10.151)
OpenVPN 2.2.1 x86_64-linux-gnu [SSL] [LZO2] [EPOLL] [PKCS11] [eurephia] [MH] [PF_INET6] [IPv6 payload 20110424-2 (2.2RC2)] built on Mar 13 2014

Code: Select all

Server config
port 1198
proto tcp
dev tun
ca /etc/openvpn/CAChain.pem
cert /etc/openvpn/vpnserver.pem
key /etc/openvpn/vpnserver.pem 
dh /etc/openvpn/dh1024.pem
server 172.25.1.0 255.255.255.0
ifconfig-pool-persist ipp.txt
keepalive 10 120
tls-verify "/etc/openvpn/ovpnCNcheck.py /etc/openvpn/userlist.txt"
cipher AES-256-CBC   # AES
comp-lzo
max-clients 100
user nobody
group nogroup
persist-key
persist-tun
status openvpn-status.log
log        /etc/openvpn/openvpn.log
verb 7

Code: Select all

ovpnCNcheck.py
#!/usr/bin/env python

'''
    ovpnCNcheck -- an OpenVPN tls-verify script
    """""""""""""""""""""""""""""""""""""""""""
    
    This script checks if the peer is in the allowed
    user list by checking the CN (common name) of the 
    X509 certificate against a provided text file.
    
    For example in OpenVPN, you could use the directive
    (as one line):
    
    tls-verify "/usr/local/sbin/ovpnCNcheck.py
                /etc/openvpn/userlist.txt"

    This would cause the connection to be dropped unless
    the client common name is within the userlist.txt.
    Every line should hold one regular expression which
    can also be just one common name (don't forget to escape
    stuff like .?^()[]\ with a \).
    Empty or lines which start with a # are ignored.
    
    Written by Robert Penz <robert@penz.name> under the GPL 2
    Parts are copied from the verify-cn sample OpenVPN
    tls-verify script.
'''

# Version 0.1
# Initial Release


import sys
import re


def matchCommonName(userListFile, cn):
    """ reads the user list file and tries to match every regex """
    for rawLine in open(userListFile,"r").readlines():
        line = rawLine.strip().rstrip("\n")
        if not line or line[0] == "#":
            continue
        
        if re.compile(line).match(cn):
            return True
    return False

def main():
    # we only work with 3 parameters
    if len(sys.argv) != 4:
        print __doc__
        sys.exit(-1)

    # Parse out arguments:
    # userListFile -- Path of the file with the allowed users
    #                 taken from the argument to the tls-verify directive
    #                 in the OpenVPN config file.
    # depth        -- The current certificate chain depth.  In a typical
    #                 bi-level chain, the root certificate will be at level
    #                 1 and the client certificate will be at level 0.
    #                 This script will be called separately for each level.
    # x509         -- the X509 subject string as extracted by OpenVPN from
    #                 the client's provided certificate.
    (userListFile, depth, x509) = sys.argv[1:]

    if depth == "0":
        # If depth is zero, we know that this is the final
        # certificate in the chain (i.e. the client certificate),
        # and the one we are interested in examining.
        # If so, parse out the common name substring in
        # the X509 subject string.

        found = re.compile(r"/CN=(?P<cn>[^/]+)").search(x509)
        if found:
            # Accept the connection if the X509 common name
            # string matches a regex
            if matchCommonName(userListFile, found.group("cn")):
                sys.exit(0)
            
	# Authentication failed -- Either we could not parse
        # the X509 subject string, or the common name in the
        # subject string didn't match the user list regexes
        sys.exit(1)

    # If depth is nonzero, tell OpenVPN to continue processing
    # the certificate chain.
    sys.exit(0)

if __name__ == '__main__':
    main()

Code: Select all

userlist.txt
Aladin
OpenVPN client
OS: Win 7 ultimate 64b
OpenVpn: 2.3.1

Code: Select all

client config
client
dev tun
proto tcp
remote 10.2.32.42 1198
resolv-retry infinite
nobind
persist-key
persist-tun
ca "C:\\Program Files (x86)\\OpenVPN\\config\\CAChain.pem"
cipher AES-256-CBC
comp-lzo
verb 3
pkcs11-providers "C:\\Program Files (x86)\\Corporation\\CA Token Manager\\CA.dll"
pkcs11-id 'Securemetric\x20Technology\x20Sdn\x2EBhd\x2E/PKI\x20Token/0562573418200A12/CA\x20Token/33333634314539422D443336362D344434462D414530382D354339363137384330344435'
Log

Code: Select all

Client
Tue May 20 14:50:46 2014 OpenVPN 2.1.3 i686-pc-mingw32 [SSL] [LZO2] [PKCS11] bui
lt on Aug 20 2010
Tue May 20 14:50:46 2014 PKCS#11: Adding PKCS#11 provider 'C:\Program Files (x86
)\Bkav Corporation\BkavCA Token Manager\BkavCA.dll'
Tue May 20 14:50:47 2014 WARNING: No server certificate verification method has
been enabled.  See http://openvpn.net/howto.html#mitm for more info.
Tue May 20 14:50:47 2014 NOTE: OpenVPN 2.1 requires '--script-security 2' or hig
her to call user-defined scripts or executables
Tue May 20 14:50:48 2014 LZO compression initialized
Tue May 20 14:50:48 2014 Control Channel MTU parms [ L:1560 D:140 EF:40 EB:0 ET:
0 EL:0 ]
Tue May 20 14:50:48 2014 Socket Buffers: R=[8192->8192] S=[8192->8192]
Tue May 20 14:50:48 2014 Data Channel MTU parms [ L:1560 D:1450 EF:60 EB:135 ET:
0 EL:0 AF:3/1 ]
Tue May 20 14:50:48 2014 Local Options hash (VER=V4): '958c5492'
Tue May 20 14:50:48 2014 Expected Remote Options hash (VER=V4): '79ef4284'
Tue May 20 14:50:48 2014 Attempting to establish TCP connection with 10.2.32.42:
1198
Tue May 20 14:50:48 2014 TCP connection established with 10.2.32.42:1198
Tue May 20 14:50:48 2014 TCPv4_CLIENT link local: [undef]
Tue May 20 14:50:48 2014 TCPv4_CLIENT link remote: 10.2.32.42:1198
Tue May 20 14:50:48 2014 TLS: Initial packet from 10.2.32.42:1198, sid=4060630e
947b4ef5
Tue May 20 14:50:48 2014 VERIFY OK: depth=2, /C=VN/O=Ministry_of_Information_and
_Communications/OU=National_CA_Center/CN=MIC_National_Root_CA
Tue May 20 14:50:48 2014 VERIFY OK: depth=1, /C=VN/L=HN/O=Corporation/CN
=CA
Tue May 20 14:50:48 2014 VERIFY OK: depth=0, /UID=MST:0101360697-OpenVPN_Server/
CN=OpenVPN_Server/O=Corporation/ST=H_xC3_xA0_N_xE1_xBB_x99i/C=VN
Enter BkavCA Token token Password:
Tue May 20 14:51:03 2014 Connection reset, restarting [-1]
Tue May 20 14:51:03 2014 TCP/UDP: Closing socket
Tue May 20 14:51:03 2014 SIGUSR1[soft,connection-reset] received, process restar
ting
Tue May 20 14:51:03 2014 Restart pause, 5 second(s)

Code: Select all

Server
Tue May 20 01:09:28 2014 us=828195 OpenVPN 2.2.1 x86_64-linux-gnu [SSL] [LZO2] [EPOLL] [PKCS11] [eurephia] [MH] [PF_INET6] [IPv6 payload 20110424-2 (2.2RC2)] built on Mar 13 2014
Tue May 20 01:09:28 2014 us=828434 NOTE: the current --script-security setting may allow this configuration to call user-defined scripts
Tue May 20 01:09:28 2014 us=830300 Diffie-Hellman initialized with 1024 bit key
Tue May 20 01:09:28 2014 us=830707 WARNING: file '/etc/openvpn/vpnserver.pem' is group or others accessible
Tue May 20 01:09:28 2014 us=831579 TLS-Auth MTU parms [ L:1560 D:140 EF:40 EB:0 ET:0 EL:0 ]
Tue May 20 01:09:28 2014 us=831628 Socket Buffers: R=[87380->131072] S=[16384->131072]
Tue May 20 01:09:28 2014 us=831812 ROUTE default_gateway=10.2.32.1
Tue May 20 01:09:28 2014 us=839840 TUN/TAP device tun0 opened
Tue May 20 01:09:28 2014 us=839892 TUN/TAP TX queue length set to 100
Tue May 20 01:09:28 2014 us=839922 do_ifconfig, tt->ipv6=0, tt->did_ifconfig_ipv6_setup=0
Tue May 20 01:09:28 2014 us=839960 /sbin/ifconfig tun0 172.25.1.1 pointopoint 172.25.1.2 mtu 1500
Tue May 20 01:09:28 2014 us=841672 /sbin/route add -net 172.25.1.0 netmask 255.255.255.0 gw 172.25.1.2
Tue May 20 01:09:28 2014 us=842763 Data Channel MTU parms [ L:1560 D:1450 EF:60 EB:135 ET:0 EL:0 AF:3/1 ]
Tue May 20 01:09:28 2014 us=845948 GID set to nogroup
Tue May 20 01:09:28 2014 us=846095 UID set to nobody
Tue May 20 01:09:28 2014 us=846124 Listening for incoming TCP connection on [undef]
Tue May 20 01:09:28 2014 us=846152 TCPv4_SERVER link local (bound): [undef]
Tue May 20 01:09:28 2014 us=846164 TCPv4_SERVER link remote: [undef]
Tue May 20 01:09:28 2014 us=846197 MULTI: multi_init called, r=256 v=256
Tue May 20 01:09:28 2014 us=846294 IFCONFIG POOL: base=172.25.1.4 size=62, ipv6=0
Tue May 20 01:09:28 2014 us=846311 ifconfig_pool_read(), in='cloud,172.25.0.2', TODO: IPv6
Tue May 20 01:09:28 2014 us=846337 succeeded -> ifconfig_pool_set()
Tue May 20 01:09:28 2014 us=846346 IFCONFIG POOL LIST
Tue May 20 01:09:28 2014 us=846390 MULTI: TCP INIT maxclients=100 maxevents=104
Tue May 20 01:09:28 2014 us=846418 Initialization Sequence Completed
Tue May 20 01:09:35 2014 us=276597 MULTI: multi_create_instance called
Tue May 20 01:09:35 2014 us=276671 Re-using SSL/TLS context
Tue May 20 01:09:35 2014 us=276733 LZO compression initialized
Tue May 20 01:09:35 2014 us=277067 Control Channel MTU parms [ L:1560 D:140 EF:40 EB:0 ET:0 EL:0 ]
Tue May 20 01:09:35 2014 us=277127 Data Channel MTU parms [ L:1560 D:1450 EF:60 EB:135 ET:0 EL:0 AF:3/1 ]
Tue May 20 01:09:35 2014 us=277178 Local Options String: 'V4,dev-type tun,link-mtu 1560,tun-mtu 1500,proto TCPv4_SERVER,comp-lzo,cipher AES-256-CBC,auth SHA1,keysize 256,key-method 2,tls-server'
Tue May 20 01:09:35 2014 us=277211 Expected Remote Options String: 'V4,dev-type tun,link-mtu 1560,tun-mtu 1500,proto TCPv4_CLIENT,comp-lzo,cipher AES-256-CBC,auth SHA1,keysize 256,key-method 2,tls-client'
Tue May 20 01:09:35 2014 us=277266 Local Options hash (VER=V4): '79ef4284'
Tue May 20 01:09:35 2014 us=277353 Expected Remote Options hash (VER=V4): '958c5492'
Tue May 20 01:09:35 2014 us=277453 TCP connection established with [AF_INET]10.2.32.189:51675
Tue May 20 01:09:35 2014 us=277478 TCPv4_SERVER link local: [undef]
Tue May 20 01:09:35 2014 us=277487 TCPv4_SERVER link remote: [AF_INET]10.2.32.189:51675
RTue May 20 01:09:35 2014 us=286485 10.2.32.189:51675 TLS: Initial packet from [AF_INET]10.2.32.189:51675, sid=b626c8b6 755626a5
WRRWWWWRWRWRWWRWRWRWRWRWRWRWRWRWRWRWRWRWRWRWRWRWRWRWRWRWRWRWRWRWRWRWRWRWRWRWRRRWWRWRWRWRWRRRWRWRWRWRWRWRWRWRWRWRWRWRWRWRWRWRWRWRWRWRWRWRWRWRWRWRWRTue May 20 01:09:45 2014 us=821758 10.2.32.189:51675 WARNING: Failed running command (--tls-verify script): could not execute external program
Tue May 20 01:09:45 2014 us=821959 10.2.32.189:51675 VERIFY SCRIPT ERROR: depth=2, /C=VN/O=Ministry_of_Information_and_Communications/OU=National_CA_Center/CN=MIC_National_Root_CA
Tue May 20 01:09:45 2014 us=822183 10.2.32.189:51675 TLS_ERROR: BIO read tls_read_plaintext error: error:140890B2:SSL routines:SSL3_GET_CLIENT_CERTIFICATE:no certificate returned
Tue May 20 01:09:45 2014 us=822206 10.2.32.189:51675 TLS Error: TLS object -> incoming plaintext read error
Tue May 20 01:09:45 2014 us=822220 10.2.32.189:51675 TLS Error: TLS handshake failed
Tue May 20 01:09:45 2014 us=822368 10.2.32.189:51675 Fatal TLS error (check_tls_errors_co), restarting
Tue May 20 01:09:45 2014 us=822399 10.2.32.189:51675 SIGUSR1[soft,tls-error] received, client-instance restarting
Tue May 20 01:09:45 2014 us=822500 TCP/UDP: Closing socket

voyage146
OpenVpn Newbie
Posts: 7
Joined: Tue May 20, 2014 7:27 am

Re: [Troubleshooting]Check the CN of the client certificate

Post by voyage146 » Tue May 20, 2014 8:30 am

But if i remove this line "tls-verify "/usr/local/sbin/ovpnCNcheck.py /etc/openvpn/userlist.txt" then it works normally

voyage146
OpenVpn Newbie
Posts: 7
Joined: Tue May 20, 2014 7:27 am

Re: [Troubleshooting]Check the CN of the client certificate

Post by voyage146 » Thu May 22, 2014 4:15 am

Any one help me? :?:

santh12345
OpenVpn Newbie
Posts: 2
Joined: Wed Jul 02, 2014 3:48 pm

Re: [Troubleshooting]Check the CN of the client certificate

Post by santh12345 » Wed Jul 02, 2014 3:56 pm

It can be done vary easily. follow the procedure below
1) create a list of allowd common names and put it in /etc/openvpn/cn-list
2) write a shall script and mention its name in server.conf auth-user-cn-verify /etc/openvpn/script.sh via-file
3) in the shell script use grep "$common-name" /etc/openvpn/cn-list
if exist return 0 else return 1
Since the $common_name contains the common name of the client who is tring to connect to the server it will have the CN value mentioned in the certificate

Post Reply