Discussion:
[Openvpn-users] username-as-common-name not setting username as common_name for plugin
Michael Hicks
2016-08-03 21:35:46 UTC
Permalink
Greetings OpenVPN users,

I’m having some trouble with openvpn using an auth plugin for DuoSecurity MFA.
https://github.com/duosecurity/duo_openvpn

server side
OpenVPN 2.3.6 x86_64-sun-solaris2.11 [SSL (OpenSSL)] [LZO] [IPv6] built on Dec 5 2015
library versions: OpenSSL 1.0.2e 3 Dec 2015, LZO 2.09

client side:
OpenVPN 2.3.6 x86_64-apple-darwin13 [SSL (OpenSSL)] [LZO] [MH] [IPv6] built on Jun 17 2016
library versions: OpenSSL 1.0.2h 3 May 2016, LZO 2.09

I generated certificates using EasyRSA 3.0.1 and can see what the CN is set to
openssl x509 -text -noout -in EasyRSA-3.0.1/pki/issued/triskaideka.crt
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 1 (0x1)
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN=foobiebletch
Validity
Not Before: Jul 28 19:35:34 2016 GMT
Not After : Jul 26 19:35:34 2026 GMT
Subject: CN=triskaideka
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:

On the client side I’m supplying my username and pass via the auth-user-pass parameter with a file.

On the server side I’m trying to use username-as-common-name so that the client supplied username parameter is used to auth against Duo instead of the cert CN.

What seems to be happening is that OpenVPN is not setting the username as the common_name parameter. With logging verbosity set to 7 I see this in the openvpn.log file demonstrating that the common_name is set to the connecting client’s hostname, and that it clearly also knows what the username is.

