Using LDAP to authenticate Squid proxy users

This article is meant to help set up LDAP authentication with a Squid proxy. Often administrators are using Squid as the central proxy for a company. For security reasons users need to enter their username and password before they are allowed to surf the internet. Firewalls usually deny accesses to the internet that would bypass the proxys. This way – if a user it doing dangerous things – you know who it was.

(Please be fair to your users and don’t lurk around what people are doing. In many countries this is forbidden anyway. If you don’t want them to surf private web sites during business-hours then use a decent blocking software instead of lurking on them.)

What is LDAP?

LDAP is short for "lightweight directory access protocol". It is not a directory service (which is often confused). Instead it is a way to access a directory through a common interface. You may already have a user directory based on OpenLDAP, Novell Directory Service (NDS) or Microsoft Active Directory. Any client that speaks LDAP can fetch information from those services.

LDAP provides a tree structure. Just an example:

+-- Company
|
+-- IT-Services
| |
| +-- George
| |
| +-- Tim
|
+-- Sales
| |
| +-- Joe
|
+-- Management
|
+-- Tina
|
+-- George

There are different types of nodes like "o" for organizations or "ou" for organizational units. To complicate matters a bit there are some limitations on how these nodes can be connected. In the above example you start your tree with the main node which is your company. This node is addressed as

o=Company

To refer to the sales department you would write the path to the node:

ou=Sales,o=Company

This path is called the "distinguished name" (dn). The dn is always unique in your directory.

And there may be different types of leafs like people or printers. You have probably noticed that I have two "George"s in the tree that are two different persons. George in the IT department has another distinguished name than George in the Management (although he probably would like to get the same salary). His distinguished name is:

cn=George,ou=IT-Services,o=Company

