phokz / mod-auth-external

External Authentication Module for Apache HTTP Server - mod_authnz_external
36 stars 13 forks source link

Each authentication request generates multiple invocations of mod_authnz_external #51

Open kmccurley opened 2 years ago

kmccurley commented 2 years ago

Our authentications are taking over four seconds, and I couldn't imagine why it is this slow. Our script invokes php to contact another server, and somehow this external php script is sending six different requests to the authentication server. This seems incomprehensible to us, since the script executes only a single HTTP request to the other server. Nevertheless, each invocation of mod_authnz_external translates into six different executions to the auth server, and apparently apache blocks until the last one finishes. This raises the question of what exactly is happening - is there any restart logic in the default configuration of mod_authnz_external that I was unable to find? I ran netstat -cant while it was executing an authentication, and sure enough it fires six different socket connections. The php code that does this is quite simple, and does just a POST to the server. This can timeout, but we don't have any retry logic in our php script.

$client = new \GuzzleHttp\Client(); $response = $client->request('POST', $auth_endpoint_url, ["form_params" => $query]);

Executing our script from the command line generates only a single POST, so this causes me to think that mod_authnz_external is invoking it multiple times for each authentication request from the apache server.

We are using debian 11, apache 2.4.51-1~deb11u1, mpm_prefork, php 7.4.25, and this module built from master (looks like 3.3.3). We can try installing the debian package instead, but I'm grasping at straws to imagine how a single authentication request translates into six RPC calls.

kmccurley commented 2 years ago

Further information: it seems that apache is passing the http request to a single worker in mpm_prefork, and that worker is making multiple calls to exec_external, each of which spawns a separate process. The processes are completing correctly, but issuing six at once is causing it to be delayed considerably while it waits for all to finish. I looked at whether mod_authnz_external is killing them due to a timeout, but that's not the case (it uses APR_KILL_AFTER_TIMEOUT, which is 3 seconds by default in apache). I even set a sleep(5) in the external php authenticator, and it still wasn't killed.

This is quite baffling, since I cannot tell why apache would make multiple calls to the external authenticator for a single http request.

bimimicah commented 2 years ago

Sorry for the late response. Have you tried setting apache's loglevel to debug or higher and seeing how many times per request mod_authnz_external is triggered? If we know that, it should help narrow some things down.

On a side note: One page load does not necessarily mean only one request for the page. In some situations (such as kerberos SSO (Negotiate)) it takes an initial auth failure and then the browser sends the proper authentication information on the second try. Obviously that doesn't explain 6 different requests, It's just an example of how you might have multiple requests per page load even without requests for images, css, etc.