Forum Discussion

Ray_371608's avatar
Ray_371608
Icon for Nimbostratus rankNimbostratus
Feb 05, 2019

Trying to do authentication with LDAP from iRule, not working

I'm trying to do some fairly simple authentication (basic auth to an ldap) for inbound traffic in an iRule and I'm having problems. At this point I'm pretty sure it's something I'm not doing right or that I don't have configured yet. I have tried with my own iRule, that didn't work. Then I tried using the sample ldap iRule provided with the F5, and that is behaving the same way. What they are both doing is, "not calling the LDAP server". Which in my case is OpenLDAP (slapd) on CentOS. When I tail my logs on the LDAP server it never shows a connection attempt from the F5 when I send a test message to the virtual server with the iRule. I can, however, run an ldapsearch from the command line on the F5 and get back a results. To my way of thinking, this eliminates network connectivity as an issues. There are no hints of errors in any of the logs on the F5. I have iRule logging set to Debug.

 

What I'm left with is something isn't either isn't configured or isn't configured properly in the F5.

 

Here is what I have configured:

 

1) Local Traffic > Profiles > Authentication > CRLDP Server:

 

  • IP of my LDAP

     

  • Port: 389

     

  • BaseDN: dc=mydomain,dc=local (I'm not sure if I need ou=People here or not, I have tried it both ways though)

     

2) Local Traffic > Profiles > Authentication > Configuration:

 

  • points to the CRLDP Server above

3) Local Traffic > Profiles > Authentication > Profile:

 

  • points to the Configuration above

4) Local Traffic > Virtual Servers > Auth-Test-VIP:

 

  • Under Advanced config the "Authentication Profiles" contains the profile above.

I'm using a lot of "log local0" statements and it steps right through the AUTH:authenticate step but nothing shows up, good, bad, or otherwise, in the LDAP logs. But the iRule and logs are too big to post here.

 

