Reset expired password not working

I’ve been reading docs and I reconfigured Duo to use ldaps instead of radius for Fortigate auth in hopes of getting expired password change functionality working. Here’s the duo config:

[main]
debug=false
log_auth_events=true

[ad_client]
host=dc01.mydomain.local
host_2=dc02.mydomain.local
service_account_username=svcLDAP
service_account_password=<password>
search_dn=DC=mydomain,DC=local
security_group_dn=CN=VPN_Users,OU=Security Groups,DC=mydomain,DC=local
ldap_filter=(|(memberOf=CN=VPN_Users,OU=Security Groups,DC=mydomain,DC=local))
transport=ldaps
ssl_ca_certs_file=conf/ssl/MYDOMAIN-LDAPS-CA.pem

[ldap_server_auto]
ikey=<ikey>
skey=<skey>
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
client=ad_client
failmode=secure
ssl_port=636
ssl_key_path=ssl/cerberus.key
ssl_cert_path=ssl/cerberus.pem

Everything is working as expected via Fortigate, both ssl vpn auth and testing auth at the command line using “diagnose test authserver ldap Duo <username> <password>” However, when testing using a user with an expired or forced changed password I get a failed message. The same expired password tests for an AD configured ldap in Fortigate work.

Relevant fortigate config is:

    edit "Duo"
        set server "cerberus"
        set cnid "sAMAccountName"
        set dn "dc=mydomain,dc=local"
        set type regular
        set username "mydomain\\svcldap"
        set password ENC <enc-password>
        set secure ldaps
        set ca-cert "CA_Cert_3"
        set port 636
        set password-expiry-warning enable
        set password-renewal enable
    next

What am I missing?

I missed the radius_server_auto section of the config, here’s the whole thing:

avery@cerberus:/opt/duoauthproxy/conf$ cat authproxy.cfg
; Complete documentation about the Duo Auth Proxy can be found here:
; https://duo.com/docs/authproxy_reference

[main]
debug=false
log_auth_events=true


[ad_client]
host=dc01.domain.local
host_2=dc02.domain.local
service_account_username=svcLDAP
service_account_password=<password>
search_dn=DC=domain,DC=local
security_group_dn=CN=VPN_Users,OU=Security Groups,DC=domain,DC=local
ldap_filter=(|(memberOf=CN=VPN_Users,OU=Security Groups,DC=domain,DC=local))
transport=ldaps
ssl_ca_certs_file=conf/ssl/LDAPS-CA.pem
auth_type=ntlm2

[ldap_server_auto]
ikey=<ikey>
skey=<skey>
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
client=ad_client
failmode=secure
ssl_port=636
ssl_key_path=ssl/cerberus.key
ssl_cert_path=ssl/cerberus.pem


[radius_server_auto]
radius_ip_1=10.1.1.2
radius_secret_1=<secret>
ikey=<ikey>
skey=<skey>
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
client=ad_client
failmode=secure
#failmode=safe

I am not sure the diagnose test would work due to the way the Duo proxy actually proxies incoming authentication requests (where it expects a bind as service account > search for user > bind as user LDAP operation sequence)

Did you try an actual VPN client auth where the user’s password is expired?

You should also enable debug logging on the Duo proxy and look at the log output during the expired password auth to see what is happening.

Hi, thanks for the reply. The VPN client auth fails as well with “Error: permission denied” on the web interface and “Login failed. Insufficient credential(s). Please check the password, client certificate, etc.” on the FortiClient.

In debug mode the log contains this:

2022-01-12T17:51:47.932314-0600 [_ADAuthClientProtocol (TLSMemoryBIOProtocol),client] C<-S LDAPMessage(id=127, value=LDAPBindResponse(resultCode=49, errorMessage='8009030C: LdapErr: DSID-0C090590, comment: AcceptSecurityContext error, data 773, v2580\x00'), controls=None)
2022-01-12T17:51:47.932675-0600 [duoauthproxy.lib.log#info] LDAP Authentication Failed: 'invalidCredentials: 8009030C: LdapErr: DSID-0C090590, comment: AcceptSecurityContext error, data 773, v2580\x00'
2022-01-12T17:51:47.932919-0600 [_ADAuthClientProtocol (TLSMemoryBIOProtocol),client] C->S LDAPMessage(id=128, value=LDAPUnbindRequest(), controls=None)
2022-01-12T17:51:47.933363-0600 [duoauthproxy.lib.log#info] (('10.1.1.2', 11227), testuser, 87): Primary credentials rejected - User Authentication Failed
2022-01-12T17:51:47.933792-0600 [duoauthproxy.lib.log#info] (('10.1.1.2', 11227), testuser, 87): Returning response code 3: AccessReject
2022-01-12T17:51:47.934037-0600 [duoauthproxy.lib.log#info] (('10.1.1.2', 11227), testuser, 87): Sending response

That looks like it’s getting the correct response, the “data 773” code means the password needs to be changed according to https://ldapwiki.com/wiki/Common%20Active%20Directory%20Bind%20Errors Incidentally I get the same response on the fortigate when running in debug mode:

[1010] fnbamd_ldap_parse_response-Error 49(80090308: LdapErr: DSID-0C09044E, comment: AcceptSecurityContext error, data 773, v2580)
[1023] fnbamd_ldap_parse_response-ret=49
[1720] fnband_ldap_run_password_policy_sm-Prompt user to renew expired password.

Edit: I should have mentioned that the fortigate log message when when running the “ diagnose test authserver ldap Duo <username> <password> ” in debug mode.

Hmm, OK. After the 773 response there should be another bind followed by an LDAPModifyRequest to reset the password. You don’t see anything like that in the log?

Does the Fortigate perform password reset as a service account on behalf of the user, or as the user? If as the service account, does the service account used have right to change passwords delegated in AD?

Did you import the CA issuer cert for the cerberus.pem certificate into the Fortigate for the Duo proxy as LDAPS server (I think this had to be done or incoming LDAPS would fail entirely but asking anyway). Out of curiosity did the same CA issue both the cerberus.pem cert and whatever cert your DC uses for SSL (LDAPS-CA.pem)?

Is it known for sure that the Fortigate can do pwreset against non-AD LDAP servers? All the examples I am finding on their site keep referencing AD. Are there any tracebacks in the Duo proxy log that mention an invalid tag?

ETA in this article for Fortigate with LDAP it mentions the need to enforce 2FA for primary binds because that is how the Fortigate does the auths. Have you tried it?

You might need to open a Duo support case to get direct help.

1 Like

Thanks for the pointer to https://help.duo.com/s/article/3162?language=en_US :pray: Adding exempt_ou_1=<bind user DN> and exempt_primary_bind=false to the config made everything work.

1 Like