-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Rainer,

On 7/23/14, 1:49 PM, Rainer Jung wrote:
> Am 23.07.2014 um 17:59 schrieb Christopher Schultz:
>> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256
>> 
>> Rainer,
>> 
>> On 7/23/14, 11:23 AM, Rainer Jung wrote:
>>> On 23.07.2014 16:37, Christopher Schultz wrote:
>>> 
>>>> On 7/18/14, 12:13 PM, Rainer Jung wrote:
>>> 
>>>>> On 17.06.2014 16:43, Christopher Schultz wrote:
>>>>>> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256
>>>>>> 
>>>>>> All,
>>>>>> 
>>>>>> I've been using sticky sessions with mod_jk and I can
>>>>>> see that there is a bit of a problem when attempting to
>>>>>> take a backend Tomcat server out of load-balanced
>>>>>> rotation: a user who never (or rarely) restarts their web
>>>>>> browser will keep the same JSESSIONID cookie forever and
>>>>>> therefore end up with the same backend server whether it
>>>>>> has been disabled or not.
>>>>>> 
>>>>>> Quick series of events:
>>>>>> 
>>>>>> 1. User visits load-balancer and gets a
>>>>>> randomly-assigned backend server/route. We'll call this
>>>>>> route "X". The JSESSIONID cookie set by the backend
>>>>>> server is therefore foo.X.
>>>>>> 
>>>>>> 2. User's requests are routed by mod_jk to route X.
>>>>>> 
>>>>>> 3. Route X is disabled using mod_jk's status worker
>>>>>> 
>>>>>> 4. User's session on server X expires.
>>>>>> 
>>>>>> [Technically, 3 and 4 can happen in either order]
>>>>>> 
>>>>>> 5. User makes a new request to the load-balancer, and
>>>>>> mod_jk sees the JSESSIONID cookie still set to foo.X.
>>>>>> mod_jk sends the request to route X which allows the user
>>>>>> to login, etc.
>>>>>> 
>>>>>> Thus, it takes more time than necessary to bleed all the 
>>>>>> traffic from route X for maintenance, etc.
>>>>>> 
>>>>>> Is there a way for mod_jk to ask route X if the session
>>>>>> is *still* valid? It seems that mod_jk will not re-route
>>>>>> a request that looks like it's got a valid session id to
>>>>>> a new (active) backend server unless the backend server X
>>>>>> is actually down.
>>>>>> 
>>>>>> Any ideas?
>>>>> 
>>>>> Not exactly what you want, but you can build something
>>>>> around it:
>>>>> 
>>>>> 1) Switch off stickyness for specific URLs
>>>>> 
>>>>> If you know that users will come via specific URLs, like a 
>>>>> login page, and you want that page to be handled non-sticky
>>>>> to optimize load balancing even if users have an old
>>>>> cookie, you can do that by setting the Apache envvar
>>>>> JK_STICKY_IGNORE. Look for JK_STICKY_IGNORE on:
>>>>> 
>>>>> http://tomcat.apache.org/connectors-doc/reference/apache.html
>>>>
>>>>
>>>>> 
This seems like a reasonable way to do things, except that we
>>>> still want to support requests to protected resources being
>>>> saved and redirected to the login page. If we did this 
>>>> (JK_STICKY_IGNORE), then we'd end up "forgetting" the saved 
>>>> request (because the client would be re-balanced to another
>>>> node for the login page) and ending up with a (useless)
>>>> session on the node we are trying to take down.
>>>> 
>>>> We'd like to retain the request-saving capabilities of the 
>>>> container.
>>> 
>>> Whatever "saved" exactly means: if you can identify that
>>> situation in terms of any part of the request (e.g. something
>>> in the referer header etc.), you can add that as a positive or
>>> negative condition via RewriteCond (or the 2.4 unified
>>> expression parser) and set JK_STICKY_IGNORE in a RewriteRule
>>> that does not change the URI, only sets the variable and also
>>> only of the RewriteConds apply. You'd have to analyze the
>>> request-response stream e.g. with a browser plugin to look for
>>> a useful header or similar which can be used to distinguish the
>>> "saved" and the "normal" case.
>> 
>> When I say "saved" I mean this workflow:
>> 
>> 1. User requests a protected resource 2. Container saves the
>> request (which creates a new session), presents the login screen 
>> 3. User authenticates 4. User is redirected to request saved in
>> step #1
> 
> So where's the interaction with putting a JK_STICKY_IGNORE on the
> login page if directly retrieved?