Wed Aug 3 20:37:41 2016 us=607548 192.168.42.155:1194 ARGV[0] = '/opt/duo/duo_openvpn.so'
Wed Aug 3 20:37:41 2016 us=607569 192.168.42.155:1194 ENVP[0] = 'auth_control_file=/opt/local/etc/openvpn/tmp/openvpn_acf_a193b796224f01379455de68f7864bc5.tmp'
Wed Aug 3 20:37:41 2016 us=607584 192.168.42.155:1194 ENVP[1] = 'untrusted_port=1194'
Wed Aug 3 20:37:41 2016 us=607598 192.168.42.155:1194 ENVP[2] = 'untrusted_ip=192.168.42.155'
Wed Aug 3 20:37:41 2016 us=607623 192.168.42.155:1194 ENVP[3] = 'common_name=triskaideka'
Wed Aug 3 20:37:41 2016 us=607638 192.168.42.155:1194 ENVP[5] = 'username=mhicks'
Wed Aug 3 20:37:41 2016 us=607652 192.168.42.155:1194 ENVP[6] = 'tls_serial_hex_0=01'
Wed Aug 3 20:37:41 2016 us=607666 192.168.42.155:1194 ENVP[7] = 'tls_serial_0=1'
Wed Aug 3 20:37:41 2016 us=607679 192.168.42.155:1194 ENVP[8] = 'tls_digest_0=68:51:76:e9:77:b6:66:59:55:73:c6:ca:97:9a:80:20:59:eb:90:f6'
Wed Aug 3 20:37:41 2016 us=607694 192.168.42.155:1194 ENVP[9] = 'tls_id_0=CN=triskaideka'
Wed Aug 3 20:37:41 2016 us=607708 192.168.42.155:1194 ENVP[10] = 'X509_0_CN=triskaideka'
Wed Aug 3 20:37:41 2016 us=607722 192.168.42.155:1194 ENVP[11] = 'tls_serial_hex_1=e5:3c:22:2e:4b:e6:a1:50'
Wed Aug 3 20:37:41 2016 us=607736 192.168.42.155:1194 ENVP[12] = 'tls_serial_1=16518115115525382480'
Wed Aug 3 20:37:41 2016 us=607750 192.168.42.155:1194 ENVP[13] = 'tls_digest_1=02:23:c8:e6:b2:3d:48:a8:d7:0a:92:26:31:72:ee:e9:e3:17:79:6c'
Wed Aug 3 20:37:41 2016 us=607764 192.168.42.155:1194 ENVP[14] = 'tls_id_1=CN=foobiebletch'
Wed Aug 3 20:37:41 2016 us=607778 192.168.42.155:1194 ENVP[15] = 'X509_1_CN=foobiebletch'
Wed Aug 3 20:37:41 2016 us=607792 192.168.42.155:1194 ENVP[16] = 'remote_port_1=1194'
Wed Aug 3 20:37:41 2016 us=607806 192.168.42.155:1194 ENVP[17] = 'local_port_1=1194'
Wed Aug 3 20:37:41 2016 us=607820 192.168.42.155:1194 ENVP[18] = 'local_1=192.168.40.25'
Wed Aug 3 20:37:41 2016 us=607834 192.168.42.155:1194 ENVP[19] = 'proto_1=udp'
Wed Aug 3 20:37:41 2016 us=607848 192.168.42.155:1194 ENVP[20] = 'daemon_pid=90029'
Wed Aug 3 20:37:41 2016 us=607862 192.168.42.155:1194 ENVP[21] = 'daemon_start_time=1470256354'
Wed Aug 3 20:37:41 2016 us=607876 192.168.42.155:1194 ENVP[22] = 'daemon_log_redirect=1'
Wed Aug 3 20:37:41 2016 us=607889 192.168.42.155:1194 ENVP[23] = 'daemon=0'
Wed Aug 3 20:37:41 2016 us=607904 192.168.42.155:1194 ENVP[24] = 'verb=7'
Wed Aug 3 20:37:41 2016 us=607918 192.168.42.155:1194 ENVP[25] = 'config=/opt/local/etc/openvpn/openvpn.conf'
Wed Aug 3 20:37:41 2016 us=607932 192.168.42.155:1194 ENVP[26] = 'ifconfig_local=10.43.43.1'
Wed Aug 3 20:37:41 2016 us=607946 192.168.42.155:1194 ENVP[27] = 'ifconfig_remote=10.43.43.2'
Wed Aug 3 20:37:41 2016 us=607960 192.168.42.155:1194 ENVP[28] = 'route_vpn_gateway=10.43.43.2'
Wed Aug 3 20:37:41 2016 us=607974 192.168.42.155:1194 ENVP[29] = 'route_network_1=10.43.43.0'
Wed Aug 3 20:37:41 2016 us=607987 192.168.42.155:1194 ENVP[30] = 'route_netmask_1=255.255.255.0'
Wed Aug 3 20:37:41 2016 us=608001 192.168.42.155:1194 ENVP[31] = 'route_gateway_1=10.43.43.2'
Wed Aug 3 20:37:41 2016 us=608015 192.168.42.155:1194 ENVP[32] = 'script_context=init'
Wed Aug 3 20:37:41 2016 us=608029 192.168.42.155:1194 ENVP[33] = 'tun_mtu=1500'
Wed Aug 3 20:37:41 2016 us=608043 192.168.42.155:1194 ENVP[34] = 'link_mtu=1542'
Wed Aug 3 20:37:41 2016 us=608057 192.168.42.155:1194 ENVP[35] = 'dev=tun0'
Wed Aug 3 20:37:41 2016 us=608071 192.168.42.155:1194 ENVP[36] = 'dev_type=tun'
Wed Aug 3 20:37:41 2016 us=608085 192.168.42.155:1194 ENVP[37] = 'redirect_gateway=0'
Wed Aug 3 20:37:41 2016 us=610105 192.168.42.155:1194 PLUGIN_CALL: POST /opt/duo/duo_openvpn.so/PLUGIN_AUTH_USER_PASS_VERIFY status=2

the duo plugin is clearly expecting the common_name parameter
https://github.com/duosecurity/duo_openvpn/blob/master/duo_openvpn.c#L56