I hope that you now have a basic understanding of how LDAP structures look like. This article does not cover how to set up your own directory. If you like to play around with LDAP without spending money you may want to take a look at OpenLDAP (see http://www.openldap.org). 

Making Squid use LDAP for authenticating your users

As you probably already know you can make Squid ask your users for an authentication before they are allowed to surf the web. These are the parts of your configuration that set up how LDAP authentication is supposed to work: 

auth_param basic program /usr/lib/squid/ldap_auth -b o=Company -h ldapserver
   -D cn=Tim,ou=IT-Services,o=Company -w timspassword -f (&(objectclass=person)(cn=%s))
auth_param basic children 50
auth_param basic realm Web-Proxy
auth_param basic credentialsttl 1 minute

The option -b defines the context (branch of the tree) where you want to search for that users. In this example you are searching everywhere in the whole company tree. -h defines the hostname of the LDAP server to use. Next I need a user account to search the tree for the user (Novell requires that as it does not seem to allow anonymous searching). This account is provided using the -D option. -w lists the according password. And last I use a filter to search for all persons that have the name we look for (%s is the name this authenticator gets from Squid).

(Hint: this line is used in production in a network using a Novell Directory Service. There are other ways to call the ldap_auth authenticator which may be easier. But we don’t know where the user is located in the LDAP tree so we do a full search. Tim is a user account that is used to do that search.)

You also need to use ACLs to force the users to authenticate. Example: 

acl ldap-auth proxy_auth REQUIRED
http_access deny !ldap-auth

This would deny everybody access who is not authenticated (thus the "!").

By the way: an authenticator is just any program that reads lines from STDIN (like the console) that look like this

username password

and return either OK (if the credentials are okay) or ERR if something went wrong. 

Using LDAP groups

In addition to simple authentication you may also want to grant different privileges to different users. The easiest way is to use LDAP groups. A group is just a list of dinstiguished names. Example group:

  • dn=cn=Tim,ou=IT-Services,o=Company
  • dn=cn=Tina,ou=Management,o=Company

Assume that these two users are allowed to use Google where all other users are not allowed. First you need to define the LDAP group mapping: 

external_acl_type ldapgroup %LOGIN /usr/lib/squid/squid_ldap_group -b o=Company
   -f (&(objectclass=person)(cn=%v)(groupMembership=cn=%a,ou=Proxygroups,o=Company))
   -D cn=Tim,ou=IT-Services,o=Company -w timspassword -h ldapserver

The filter expression looks a little complicated. It just means that we are looking for any user (person) with the name we are looking for (%v) who is a member of the group we are looking for (groupMembership). You can now just create any number of groups in the tree like

cn=googleallowed,ou=Proxygroups,o=Company

Then this pile of ACLs should block off everyone from google.com who is not a member of that group: 

acl ldapgroup-googleallowed external ldapgroup googleallowed
acl google dstdomain google.com
http_access deny google !ldapgroup-googleallowed

You may be curious how such a group authorizator works. Simple. It just reads line after line from STDIN (like the console) where each line looks like

username groupname

and returns either OK or ERR depending on whether the user is a member of that group or not.

16 thoughts on “Using LDAP to authenticate Squid proxy users

  • 2009-07-10 at 19:54
    Permalink

    # NOTE: proxy_auth can’t be used in a transparent proxy as
    #         # the browser needs to be configured for using a proxy in order
    #         # to respond to proxy authentication.
    #
     

     

    So you need configure browser…

    Reply
  • 2010-03-07 at 04:20
    Permalink

    Nice and Informative Tutorial especially regards to the LDAP structure.

    Reply
    • 2010-10-18 at 20:19
      Permalink

      Any document I can find all the % varible?

      Reply
  • 2010-11-25 at 18:03
    Permalink

    I tried it in SLES 11 with AD 2008 & its giving this error

    squid#/usr/sbin/squid_ldap_auth -b o=mydomain.com -h 192.168.1.50 -D cn=Administrator,ou=Users,o=mydomain.com -w 123456 -f "(&(objectclass=person)(cn=%s))"
    administrator 123456
    squid_ldap_auth: WARNING, could not bind to binddn 'Invalid credentials'
    ERR Success
     

    Reply
    • 2011-03-15 at 13:59
      Permalink

      o=mydomain.com is not a valid syntax.

      use :

      dc=mydomain,dc=com

      objectClass must be with a Capital C.

      -b "dc=mydomain,dc=com"

      Reply
  • 2011-07-20 at 05:32
    Permalink

    can i use this paralel with ldap_auth?
    how it will work?

    as we know ldap_auth will ask for username and password while ldapgroup ask for username and groupname?

    Reply
  • 2011-08-09 at 12:52
    Permalink

    When I deny access for my group the squid reask for user cerdentials every time I typ to access a forbidden domain and doesn't schon deny_info pages.

    Reply
  • 2011-08-31 at 17:20
    Permalink

    im having troubles assigning ACL to ldap groups… i have this:

    external_acl_type gruposLDAP %LOGIN /usr/lib64/squid/squid_ldap_group -P -R -b OU=USUARIOS,DC=tierradelfuego,DC=gov,DC=ar -D proxyAuth -w password -f (&(objectClass=person)(sAMAccountName=%u)(memberOf=CN=%g,OU=GRUPOS,DC=tierradelfuego,DC=gov,DC=ar)) -h 10.1.9.33 -s sub -v 3 -d

    acl ProxyA external gruposLDAP _GP_US_PROXY_A
    acl ProxyB external gruposLDAP _GP_US_PROXY_B


    acl ad_users proxy_auth REQUIRED

    http_access deny !ad_users
    http_access deny ProxyB
    http_access allow ProxyA

    http_access allow all

    but no matters if a user is in ProxyA or ProxyB … it falls into an authentation loop.. can anybody help me?

    Reply
  • 2013-05-24 at 04:28
    Permalink

    Thanks for the knowledge. Currently I use ntlm_auth + winbind (this winbind connects to another openldap server) for proxy authentication. This way, had users log(ged)in with their domain uid into a domain machine, no more auth window pop out. It’s for a simple reason: “hei, we’ve had authenticated before. Why should we authenticate again?” yelling. Other way (i.e login with local user or into non domain machine (hadn’t joinned the domain)), they have to authenticate. The drawback is I have to create a group list of users separately in proxy instead of using existing groups on ldap server. Is it feasible to get the same scheme with ldap_auth? Thank you in advance.
    Regards,

    Reply
    • 2013-08-22 at 23:26
      Permalink

      You can actually combine ntlm_auth with squid_ldap_group in order to achieve this.
      I use ntlm_auth for single-sign-on (so users who are authenticated with the AD don’t need to re-type their username/password) – then I determine which group they’re in on the AD using an LDAP lookup.

      The documentation at http://wiki.squid-cache.org/ConfigExamples/Authenticate/WindowsActiveDirectory will get you going using NTLM.

      NTLM example:
      auth_param ntlm program /usr/bin/ntlm_auth –diagnostics –helper-protocol=squid-2.5-ntlmssp
      auth_param ntlm children 15
      auth_param ntlm keep_alive on

      LDAPGroup example:
      In this example, my domain is ‘wnz.widgets.com’. The LDAP username on the AD is “LDAP User” – in the group “Service Accounts”, which is nested under “Administration Accounts”.
      The password for “LDAP User” is stored in “/etc/squid3/bindsecret” and this file contains _just the password_ with no trailing enters or spaces.
      The AD I query is ‘wnzaklad1.widgets.com’.

      I am looking for groups containing people (objectclass=person) with the username %u (which is returned from NTLM auth).
      The group must be a sub-group of “Business Units” in the domain wnz.widgets.com.

      The username (%u) comes from NTLM.

      external_acl_type LDAPLookup ttl=300 negative_ttl=30 %LOGIN /usr/lib/squid3/squid_ldap_group -R -S -K -b “dc=WNZ,dc=WIDGETS,dc=COM” -D “cn=LDAP User,ou=Service Accounts,ou=Administration Accounts,dc=WNZ,dc=WIDGETS,dc=COM” -W /etc/squid3/bindsecret -f “(&(objectclass=person)(sAMAccountName=%u)(memberof=cn=%a,ou=Business Units,dc=WNZ,dc=WIDGETS,dc=COM))” -h wnzaklad1.widgets.com

      Advice:
      Yes, you need to bind Samba to the AD to do this. No, it’s not a big deal.
      Yes, you need to install a weekly cronjob to change the computer account’s trust password each week. (net changetrustpw -d 1)
      Don’t try using Kerberos unless all your clients are Windows 7+.
      When you are doing ACL compares to LDAP group names, PUT YOUR GROUP NAMES IN FILES (e.g. /etc/squid/LDAPGroup0, /etc/squid/LDAPGroup1). Refer to these files in your ACLs. Don’t put them in your squid config!
      If you put the LDAP names in the Squid config, things like spaces in group names become an issue.
      If your LDAP query user (“LDAP User”)’s password expires, the shit will hit the fan.

      Reply
  • Pingback: September, October 2014 Reading List - eGuru

  • Pingback: Squid Allow Users | Sufferband

  • Pingback: Squid Ldap How To | Wcstarwar

  • Pingback: How To Authenticate With Ldap | Information

  • 2016-12-19 at 08:07
    Permalink

    Hello friends,

    required your suggestion and help solve this problem

    thank you so much this article it’s easy to learn about LDAP structure. I am using zentyal server as ad and create group or users. I am also install pfsense as firewall and user authentication for internet users. I want to only zentyal users can access to a website by user authentication. I am using mydomain.local
    group – list
    under the group create user – deepak
    -sagar
    -ketan
    both user login in linux mint
    actually, i want this user to monitor sites and user authentication

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

By continuing to use the site, you agree to the use of cookies. more information

The cookie settings on this website are set to "allow cookies" to give you the best browsing experience possible. If you continue to use this website without changing your cookie settings or you click "Accept" below then you are consenting to this.

Close