No problem there.

> The above sequence of steps does not retrieve the login page from
> the outside via its real URL, e.g. /login, does it?

Yes, it does: the request in #2 results in a *redirect* to the login
page. Thus, the saved request would be lost if we stripped the
stickiness of the request.

> That env var is only useful for URIs for which you know that they
> either don't need a session (unprotected static content) or will 
> start a new session (login page accessed by URI).

That why I think we might want to start to use a different URI for
"regular" logins versus logins prompted by the container (those that
are for "saved" requests).

The above poses the following problem: users with expired session ids
will create "saved request sessions" on a node that should not be
used, then they will be redirected to another node in the cluster,
thereby losing the saved session. I'd like to avoid both parts of that
problem and I believe it can be done with a Valve (but not a Filter).

> The other case, a request with an invalid session ID accessing a
> tomcat instance with activation disabled can IMHO be handled by a
> filter that
> 
> - checks whether the request has a valid session using 
> getSession(false), if it has one, let the request proceed
> 
> - checks activation state, if "active", let the request proceed
> 
> - checks the request method, if not GET, let the request proceed
> 
> - otherwise:
> 
> - set the session cookie, e.g. JSESSIONID the an empty value -
> issue an external redirect to the same request URL - optional
> redirect loop detection: add a query string param or cookie that
> gets the local jvmRoute appended during each redirect. Before
> doing the redirect, check that the local jvmRoute is not already
> part of that token (we have already been here before)
> 
> This would not really interfere with your saved requests: they
> would get a redirect which the browser follwos automatically and
> after that you will observe the normal behavior.

This is exactly what I have implemented -- as a Filter since we can
insert it before SecurityFilter intercepts the requests -- and my
tests suggest that it will work correctly.

I added code to strip-out any ;jsessionid path parameter from the URL
if it exists, but haven't done any of the redirect loop detection
(yet). I think the loop detection is going to have to keep a running
list of visited nodes which, in large clusters, could grow very large
especially if the node names are long. I'll post my code when it's a
little more featureful.

Thanks,
- -chris
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
Comment: GPGTools - http://gpgtools.org
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iQIcBAEBCAAGBQJT0Ab/AAoJEBzwKT+lPKRYG7wQAModddUmQTUFOS1XCFkFMSEM
Ccudk+haFhMlNgI8F69VC/Y/SKd+QAeyyv/f2a5mwz+2/xg6+/yoJtw39HKrQjy5
4wKNGGuO0wiHPqmndXi9R5QPWRrV59U++W4VOU2i2Hc8kxid0Wh95oDPMkePrrxz
DKDo53nVLbeL1KmN2gb53ykcxsbhUObWFW73Y8R1izewn1FgNEPs7+OjnBanf8eh
S7tPkIbASYOMdaGouDxe9XBM0PToeMkWFQPlsd29OLZ1UdRgAHmWrWyjX07Rmzff
RGt1w9GWu96y9MzC5F+XMFzs+3CNNfiQoIaEG7/1M/Imh8XI5Ymj6tYmCC6cN9xi
hnXMZZSFxar61q1B4yoQMslP18O2a8C54LReousNnIKSpLjdy0d5anue+OPmHjPD
JzoCAfwsH5e8REkS1pp+b1Eizt2djbpOylcU6g5cnmsZ99N50fB4lKD4sEqGaq3/
SYgOptl5m1RAx+c4Shoy9yELTN95+nddRZi5xjh223M2+h6pV3f1yfiORikCDyTH
ME+fZKXTIiMd7PR+F0K6QAPnhu+HeDHqJyZqcnXSOS8Z1nBO3dxnhKTtJqrggAup
cLuU/FUEH60N9ImUZFzMTId8HOr1lGYRRJrkGcuxF0qSPjJ+jpw4zWmf9in8yuYD
jxm0uRqU3wlrWrOnIUjY
=v6RU
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org

Reply via email to