Re: [RFC] Handle ACLs that are neither denied nor allowed

From: Alex Rousskov <rousskov_at_measurement-factory.com>
Date: Thu, 05 Apr 2012 13:44:45 -0600

On 03/23/2012 04:27 AM, Amos Jeffries wrote:
> On 23/03/2012 4:21 a.m., Alex Rousskov wrote:
>> On 03/22/2012 01:10 AM, Alex Rousskov wrote:
>>
>>>>> IMHO, if authentication is involved, the only sane option is to follow
>>>>> this pattern:
>>>>>
>>>>> 1a. Authenticate (may require several HTTP transactions).
>>>>>
>>>>> 1b. Iff authenticated user is authorized to access Squid, continue.
>>>>> Otherwise, deny further access.
>>>>>
>>>>> 2. Use authenticated user credentials as needed.
>>>>> No authentication can be triggered at this stage.
>>>>> Credentials cannot become invalid or stale here.

>> * Authentication information for a
>> given transaction or tunnel does not change once set (and does not have
>> a freshness status or expiration ability). Bob's tunnel is Bob's tunnel
>> forever. It will never become Alice' tunnel. All requests inside Bob's
>> tunnel are Bob's requests, of course.
>>
>> * However, access control is a separate issue. Http_access and similar
>> access control knobs may apply to bumped requests inside tunnels and are
>> checked at the time of the request. Thus, if Bob's account is deleted,
>> his access to Squid can be blocked using http_access (normally without
>> re-authentication because we should not authenticate bumped requests).
>> No additional options are needed for this.

> This bites to the heart of the issue. Should all of Bobs access be cut
> immediately when his credentials expire or not?

I try to avoid the phrases like "credentials expire" because from Squid
point of view, there should be no such thing, but I can answer if we go
back to the "Bob's account has been deleted" example:

For now, access should be cut when the next http_access (or equivalent)
is evaluated. One could add more knobs/code to cut access earlier or
later, but any such code would have nothing to do with authentication.
It is only about authorization (which is now done at most a few times
per message/connection but could be extended to be performed for every
byte if desired).

> The current authentication cases are:
>
> * NTLM and Negotiate authenticate the TCP connection. Credentials do
> not detatch until the keep-alive/pinned/persistent connection is closed.
> Validation can only be done once.

Not sure what you mean by validation. We authenticate once. We can
authorize or deny access for any request on the authenticated TCP
connection.

> * Digest nonce becomes stale with every N milliseconds and needs
> revalidating each request.

> * Bearer access_token becomes invalid on a timeout after N milliseconds
> from allocation, authorization can be revoked midway through a transaction.

> * Basic credentials are valid only for one request.

I am not sure, but I think the above three do not contradict what I am
proposing.

> * side-band credentials from external ACL can be revoked and replaced
> (bob becomes alice) on any ACL test.

The "any" part sounds wrong. From a distant outside observer, it may
seem that Bob became Alice if we use several authentication points
(e.g., http_access and adapted_http_access) but that actually does not
have to happen from Squid point of view. We can use the same
credentials-never-expire approach: When there are multiple
authentication points, the authentication scope (the user is known as
Bob) may end at the next authentication point (where the user may be now
authenticated as Alice).

> * REQMOD adaptation can revoke and replace (bob becomes alice)
> credentials.

I would not put it that way. REQMOD can indeed change credentials in
request headers. If both http_access and adapted_http_access are used,
the original credentials last until REQMOD. The new credentials last
after REQMOD. There are just two different authentication scopes rather
than one scope where Bob becomes Alice.

> * SSL certificate credentials authenticate the connection. Validation
> can only be done once.

Authentication is done once. Access control can be done for every request.

> * SSL-bump cannot authenticate aand must use credentials from CONNECT
> request (if any). Validation can only be done on the CONNECT.

Authentication is done using CONNECT. Access control can be done for
CONNECT and every embedded request in the tunnel.

> That is the requirements Squid has to meet.
>
> Solution?
> - pull Digest/Bearer/Basic creds from request and check validity
> per-request.
> - pull NTLM/Negotiate creds from connection and check validity only on
> handshake request.
> - pull SSL certificate creds from connection and check validity only on
> handshake.
> - pull SSL-bumped creds from connection and check validity never.
> - pull external ACL creds from request and check validity never.

Again, I think it is better to clearly separate authentication from
authorization (or basic matching). "Validity" may imply dealing with
time-sensitive, expiring authentication which is something general Squid
code should try to avoid, IMO.

> adaptation is the main problem. Do we check credentials validity in
> http_access only? or in both http_access AND adapted_http_access?

Authentication and access control can be performed at both points. If
authentication is performed at both points, then we have two
authentication scopes: before adapted_http_access and after
adapted_http_access.

> external ACL is a similar problem.

I do not see why it is similar.

> Can we assume the script writer knows
> best and replace any request credentials with those given by the ACL?
>
> can we go so far as to trust both external ACL helpers and whatever
> adaptation system are in use and not bother to validate credentials
> received from there *at all*?

I may not understand the problem you are referring to, probably because
I do not know much about some ACL internals. I think we should separate
two cases:

1) Any ACL (external or not) can return a "match" or "no match" answer.
Nothing interesting here.

2) Some ACLs can also return "let's [re]authenticate!" answers with
various details and flavors. Such answers are only valid at a few
well-known points (e.g., http_access and adapted_http_access). If such
answers are received at any different point (e.g., tcp_outgoing_tos), it
has to be treated as a configuration or helper bug.

We must tell an ACL whether "let's [re]authenticate!" and other special
answers are allowed by its context. When dealing with old external ACLs,
we can define a consistent policy on how to treat those special answers
when they are inappropriate for the context.

From Squid code point of view, the above complexities can be confined to
those few well-known points (http_access and adapted_http_access) and a
single general "what to do with inapropriate ACL answer" method. The
rest of the code will not have to deal with any of this.

Hope this clarifies,

Alex.
Received on Thu Apr 05 2012 - 19:44:50 MDT

This archive was generated by hypermail 2.2.0 : Fri Apr 06 2012 - 12:00:04 MDT