I am attaching a patch for 3.0.x versions (I will forward port if there is interest and change recommendations). This patch adds a new option to Squid that allows it to forward the current authenticated user to the next proxy (or the HTTP server if that is what is wanted) via an HTTP header.

The need for this option is originated by the usage of Kerberos authentication on our installations and the usage of an external content filter proxy (Dansguardian). By nature the Kerberos authentication header sent by the browser to proxy is heavily encrypted and is designed to be data to only be understood by the browser and the Squid proxy that is doing the authentication. Basic installations of Dansguardian (oand my other non ICAP content filters) is to chain Dansguardian before Squid. The problem with this setup is that Dansguardian needs to know the user before the request is sent to Squid to do checks before the request is sent to Squid (for example, denying it filtering by URL). Dansguardian is able to works in this configuration for other auth methods like basic, and NTLM, because it is able to extract the user from the respective auth headers, something it can not do from the Kerberos encrypted header.

The solution to this problem is to switch the positions of Squid and Dansguardian in the chain, forward from Squid the authenticated user to Dansguardian (disabling caching on Squid in order to not cache Dansguardian generated responses). If caching is needed a second Squid could be added after Dansguardian

Browser -> Squid (no caching) -> Dansguardian -> Squid (optional) -> Internet

Dansguardian is patched too in order to add an authentication plugin able to understand the forwarded authenticated user. Currently my Dansguardian patch is not able to remove the header from the request, something that must be done for privacy reasons when not using the second optional Squid (if authenticated user forwarding is not enabled on it the header is removed)

I think ICAP could be the ideal solution for this problem, when Squid is able to call ICAP services at postcache stages.

TODO: the user is forwarded, Dansguardian uses it, but the other Squids on the chain are not able to use acls using that user, for them the request is unauthenticated, it is interesting to add the capability to use that user on that other Squid instances for example to be able to use different tcp_outgoing_address using auth based acls

This solution has been working for near month on a production site with more than 100 simultaneous users without problems to the present day

Note: thanks to rousskov ant squiddev IRC channel for the help and recommendations
diff -Naur squid-3.0.STABLE24.original/src/cf.data.pre 
squid-3.0.STABLE24/src/cf.data.pre
--- squid-3.0.STABLE24.original/src/cf.data.pre 2010-02-12 09:23:17.000000000 
-0430
+++ squid-3.0.STABLE24/src/cf.data.pre  2010-03-17 09:09:05.345201659 -0430
@@ -62,6 +62,17 @@
   configuration files.
 COMMENT_END
 
+NAME: forward_authenticated_user
+COMMENT: on|off
+TYPE: onoff
+DEFAULT: off
+LOC: opt_forward_authenticated_user
+DOC_START
+       If set, Squid will include the authenticated user on every HTTP request
+       on the header X-Authenticated-User
+DOC_END
+
+
 COMMENT_START
  OPTIONS FOR AUTHENTICATION
  -----------------------------------------------------------------------------
diff -Naur squid-3.0.STABLE24.original/src/globals.h 
squid-3.0.STABLE24/src/globals.h
--- squid-3.0.STABLE24.original/src/globals.h   2010-02-12 09:23:18.000000000 
-0430
+++ squid-3.0.STABLE24/src/globals.h    2010-03-17 09:11:07.784077767 -0430
@@ -87,6 +87,7 @@
     extern int opt_dns_tests;  /* 1 */
     extern int opt_foreground_rebuild; /* 0 */
     extern int opt_forwarded_for;      /* 1 */
+    extern int opt_forward_authenticated_user;    /* 0 */
     extern int opt_reload_hit_only;    /* 0 */
 #if HAVE_SYSLOG
 
diff -Naur squid-3.0.STABLE24.original/src/http.cc 
squid-3.0.STABLE24/src/http.cc
--- squid-3.0.STABLE24.original/src/http.cc     2010-02-12 09:23:18.000000000 
-0430
+++ squid-3.0.STABLE24/src/http.cc      2010-03-17 09:46:30.523077910 -0430
@@ -1416,6 +1416,16 @@
 
     strFwd.clean();
 
+    /* append X-Authenticated-User if allowed to forward and not already added 
*/
+    if (opt_forward_authenticated_user && 
!hdr_out->has(HDR_X_AUTHENTICATED_USER)
+        && orig_request->auth_user_request != NULL) {
+        hdr_out->putStr(HDR_X_AUTHENTICATED_USER, 
orig_request->auth_user_request->username());
+    }
+    /* remove X-Authenticated-User if not allowed to forward */
+    if (!opt_forward_authenticated_user && 
hdr_out->has(HDR_X_AUTHENTICATED_USER)) {
+        hdr_out->delById(HDR_X_AUTHENTICATED_USER);
+    }
+
     /* append Host if not there already */
     if (!hdr_out->has(HDR_HOST)) {
         if (orig_request->peer_domain) {
diff -Naur squid-3.0.STABLE24.original/src/HttpHeader.cc 
squid-3.0.STABLE24/src/HttpHeader.cc
--- squid-3.0.STABLE24.original/src/HttpHeader.cc       2010-02-12 
09:23:15.000000000 -0430
+++ squid-3.0.STABLE24/src/HttpHeader.cc        2010-03-16 10:51:46.404156357 
-0430
@@ -138,6 +138,7 @@
         {"X-Forwarded-For", HDR_X_FORWARDED_FOR, ftStr},
         {"X-Request-URI", HDR_X_REQUEST_URI, ftStr},
         {"X-Squid-Error", HDR_X_SQUID_ERROR, ftStr},
+        {"X-Authenticated-User", HDR_X_AUTHENTICATED_USER, ftStr},
         {"Negotiate", HDR_NEGOTIATE, ftStr},
 #if X_ACCELERATOR_VARY
         {"X-Accelerator-Vary", HDR_X_ACCELERATOR_VARY, ftStr},
diff -Naur squid-3.0.STABLE24.original/src/HttpHeader.h 
squid-3.0.STABLE24/src/HttpHeader.h
--- squid-3.0.STABLE24.original/src/HttpHeader.h        2010-02-12 
09:23:15.000000000 -0430
+++ squid-3.0.STABLE24/src/HttpHeader.h 2010-03-16 10:51:18.014156130 -0430
@@ -112,6 +112,7 @@
     HDR_X_FORWARDED_FOR,
     HDR_X_REQUEST_URI,         /* appended if ADD_X_REQUEST_URI is #defined */
     HDR_X_SQUID_ERROR,
+    HDR_X_AUTHENTICATED_USER,
     HDR_NEGOTIATE,
 #if X_ACCELERATOR_VARY
     HDR_X_ACCELERATOR_VARY,

Reply via email to