Since the documentation specifies:
--username-as-common-name
For --auth-user-pass-verify authentication, use the authenticated username as the common name, rather than the common name from the client cert.just for a sa

for a sanity check I commented out my plugin line, and added a line for an auth-user-pass-verify script
auth-user-pass-verify /opt/local/etc/openvpn/envprinter via-env

that just prints the two variables in question and returns 0 like:
--------
#!/usr/bin/bash


echo "common name is: ${common_name}"
echo "username is: ${username}"
exit 0
————

and what this shows in the openvpn log is indeed that:
common name is: triskaideka
username is: mhicks
Wed Aug 3 21:17:33 2016 us=160213 192.168.42.155:1194 TLS: Username/Password authentication succeeded for username 'mhicks' [CN SET]


So the username-as-common-name parameter isn’t being honored for some reason.

I cross validated that it wasn’t just my client by using the bundled openvpn that comes with the Viscosity client I also use with similar results.


The origin of the server side openvpn binary is from the pkgsrc distribution for SmartOS and has a few patches but none of them seem to be anything to do with the options parsing or the TLS flags, username, or common_name handling.

https://github.com/joyent/pkgsrc/tree/trunk/net/openvpn

I’m happy to file this as a bug, but I figured I’d try the mailing list first in case there was something anyone knew about this behavior already or had some troubleshooting ideas.

Thanks,

Mike




------------------------------------------------------------------------------
Selva Nair
2016-08-04 05:05:39 UTC
Permalink
Post by Michael Hicks
Greetings OpenVPN users,
I’m having some trouble with openvpn using an auth plugin for DuoSecurity
MFA.
https://github.com/duosecurity/duo_openvpn
server side
OpenVPN 2.3.6 x86_64-sun-solaris2.11 [SSL (OpenSSL)] [LZO] [IPv6] built on Dec 5 2015
library versions: OpenSSL 1.0.2e 3 Dec 2015, LZO 2.09
OpenVPN 2.3.6 x86_64-apple-darwin13 [SSL (OpenSSL)] [LZO] [MH] [IPv6] built on Jun 17 2016
library versions: OpenSSL 1.0.2h 3 May 2016, LZO 2.09
I generated certificates using EasyRSA 3.0.1 and can see what the CN is set to
openssl x509 -text -noout -in EasyRSA-3.0.1/pki/issued/triskaideka.crt
Version: 3 (0x2)
Serial Number: 1 (0x1)
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN=foobiebletch
Validity
Not Before: Jul 28 19:35:34 2016 GMT
Not After : Jul 26 19:35:34 2026 GMT
Subject: CN=triskaideka
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
On the client side I’m supplying my username and pass via the
auth-user-pass parameter with a file.
On the server side I’m trying to use username-as-common-name so that the
client supplied username parameter is used to auth against Duo instead of
the cert CN.
What seems to be happening is that OpenVPN is not setting the username as
the common_name parameter. With logging verbosity set to 7 I see this in
the openvpn.log file demonstrating that the common_name is set to the
connecting client’s hostname, and that it clearly also knows what the
username is.
--username-as-common-name option does not change the common-name until
authenticated. So the duo plugin will see your common-name in the
certificate. I have no idea why duo decided to take the username from cert
CN instead of from the response to auth-user-pass.dialog.

Selva
Michael Hicks
2016-08-04 15:50:19 UTC
Permalink
Hmm, thats interesting. I guess maybe I’ve just been thrown off by the wording of the docs at
https://community.openvpn.net/openvpn/wiki/Openvpn23ManPage

------------------------------------------------------------------------
--username-as-common-name
For --auth-user-pass-verify authentication, use the authenticated username as the common name, rather than the common name from the client cert.
------------------------------------------------------------------------

The description is confusing at this point. "For --auth-user-pass-verify authentication” would make me think that the username as the common_name is usable “For” an auth-user-pass-verify script, which I demonstrated it is not and you are agreeing that it is not for that. Clearly the "auth-user-pass-verify” section states that "The script should examine the username and password” and says nothing about the common_name parameter and when it says "use the authenticated username as the common name” this would make me think it behaves as you say that the user needs to be already “authenticated” rather than it just having been a supplied by the client username and that it still needs to be authenticated. The “For” just threw me off.

