[squid-users] help with acl order and deny_info pages

Marko Cupać marko.cupac at mimar.rs
Wed Oct 7 14:40:41 UTC 2015


On Thu, 24 Sep 2015 23:02:35 +1200
Amos Jeffries <squid3 at treenet.co.nz> wrote:

> On 24/09/2015 7:30 p.m., Marko Cupać wrote:
> > On Sun, 20 Sep 2015 21:43:26 +1200
> > Amos Jeffries <squid3 at treenet.co.nz> wrote:
> > 
> >> On 17/09/2015 7:24 p.m., Marko Cupać wrote:
> >>> On Thu, 17 Sep 2015 03:00:56 +1200
> >>> Amos Jeffries <squid3 at treenet.co.nz> wrote:
> >>>
> >>>> On 17/09/2015 12:37 a.m., Marko Cupać wrote:
> >>>>> Hi,
> >>>>>
> >>>>> I'm trying to setup squid in a way that it authenticates users
> >>>>> via kerberos and grants different levels of web access
> >>>>> according to ldap query of MS AD groups.After some trials and
> >>>>> errors I have found acl order which apparently does not trigger
> >>>>> reauthentication (auth dialogues in browsers although I don't
> >>>>> even provide basic auth).
> >>>>
> >>>> What makes you think browser dialog box has anything to do with
> >>>> Basic auth? All it means is that the browser does not know what
> >>>> credentials will work. The ones tried (if any) have been rejected
> >>>> with a challenge response (401/407) for valid ones. It may be the
> >>>> browser password manager.
> >>>>
> >>>> If you are using only Kerberos auth then users enter their
> >>>> Kerberos username and password into the dialog to allow the
> >>>> browser to fetch the Kerberos token (or keytab entry) it needs
> >>>> to send to Squid.
> >>>>
> >>>>
> >>>>> Here's relevant part:
> >>>>>
> >>>>> http_access deny !Safe_ports
> >>>>> http_access deny CONNECT !SSL_ports
> >>>>> http_access allow localhost manager
> >>>>> http_access deny manager
> >>>>> http_access deny to_localhost
> >>>>> # INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS
> >>>>> http_access deny !auth all
> >>>>> http_access allow !basic_domains !basic_extensions basic_users
> >>>>> http_reply_access allow !basic_mimetypes basic_users
> >>>>> http_access allow !advanced_domains !advanced_extensions
> >>>>> advanced_users http_access allow expert_users all
> >>>>> # INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS
> >>>>> http_access allow localhost
> >>>>> http_access deny all
> >>>>>
> >>>>> I'd like to know which acl triggered the ban, so I've created
> >>>>> custom error page:
> >>>>>
> >>>>> error_directory /usr/local/etc/squid/myerrors
> >>>>> deny_info ERR_BASIC_EXTENSION basic_extensions
> >>>>>
> >>>>> The problem is that my custom error page does not trigger when I
> >>>>> expect it to (member of basic_users accessing URL with extension
> >>>>> listed in basic_extensions) - ERR_ACCESS_DENIED is triggered
> >>>>> instead. I guess this is because of last matching rule which is
> >>>>> http_access deny all.
> >>>>
> >>>> Perhapse.
> >>>>
> >>>> But, basic_extensions is never the last listed ACL in a denial
> >>>> rule. There is never a deny action associated with the ACL. That
> >>>> is why the deny_info response template is not being used.
> >>>>
> >>>>>
> >>>>> Is there another way how I can order acls so that I don't
> >>>>> trigger reauthentication while triggering deny_info?
> >>>>
> >>>> Not without the ACL definition details.
> >>>>
> >>>> Amos
> >>>
> >>> Hi Amos,
> >>>
> >>> thank you for looking into this. Here's complete squid.conf (I
> >>> changed just private details such as domain, DN, password etc. in
> >>> external_acl_type).
> >>>
> >>
> >> <snip'ing bits of config not relevant to the answer>
> >>
> >>> auth_param negotiate
> >>> program /usr/local/libexec/squid/negotiate_kerberos_auth \ -r -s
> >>> GSS_C_NO_NAME
> >> <snip>
> >>> # ldap query for group membership
> >>> external_acl_type adgroups ttl=60 children-startup=2
> >>> children-max=10 %LOGIN
> >>> \ /usr/local/libexec/squid/ext_ldap_group_acl -R \
> >> <snip>
> >>
> >>
> >> These ACLs...
> >>
> >>> # map ldap groups to squid acls
> >>> acl basic_users external adgroups squid_basic
> >>> acl advanced_users external adgroups squid_advanced
> >>> acl expert_users external adgroups squid_expert
> >>
> >> ... to here ...
> >>
> >>
> >> <snip>
> >>> # require proxy authentication
> >>> acl auth proxy_auth REQUIRED
> >>
> >> ... and the "auth" one will all trigger 407 challenges *if* they
> >> are the last ACL on the line. Or if there are no credentials of
> >> any kind given in the request.
> >>
> >>
> >>>
> >>> # custom error pages
> >>> deny_info ERR_BASIC_DOMAIN basic_domains
> >>> deny_info ERR_ADVANCED_DOMAIN advanced_domains
> >>> deny_info ERR_BASIC_EXTENSION basic_extensions
> >>> deny_info ERR_ADVANCED_EXTENSION advanced_extensions
> >>>
> >> <snip>
> >>> # INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS
> >>> http_access deny !auth all
> >>
> >> Problem #1:
> >>  Any client with halfway decent security will not simply broadcast
> >> credentials on their first request of a new TCP connection, but
> >> will wait for a 407 challenge to indicate both their need and the
> >> type of credentials to send.
> >>
> >> The "all" on this line will prevent that 407 happening. Instead it
> >> will simply produce a plain 403 ERR_ACCESS_DENIED for any request
> >> lacking (Kerberos) credentials.
> >>
> >> NP: you can test whether this is your problem with a custom error
> >> page:
> >>
> >>  acl test1 src all
> >>  deny_info 499:ERR_ACCESS_DENIED test1
> >>  http_access deny !auth test1
> >>
> >> Your access.log should show the 499 status when its line matches.
> >>
> >>
> >>> http_access allow !basic_domains !basic_extensions basic_users
> >>> http_access allow !advanced_domains !advanced_extensions
> >>> advanced_users
> >>
> >> Basically okay. These will trigger 407 *if* (and only if) the
> >> client sent Negotiate/Kerberos credentials AND does not have group
> >> permission to access the URL being requested.
> >>
> >> Be aware this will probably produce the popups allowing users to
> >> change their credentials to those of another user account with the
> >> right group access. That may or may not be what you want.
> >>
> >>
> >> I usually find that *these* lines are the ones people most want
> >> not to popup. You have complex ACL tests so the order can be
> >> shuffled to this:
> >>
> >>   http_access allow !basic_domains basic_users !basic_extensions
> >>   http_access allow !advanced_domains
> >> advanced_users !advanced_extensions
> >>
> >> Which prevents the popups from group checking.
> >>
> >> If you still want to retain the helper load reduction from having
> >> the extension test first, then append " all" to each of those lines
> >> instead of shuffling.
> >>
> >>
> >>> http_access allow expert_users all
> >>
> >>
> >>> # INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS
> >>> http_access allow localhost
> >>> http_access deny all
> >>>
> >>
> >> Problem 2:
> >>
> >> Requests which somehow happen to get past the "deny !auth all" rule
> >> but not have a domain listed in your *_domains ACLs or _do_ match
> >> the paired *_extensions ACLs - will get denied by this final rule.
> >>
> >> NP: you can test that like the earlier test, but use a different
> >> ACL name and 49x status code.
> > 
> > Amos,
> > 
> > I'm grateful for your help, but I'm even more confused now. I
> > changed http_access rules according to your advices, tried
> > different combinations, but I still can't achieve intended
> > behaviour. Perhaps I could try to better explain my goals, as maybe
> > there is a better way to solve what I'm trying to achieve.
> > 
> > I want to have 4 levels of web access:
> > expert access - if user is part of expert_users ad group
> > advanced access - if user is part of advanced_users AD group
> > basic access - if user is part of basic_users AD group
> > no access - if user is not part of any AD groups
> > 
> 
> Okay. Your ACLs are defined right for that.
> 
>  acl basic_users external adgroups squid_basic
>  acl advanced_users external adgroups squid_advanced
>  acl expert_users external adgroups squid_expert
> 
> 
> > Here's the difference in web access for groups:
> > expert access - allow all
> > advanced access - allow except some extensions and domains
> > basic access - allow except some more extensions and domains
> > no access - allow nothing
> 
> Which is:
> 
>   # authentication required for any access at all
>   http_access deny !auth
> 
>   # expert access - allow all
>   http_access allow expert_users all
> 
>   # advanced access - allow except some extensions and domains
>   http_access deny some_domains
>   http_access deny some_extensions
>   http_access allow advanced_users all
> 
>   # basic access - allow except some more extensions and domains
>   http_access deny more_domains
>   http_access deny more_extensions
>   http_access allow basic_users all
> 
>   # no access - allow nothing
>   http_access deny all
> 
> 
> What you need to add to this is deny_info for each of the "deny" lines
> ACL. You can have two templates one for domains and one for
> extensions. Re-use the ext template for both of the some_extensions
> and more_extensions. Ditto for the domains template.
> 
> > 
> > When a user is redirected to error page, there should be enough info
> > about error:
> > - user as seen by squid (or no user if not authenticated)
> > - group as seen by squid (or no group)
> > - acl that triggered the ban (not the last deny rule)
> 
> This is not possible. It is always the combination of multiple ACLs
> matching and non-matching that leads to a denial.
> 
> The closest you can get is the above config with one ACL per line/rule
> and a deny_info for each of the ones used on deny lines.
> 
> 
> The codes that can be used in the error pages are detailed at
> <http://wiki.squid-cache.org/Features/CustomErrors>
> specifically the %a code can be used to expand the user name. But the
> group and ACL name details are not passed and would have to be
> inferred by which template is being used.

Hi,

sorry it took me so long to test this. I confirm the ruleset you suggest
accomplishes my goals.

Regards,
-- 
Before enlightenment - chop wood, draw water.
After  enlightenment - chop wood, draw water.

Marko Cupać
https://www.mimar.rs/


More information about the squid-users mailing list