2 Replies

  • The iRule:
    when CLIENT_ACCEPTED {
                     Generate a timestamp for the log message below
                    set myIntTime [clock format [clock seconds] -format "%Y-%m-%d_%H:%M:%S %z"]
                    log local0. " ==================== BEGIN ========= $myIntTime =========== "
    }
    
    when HTTP_REQUEST {
                    log local0. " BEGIN ========= HTTP_REQUEST"
                    log local0. " === Auth Step 1"
                    if {not [info exists tmm_auth_http_sids(ldap)]} {
                                    log local0. " === Auth Step 2"
                                    set tmm_auth_sid [AUTH::start pam default_ldap]
                                    log local0. " tmm_auth_sid : $tmm_auth_sid"
                                    set tmm_auth_http_sids(ldap) $tmm_auth_sid
                                    log local0. " === Auth Step 3"
                                    if {[info exists tmm_auth_subscription]} {
                                                    log local0. " === Auth Step 4"
                                                    AUTH::subscribe $tmm_auth_sid
                                    }
                    } else {
                                    log local0. " === Auth Step 5"
                                    set tmm_auth_sid $tmm_auth_http_sids(ldap)
                                    log local0. " tmm_auth_sid : $tmm_auth_sid"
                    }
    
                    set user [HTTP::username]
                    set pass [HTTP::password]
                    log local0. " Auth using -$user- and -$pass-"
                    log local0. " === Auth Step 6"
                    AUTH::username_credential $tmm_auth_sid [HTTP::username]
                    log local0. " === Auth Step 7"
                    AUTH::password_credential $tmm_auth_sid [HTTP::password]
                    log local0. " === Auth Step 8"
                    AUTH::authenticate $tmm_auth_sid
                    log local0. " === Auth Step 9"
                    if {not [info exists tmm_auth_http_collect_count]} {
                                    log local0. " === Auth Step 10"
                                    HTTP::collect
                                    log local0. " === Auth Step 11"
                                    set tmm_auth_http_successes 0
                                    set tmm_auth_http_collect_count 1
                    } else {
                                    log local0. " === Auth Step 12"
                                    incr tmm_auth_http_collect_count
                    }
                    log local0. " END   ========= HTTP_REQUEST"
    }
    
    when AUTH_RESULT {
                    log local0. " BEGIN ========= AUTH_RESULT"
                    log local0. " === Auth Step 13"
                    set status [AUTH::status]
                    log local0. " === Auth Step 14"
                    log local0. " AuthStatus is: -$status-"
                    if {not [info exists tmm_auth_http_sids(ldap)] or \
                    ($tmm_auth_http_sids(ldap) != [AUTH::last_event_session_id]) or \
                    (not [info exists tmm_auth_http_collect_count])} {
                                    log local0. " === Auth Step 15"
                                    return
                    }
                    log local0. " === Auth Step 16"
                    if {[AUTH::status] == 0} {
                                    log local0. " === Auth Step 17"
                                    incr tmm_auth_http_successes
                    }
                     If multiple auth sessions are pending and
                     one failure results in termination and this is a failure
                     or enough successes have now occurred
                    if {([array size tmm_auth_http_sids] > 1) and \
                    ((not [info exists tmm_auth_http_sufficient_successes] or \
                    ($tmm_auth_http_successes >= $tmm_auth_http_sufficient_successes)))} {
                                    log local0. " === Auth Step 18"
                                     Abort the other auth sessions
                                    foreach {type sid} [array get tmm_auth_http_sids] {
                                                    log local0. " === Auth Step 19"
                                                    unset tmm_auth_http_sids($type)
                                                    if {($type ne "ldap") and ($sid != -1)} {
                                                                    log local0. " === Auth Step 20"
                                                                    AUTH::abort $sid
                                                                    incr tmm_auth_http_collect_count -1
                                                    }
                                    }
                                    log local0. " === Auth Step 21"
                    }
                    log local0. " === Auth Step 22"
    
                     If this is the last outstanding auth then either
                     release or respond to this session
                    incr tmm_auth_http_collect_count -1
                    if {$tmm_auth_http_collect_count == 0} {
                                    log local0. " === Auth Step 23"
                                    unset tmm_auth_http_collect_count
                                    if {[AUTH::status] == 0} {
                                                    log local0. " === Auth Step 24"
                                                    HTTP::release
                                    } else {
                                                    log local0. " === Auth Step 25"
                                                    HTTP::respond 401
                                    }
                                    log local0. " === Auth Step 26"
                    }
                    log local0. " END   ========= AUTH_RESULT"
    }
    
    when HTTP_RESPONSE {
                    log local0. " BEGIN ========== HTTP_RESPONSE"
                     For Click-Jacking protection
                    HTTP::header insert "X-FRAME-OPTIONS" "(DENY || SAMEORIGIN)"
    
                     Capture the response time for logging
                    set latency [expr {[clock clicks -milliseconds] - $reqIntLatency}]
                    log local0. " Call Latency: -$latency- milliseconds "
                    log local0. " ==================== END ========= $myIntTime =========== "
    }
    
  • The matching debug level log output for 1 transaction:

    (time, level, host, service, status removed because they were all the same)

    :  BEGIN ========= 2019-02-03_21:11:22 -0600 =========== 
    :  BEGIN ========= HTTP_REQUEST
    :  === Auth Step 1
    :  === Auth Step 2
    :  tmm_auth_sid : 1074998259
    :  === Auth Step 3
    :  Auth using -- and --
    :  === Auth Step 6
    :  === Auth Step 7
    :  === Auth Step 8
    :  === Auth Step 9
    :  === Auth Step 10
    :  === Auth Step 11
    :  END ========= HTTP_REQUEST
    :  BEGIN ========= AUTH_RESULT
    :  === Auth Step 13
    :  === Auth Step 14
    :  AuthStatus is: -1-
    :  === Auth Step 16
    :  === Auth Step 22
    :  === Auth Step 23
    :  === Auth Step 25
    :  === Auth Step 26
    :  END ========= AUTH_RESULT
    :  BEGIN ========= HTTP_REQUEST
    :  === Auth Step 1
    :  === Auth Step 5
    :  tmm_auth_sid : 1074998259
    :  Auth using -prw- and -xxxxxxx-
    :  === Auth Step 6
    :  === Auth Step 7
    :  === Auth Step 8
    :  === Auth Step 9
    :  === Auth Step 10
    :  === Auth Step 11
    :  END ========= HTTP_REQUEST
    :  BEGIN ========= AUTH_RESULT
    :  === Auth Step 13
    :  === Auth Step 14
    :  AuthStatus is: -1-
    :  === Auth Step 16
    :  === Auth Step 22
    :  === Auth Step 23
    :  === Auth Step 25
    :  === Auth Step 26
    :  END ========= AUTH_RESULT
    

    I just don’t think it’s ever actually making the call to the LDAP. It looks like it gets to that step the first time without a UID/PWD, and doesn't try. Then when it has the UID/PWD in the second pass, nothing happens again. But I can run an ldapsearch from the command line of the F5 and get a valid response.