I would guess that the "username-as-common-name” is here for use in "client-connect” (and disconnect) commands since the wording in that section states "The command is passed the common name and IP address of the just-authenticated client as environmental variables” and for the “client-config-dir” related options which would allow openvpn to use files and things that are keyed off the username rather than the common_name.

I guess I’ll submit a documentation bug to alter the description in the docs for "username-as-common-name” to more clearly illustrate this. Maybe just changing "For --auth-user-pass-verify authentication...” to "After --auth-user-pass-verify authentication
” and a note about this affecting the client-(dis)connect and client-config-dir options.

I modified the duo plugin source to use username instead of common_name and it works as I expect. I’ll also submit a pull request against the duo_openvpn plugin source to get that changed upstream and see where it goes.

Thanks for the reply,

Mike
Post by Michael Hicks
Greetings OpenVPN users,
I’m having some trouble with openvpn using an auth plugin for DuoSecurity MFA.
https://github.com/duosecurity/duo_openvpn <https://github.com/duosecurity/duo_openvpn>
server side
OpenVPN 2.3.6 x86_64-sun-solaris2.11 [SSL (OpenSSL)] [LZO] [IPv6] built on Dec 5 2015
library versions: OpenSSL 1.0.2e 3 Dec 2015, LZO 2.09
OpenVPN 2.3.6 x86_64-apple-darwin13 [SSL (OpenSSL)] [LZO] [MH] [IPv6] built on Jun 17 2016
library versions: OpenSSL 1.0.2h 3 May 2016, LZO 2.09
I generated certificates using EasyRSA 3.0.1 and can see what the CN is set to
openssl x509 -text -noout -in EasyRSA-3.0.1/pki/issued/triskaideka.crt
Version: 3 (0x2)
Serial Number: 1 (0x1)
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN=foobiebletch
Validity
Not Before: Jul 28 19:35:34 2016 GMT
Not After : Jul 26 19:35:34 2026 GMT
Subject: CN=triskaideka
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
On the client side I’m supplying my username and pass via the auth-user-pass parameter with a file.
On the server side I’m trying to use username-as-common-name so that the client supplied username parameter is used to auth against Duo instead of the cert CN.
What seems to be happening is that OpenVPN is not setting the username as the common_name parameter. With logging verbosity set to 7 I see this in the openvpn.log file demonstrating that the common_name is set to the connecting client’s hostname, and that it clearly also knows what the username is.
--username-as-common-name option does not change the common-name until authenticated. So the duo plugin will see your common-name in the certificate. I have no idea why duo decided to take the username from cert CN instead of from the response to auth-user-pass.dialog.
Selva
Selva Nair
2016-08-04 16:42:17 UTC
Permalink
Post by Michael Hicks
I guess I’ll submit a documentation bug to alter the description in the
docs for "username-as-common-name” to more clearly illustrate this. Maybe
just changing "For --auth-user-pass-verify authentication...” to
"After --auth-user-pass-verify authentication
” and a note about this
affecting the client-(dis)connect and client-config-dir options.
Yes the documentation is poorly worded and could be improved. I think the
reference to auth-user-pass-verify itself is confusing as one could instead
use management-client-auth to authenticate users. A description that says
this option replaces the common-name by the "authenticated username"
without any reference to auth-user-pass-verify may be better. As you wrote,
clarifying that this affects ccd etc. is also useful.
Post by Michael Hicks
I modified the duo plugin source to use username instead of common_name
and it works as I expect. I’ll also submit a pull request against the
duo_openvpn plugin source to get that changed upstream and see where it
goes.
More likely to get accepted if you make that configurable --- say adding an
optional arg to the plugin to indicate username should be taken from
getenv("username",..) instead of getenv("common-name",..) so that existing
use cases are not affected. That said, I think that plugin could be further
improved using the static challenge feature openvpn so that the usual
username/password auth can work along with Duo.

