F5 is upgrading its customer support chat feature on My.F5.com. Chat support will be unavailable from 6am-10am PST on 1/20/26. Refer to K000159584 for details.

Forum Discussion

tiwang's avatar
tiwang
Icon for Nimbostratus rankNimbostratus
Sep 17, 2014

APM httpagent401 in clientless mode?

Hi out there I just ran into a problem - I need to issue a http401 from the APM to authenticate against a remote LDAP server - and since my client isn't a full-blown browser but a client build on MS WCF I have to run in clientless mode. But it looks to me as if the http401 agent isn't executed at all? Could this because fo the clientless mode? (yes - if I remove the clientless mode flag I get prompted) - is there another way I could get the username and password from a client in clientless mode under APM?

 

best regards /ti

 

8 Replies

  • You are correct. Clientless-mode is disabling this "disruptive" agent. A workaround would be to use an iRule to send the 401 (in the absence of an existing Authorization) header. That iRule might look something like this:

    when HTTP_REQUEST {    
        if { not ( [HTTP::header exists Authorization] ) } {
            HTTP::respond 401 WWW-Authenticate "Basic realm=\"myrealm\""
        }
    }
    

    I may have my Authorization header syntax a little off, but you should get the idea.

  • tiwang's avatar
    tiwang
    Icon for Nimbostratus rankNimbostratus

    ok - thanks - just a minor problem still - see - I am used to use the APM module for authentication etc - this irule here is probably fired under the LTM module - after the APM - or can I use this in a irule I get trigged from the apm module somehow? I can see that I under general purpose in the VE has acccess to an irule event where I get the option of a Custom irule event agent with an ID? - do create this irule here and then bind it somehow to this event and I can then afterwards get access to the "session.logon.last.username and password" here?

     

    best regards /ti

     

  • The HTTP_REQUEST event will fire before access policy evaluation. The iRule event in the APM visual policy triggers the ACCESS_POLICY_AGENT_EVENT event. So the above iRule example would preemptively respond with a 401 response before any traffic arrives at the access policy.

     

  • tiwang's avatar
    tiwang
    Icon for Nimbostratus rankNimbostratus

    hi Again thanks kevin - this sounds as this is just the way to do it - will try it first thing tomorrow morning. Are the irules in general run before the apm module or what controls in what order it is run/evalueted?

     

    best regards /ti

     

  • Are the irules in general run before the apm module or what controls in what order it is run/evalueted?

     

    Roughly speaking, all layer 4 through 6 events (TCP, SSL, etc.), and the HTTP_REQUEST (and optionally the HTTP_REQUEST_DATA) events get triggered before any of the ACCESS events. Then the HTTP_REQUEST_RELEASE and HTTP_REQUEST_SEND events, and all of the server side events are triggered after the ACCESS events. There are actually non ACCESS events that get triggered during an ACCESS policy evaluation, but they are hidden by default.

     

    are the session username and passwords stored in the ordinary session.* variables when the authentication is forced this way?

     

    Yes.

     

  • tiwang's avatar
    tiwang
    Icon for Nimbostratus rankNimbostratus

    hi Again hmm - can you tell me what I do wrong here I issue the riule and get promnpted from the the browser - enter my credentials and get rejected because I don't got the username and password exported to the apm module:

     

    notice apd[10731]: 01490143:5: 7696b4d9: Logging Agent: before ldap notice apd[10731]: 01490113:5: 7696b4d9: session.user.agent is Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.120 Safari/537.36 notice apd[10731]: 01490113:5: 7696b4d9: session.user.clientip is 194.182.254.34 notice apd[10731]: 01490113:5: 7696b4d9: session.user.display_sessionid is 7696b4d9 notice apd[10731]: 01490113:5: 7696b4d9: session.user.sessionid is 7696b4d9 notice apd[10731]: 01490113:5: 7696b4d9: session.user.starttime is 1411036793 info apd[10731]: 01490004:6: 7696b4d9: Executed agent '/dk_dmz/DK_FUR_401_ap_act_logging_4_ag', return value 0 debug apd[10731]: 01490000:7: ./AccessPolicyProcessor/SessionState.h func: "clearTempSessionAgentState()" line: 84 Msg: Agent did not initiated the scheduled agent debug apd[10731]: 01490000:7: AccessPolicyProcessor/AccessPolicy.cpp func: "execute()" line: 290 Msg: Let's evaluate rules, total number of rules for this action=1 debug apd[10731]: 01490000:7: AccessPolicyProcessor/AccessPolicy.cpp func: "execute()" line: 296 Msg: Rule to evaluate = "" info apd[10731]: 01490006:6: 7696b4d9: Following rule 'fallback' from item 'Logging' to item 'LDAP Auth' debug apd[10731]: 01490011:7: 7696b4d9: LDAP agent: ENTER Function executeInstance debug apd[10731]: 01490000:7: ./AccessPolicyProcessor/Session.h func: "getSessionVar()" line: 303 Msg: variable "session.logon.last.username" was not found in the local cache for session "7696b4d9" debug apd[10731]: 01490000:7: ./AccessPolicyProcessor/Session.h func: "getSessionVar()" line: 310 Msg: try to get it from MEMCACHED debug apd[10731]: 01490000:7: memcache.c func: "mc_convert_session_var_to_mc_key()" line: 1160 Msg: Converted Var: session.logon.last.username to Session Var tmm.session.7696b4d9.session.logon.last.username debug apd[10731]: 01490000:7: ./AccessPolicyProcessor/Session.h func: "getSessionVar()" line: 344 Msg: variable "session.logon.last.username" for session "7696b4d9" was not found in MEMCACHED debug apd[10731]: 01490000:7: ./AccessPolicyProcessor/Session.h func: "getSessionVar()" line: 303 Msg: variable "session.logon.last.password" was not found in the local cache for session "7696b4d9" debug apd[10731]: 01490000:7: ./AccessPolicyProcessor/Session.h func: "getSessionVar()" line: 310 Msg: try to get it from MEMCACHED

     

    As far as I can see the sessionvariables are not stored in mem - I need to do something more that just try to fetch the variables in the apm module? best regards /ti

     

  • Session variable insertion isn't going to be automatic here. Only the 401 agent would do that. What you need to do is:

    1. Respond with a 401 if the Authorization header does not exist.
    2. If it does exist, but the MRHSession cookie does not, collect the payload and parse out the username and password from the Authorization header data and assign to temporary variables.
    3. In the ACCESS_SESSION_STARTED event, grab those temporary values and insert into session variables. Example:

      when ACCESS_SESSION_STARTED {        
          if { [info exists username] } {            
              ACCESS::session data set session.logon.last.username $username
          }
      }        
      

    I don't have a chance to test this, but the logic should at least be close.

  • I've noticed that when using clientless mode the logging statement for username is blank. When using the normal Login Page agent, this information is populated once the login button is submitted by the client.

    Here is my iRule configuration:

    when HTTP_REQUEST {
        if { ([HTTP::header exists "Authorization"]) && ([HTTP::cookie value MRHSession] == "") } {
            switch [IP::addr [IP::client_addr] mask 255.255.0.0] {
                "10.3.0.0" {
                    HTTP::header insert "clientless-mode" 1
                    set clientless_mode 1
                }
            }
        }
    }
    
    when ACCESS_SESSION_STARTED {
        set sid [ACCESS::session data get "session.user.sessionid"]
        if { [info exists clientless_mode] } {
            log -noname accesscontrol.local1.notice "01490000:7: $sid: ---New Clientless Session---"
            ACCESS::session data set session.logon.last.username [HTTP::username]
            ACCESS::session data set -secure session.logon.last.password [HTTP::password]
            ACCESS::session data set session.inactivity_timeout  120
            ACCESS::session data set session.max_session_timeout 120
            unset clientless_mode
        }
    }
    

    /var/log/apm Entry

    notice apd[13742]: 01490010:5: ae67c781: Username ''
    

    Any ideas on how to get the Username log statement populated?