Selva
Joe Patterson
2016-08-04 17:31:26 UTC
Permalink
Let me second the suggestion to make it configurable. I don't know much
about duo, but ages ago I modified the PAM plugin to be able to do the
opposite: use the common name as the username for PAM. The reason being,
that without something to tie usernames to common names, an attacker only
needs to know/steal/guess any valid username/password and any valid
certificate, which should be harder to do than knowing/stealing/guessing a
*particular* user's password.

-Joe
Post by Selva Nair
Post by Michael Hicks
I guess I’ll submit a documentation bug to alter the description in the
docs for "username-as-common-name” to more clearly illustrate this. Maybe
just changing "For --auth-user-pass-verify authentication...” to
"After --auth-user-pass-verify authentication
” and a note about this
affecting the client-(dis)connect and client-config-dir options.
Yes the documentation is poorly worded and could be improved. I think the
reference to auth-user-pass-verify itself is confusing as one could instead
use management-client-auth to authenticate users. A description that says
this option replaces the common-name by the "authenticated username"
without any reference to auth-user-pass-verify may be better. As you wrote,
clarifying that this affects ccd etc. is also useful.
Post by Michael Hicks
I modified the duo plugin source to use username instead of common_name
and it works as I expect. I’ll also submit a pull request against the
duo_openvpn plugin source to get that changed upstream and see where it
goes.
More likely to get accepted if you make that configurable --- say adding
an optional arg to the plugin to indicate username should be taken from
getenv("username",..) instead of getenv("common-name",..) so that existing
use cases are not affected. That said, I think that plugin could be further
improved using the static challenge feature openvpn so that the usual
username/password auth can work along with Duo.
Selva
------------------------------------------------------------------------------
_______________________________________________
Openvpn-users mailing list
https://lists.sourceforge.net/lists/listinfo/openvpn-users
Michael Hicks
2016-08-04 18:13:20 UTC
Permalink
Agreed, and there are probably other reasons it is set to common_name such as using the duo plugin for MFA when you are not using user/password as an authentication mechanism and need to use common_name as a username with duo
Let me second the suggestion to make it configurable. I don't know much about duo, but ages ago I modified the PAM plugin to be able to do the opposite: use the common name as the username for PAM. The reason being, that without something to tie usernames to common names, an attacker only needs to know/steal/guess any valid username/password and any valid certificate, which should be harder to do than knowing/stealing/guessing a *particular* user's password.
-Joe
I guess I’ll submit a documentation bug to alter the description in the docs for "username-as-common-name” to more clearly illustrate this. Maybe just changing "For --auth-user-pass-verify authentication...” to "After --auth-user-pass-verify authentication
” and a note about this affecting the client-(dis)connect and client-config-dir options.
Yes the documentation is poorly worded and could be improved. I think the reference to auth-user-pass-verify itself is confusing as one could instead use management-client-auth to authenticate users. A description that says this option replaces the common-name by the "authenticated username" without any reference to auth-user-pass-verify may be better. As you wrote, clarifying that this affects ccd etc. is also useful.
I modified the duo plugin source to use username instead of common_name and it works as I expect. I’ll also submit a pull request against the duo_openvpn plugin source to get that changed upstream and see where it goes.
More likely to get accepted if you make that configurable --- say adding an optional arg to the plugin to indicate username should be taken from getenv("username",..) instead of getenv("common-name",..) so that existing use cases are not affected. That said, I think that plugin could be further improved using the static challenge feature openvpn so that the usual username/password auth can work along with Duo.
Selva
------------------------------------------------------------------------------
_______________________________________________
Openvpn-users mailing list
https://lists.sourceforge.net/lists/listinfo/openvpn-users <https://lists.sourceforge.net/lists/listinfo/openvpn-users>
------------------------------------------------------------------------------
_______________________________________________
Openvpn-users mailing list
https://lists.sourceforge.net/lists/listinfo/openvpn-users
Continue reading on narkive:
Loading...