Squid Ntlm Auth

Setting up Squid for NTLM Auth

http://www.flatmtn.com/article/setting-squid-ntlm-auth

Configuring Squid for use with NTLM Auth via a Windows NT domain controller

Note: The following learning process was forced upon me by a situation at work. I make no promises that this is the "right way" to do this.

Quick steps:

  • Download
  • Compile
  • Install
  • Configure
  • Running and testing
  • Auto configuration of browsers
  • Misc

Here is everything the way I did it.

Note: I am running Red Hat Linux 8.0, Samba 2.2.7 rebuilt (see below), and Squid 2.5.STABLE5 with Windows NT 4 Server as the domain controller. The box is a P2-400, 128meg RAM, 4gig hard drive. Setup is for 10 users. There are some things that are different if you are using Samba 3.x that I don't cover here. Also, there may be some differences if you are using a newer Windows Server product and Active Directory.

1) Download Samba, Squid

Download Samba .

Download Squid .

If you want or need to make rpms, get the src.rpms from your distribution (or a newer one) and install with:

rpm -ivh [package_name].src.rpm

Otherwise if an rpm is already available that you want to use:
rpm -ivh [package_name].rpm

2) Compile samba squid with NTLM auth

Note that many newer Linux distros have the newer Squid package available for them, so check before taking the time to do it yourself. Winbind, however, may not have been built with challenge/response enabled.

For Samba, you need winbind compiled for challenge/response. To test your current installation, try:

wbinfo -a [domain]\\[user]%[password]

If only plain text is returned, you will need to recompile winbind with at least:

./config --with-winbind --with-winbind-auth-challenge

RedHat's Samba rpm, or at least 2.2.7 for RH8, is not built for winbind challenge/response.

For Squid and NTLM auth, you need at least:

./config --enable-ntlm-auth-helpers="winbind,SMB" \
--enable-external-acl-helpers="unix_group,wbinfo_group" \
--enable-auth="ntlm,basic" \
--with-winbind-auth-challenge \
--with-samba-sources="/[path_to_samba_sources]/" \ --enable-basic-auth-helpers="winbind"

You also need the Samba sources available for compiling Squid with NTLM capabilities.

Please read each package's documentation for other config options you may need to specify.

For those of you interested in compiling your own RPMs, here is what I did:

Went to http://rpm.pbone.net/ and downloaded the source rpms, specifically squid-2.5.STABLE5-4.fc2.src.rpm and the one for the version of samba I choose to run. I only did this because I wanted the latest stable and could not find a pre-built rpm for RH8. You may be using a newer distro that already has binaries built for it, so check before wasting time compiling.

Installed with:

rpm -ivh [package_name].src.rpm

cd to /usr/src/redhat/SPECS

Changed the samba.spec file as follows (I needed to recompile winbind):

...
Summary: The Samba SMB server.
Name: samba
Version: 2.2.7
Release: 5.8.0a
...
%description
...
TCP/IP (NetBT) protocols and does NOT need the NetBEUI (Microsoft Raw
NetBIOS frame) protocol. Winbind built to support challenge/response.
...
        --with-acl-support \
        --with-winbind \
        --with-winbind-auth-challenge \
...
%changelog
* Wed Jun 30 2004 S. Yoder <computer_AT_flatmtn_DOT_com> 2.2.7-5.8.0a
- rebuilt to enable --with-winbind-auth-challenge
...

Changed the squid.spec file as follows:

...
Summary: The Squid proxy caching server.
Name: squid
Version: 2.5.STABLE5
Release: 5.rh8
...
Patch7: squid-2.5.STABLE5-warning.patch
Patch8: squid-2.5.STABLE3-libntlmssp.patch

Patch10: squid-2.5.STABLE5-wbinfo_group.patch
...
%patch7 -p1 -b .warning
%patch8 -p1 -b .libntlmssp
%patch10 -p1
...
   --enable-ntlm-auth-helpers="winbind,SMB" \
   --enable-external-acl-helpers="ip_user,ldap_group,unix_group,wbinfo_group" \
   --enable-auth="ntlm,basic" \
   --with-winbind-auth-challenge \
   --with-samba-sources="/usr/src/redhat/BUILD/samba-2.2.7/" \
...
%changelog
* Wed Jul 1 2004 S. Yoder <computer_AT_flatmtn_DOT_com>
- Fixed wbinfo_group.pl per http://bugzilla.redhat.com/bugzilla/long_list.cgi?bu
- Fixed wbinfo_group.pl to change [domain]\\[user] to [domain]\[user]
- Winbind auth using sources from samba-2.2.7-5.8.0.src.rpm
...

Note: change the path for "—with-samba-sources" to match where you have extracted your sources.
Installed the necessary packages for compiling: openjade, linuxdoc-tools, openldap-devel, pam-devel, openssl-devel, cyrus-sasl-devel, plus other packages those require and gcc.

Made a patch file for wbinfo_group.pl (after some debuging I found it needed changing, at least for my setup) that looks like:

--- squid-2.5.STABLE5/helpers/external_acl/wbinfo_group/wbinfo_group.pl.orig
+++ squid-2.5.STABLE5/helpers/external_acl/wbinfo_group/wbinfo_group.pl 2004-07-
@@ -12,6 +12,11 @@
 #   Jerry Murdock <jmurdock@itraktech.com>
 #
 # Version history:
+#   2004-06-30 S. Yoder <computer_AT_flatmtn_DOT_com>
+#               Updated for new wbinfo output format and
+#               fixed loop caused by shellwords per:
+#               http://bugzilla.redhat.com/bugzilla/long_list.cgi?buglist=10266
+#
 #   2002-07-05 Jerry Murdock <jmurdock@itraktech.com>
 #              Initial release
 #
@@ -33,7 +38,9 @@
 sub check {
         local($user, $group) = @_;
         $groupSID = `wbinfo -n "$group"`;
-        chop  $groupSID;
+        # because wbinfo -n also returns the group number
+        $groupSID = substr($groupSID,0,index($groupSID," ",0));
+        #chop  $groupSID;
         $groupGID = `wbinfo -Y "$groupSID"`;
         chop $groupGID;
         &debug( "User:  -$user-\nGroup: -$group-\nSID:   -$groupSID-\nGID:   -$
@@ -47,7 +54,18 @@
 while () {
         chop;
        &debug ("Got $_ from squid");
-        ($user, $group) = &shellwords;
+       # this causes a loop
+        #($user, $group) = &shellwords;
+        # instead use
+        @H1=split(/\s+/, $_);
+        $user = $H1[0];
+        # this is added because my tests showed
+        # IE (6, Win2k) was sending [domain]\\[name]
+        if ($user =~ m/\\\\/) {
+         $user =~ s|\\\\|\\|g;
+        }
+        $group = $H1[1];
+        # continue original
        $ans = &check($user, $group);
        &debug ("Sending $ans to squid");
        print "$ans\n";

(It goes in /usr/src/redhat/SOURCES/squid-2.5.STABLE5-wbinfo_group.patch)

Ran rpmbuild -bi [name].spec to test compiling.
Ran rpmbuild -bb [name].spec to build the binaries or rpmbuild -ba [name].spec to build all.
Note: I am running rpm 4.1.1-1.8x. If you are using RH8, please update to the latest or at least to the same version I am running. See rpm.org.

To download my rpm or view my full spec file, go here.

3) Install

Install Samba or replace with the updated winbindd, if you only needed that part fixed.

For non-package (ie rpm, deb, etc) installation:

make
make install

For rpm-based installation:

rpm -ivh [package_name].rpm

You will need at least samba and samba-common. May as well add samba-client so you can run smbclient if needed.
Install Squid.

For non-package installation:

make
make install

For rpm-based installation:

rpm -ivh [package_name].rpm

Note: When installing Squid, via the rpm, you may get a dependency requirement for perl(Authen::Smb). You can get it from http://search.cpan.org/dist/Authen-Smb/. There is a rpm out there (check pbone), if you prefer. If you don't install the perl-Authen-Smb rpm, but instead compile it manually, then install the squid rpm using the —nodeps option (if there are no other dependencies and you manually install the perl module).

4) Configure

Read through Squid's FAQ #23

For Samba (/etc/samba/smb.conf) you need at least:

[global]
workgroup = [WORKGROUP]
netbios name = [MACHINE_NAME]
password server = [PDC]
security = domain
winbind uid = 10000-20000
winbind gid = 10000-20000
winbind use default domain = yes

You may also want to see my other Samba page. Note that you can put an IP in for the [PDC] if you don't have an internal DNS server or do not want to modify /etc/hosts.

Tip: If your box has multiple NICs, like mine, you may not want Samba to broadcast its presence on both interfaces. To make it only use one IP add the following, in [global]:

interfaces = [interface_ip]/32 127.0.0.1/8
bind only interfaces = yes

For Squid (/etc/squid/squid.conf) I have something like (please read the config file to see all the available options and what they mean):

# note if one network card, can drop [ip_of_first_nic]:
http_port [ip_of_first_nic]:3128
# note if only one network card, can drop next line
tcp_outgoing_address [ip_of_second_nic]
hierarchy_stoplist cgi-bin ?
cache_mem 4 MB
cache_swap_low 85
cache_swap_high 90
# note read the config file about this and adjust it
# to what your disk(s) can do, and allow for log files
cache_dir ufs /var/spool/squid 100 16 256
cache_access_log /var/log/squid/access.log
cache_log /var/log/squid/cache.log
cache_store_log /var/log/squid/store.log
pid_filename /var/run/squid.pid

# note: you may need to increase children based on your number of users
auth_param ntlm program /usr/lib/squid/wb_ntlmauth
auth_param ntlm children 5
auth_param ntlm max_challenge_reuses 0
auth_param ntlm max_challenge_lifetime 2 minutes
auth_param ntlm use_ntlm_negotiate off
auth_param basic program /usr/lib/squid/wb_auth
auth_param basic children 5
auth_param basic realm Squid proxy-caching web server
auth_param basic credentialsttl 2 hours

# only need this if you want to use Windows Domain Groups for acl(s)
external_acl_type nt_group ttl=0 concurrency=5 %LOGIN /usr/lib/squid/wbinfo_group.pl

acl all src 0.0.0.0/0.0.0.0
acl manager proto cache_object
acl localhost src 127.0.0.1/255.255.255.255
acl to_localhost dst 127.0.0.0/8
acl SSL_ports port 443 563
acl Safe_ports port 80
acl Safe_ports port 21
acl Safe_ports port 443 563
acl Safe_ports port 70
acl Safe_ports port 210
acl Safe_ports port 1025-65535
acl Safe_ports port 280
acl Safe_ports port 488
acl Safe_ports port 591
acl Safe_ports port 777
acl CONNECT method CONNECT
acl QUERY urlpath_regex cgi-bin \?
acl allowedurls dstdomain "/etc/squid/restrictedusers_allowedurls"
acl blockcache url_regex -i "/etc/squid/restrictedusers_blockcache"
# blockads is optional for this config
acl blockads url_regex -i "/etc/squid/blockads"
acl restrictedusers external nt_group XWebRestricted
acl unrestrictedusers external nt_group XWebAll
acl Authenticated proxy_auth REQUIRED

# Things never to cache
no_cache deny QUERY
# Enable this if you don't want any caching
#no_cache deny all

http_access allow manager localhost
http_access deny manager
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access allow localhost
# blockads is optional for this config
http_access deny blockads
http_access deny blockcache restrictedusers
http_access allow allowedurls restrictedusers
http_access allow unrestrictedusers
http_access deny !Authenticated
http_access deny all

http_reply_access allow all

acl FTP proto FTP
always_direct allow FTP

cache_mgr [someone]
cache_effective_user squid
cache_effective_group squid

# I have very little RAM, so I set this off. YMMV
memory_pools off
forwarded_for on
error_directory /etc/squid/errors
coredump_dir /var/spool/squid

# note 33,2 lets you see which acl allowed or denied
debug_options ALL,1 33,2

/etc/squid/restrictedusers_allowedurls would be a text file that looks like:

.google.com
.yahoo.com
.yimg.com

/etc/squid/restrictedusers_blockcache, so they can't cheat and look at a cached page, would look like:

google.com.*cache
yahoo.com.*cache

Why allow restricted users to go to search sites at all? I think they should have the ability to look for things so they can request sites they think they need access to. I don't have the time to keep up with all the sites they could use for business purposes. The short summary should be enough for them to determine if it would be beneficial and enough to give the URL so management can review their request.

/etc/squid/blockads, and related acl+http_access, is something I use to block most urls used to display ads. You don't have to use it, but why not make this thing beneficial to your users as well. See the end of this page for the full text of what I am using.

Note on Squid ACLs: Take it in baby steps. I suggest not trying to do NTLM auth right away, but instead test using an IP address. This lets you make sure you've got your ACL logic working without having to worry if auth is working. An example ACL would look like:

...
acl all src 0.0.0.0/0.0.0.0
...
acl allowedurls dstdomain "/etc/squid/restrictedusers_allowedurls"
acl blockcache url_regex -i "/etc/squid/restrictedusers_blockcache"
# block specific ip
acl restrictedusers src [ip_address_to_restrict]/255.255.255.255
# allow specific ip
acl unrestrictedusers src [ip_address]/255.255.255.255

http_access allow manager localhost
...
http_access deny blockcache restrictedusers
http_access allow allowedurls restrictedusers
http_access allow unrestrictedusers
http_access deny all
...

Once you have it blocking or not blocking based on IP, then start trying the auth. Note that I am using Windows Domain Groups. You could also use a text file and block based on login name.

How to block based on browser (specifically IE and Gator)

5) Running and testing

You can skip the Samba part if you have winbind working with challenge/response.

First, start up samba

service smb start

Then join the domain (only need to do once) with:

smbpasswd -j [DOMAIN] -r [PDC] -U [user_name]

Now start winbind

service winbind start

Test joining the domain

wbinfo -t

(Should return "Secret is good")

Test challenge/response:

wbinfo -a [domain]\\[user]%[password]

Now, on to Squid.

Initialize the cache (only need to do once or when you make changes to the disk cache):

squid -z

Now run Squid:

service squid start

Test getting if someone belongs to a Windows Domain group, if you are going to use this feature:

cd /usr/lib/squid
./wbinfo_group.pl
[domain]\[user] [domain]\[group]
(press [ctrl]+[c] to exit)

OK is returned if they are in the group, otherwise ERR.

Configure a browser to use your new proxy
For IE: Go to Tools->Internet Options->Connections->LAN Settings
For Mozilla: Go to Tools->Options->General->Connection Settings

Note on NTLM auth for IE: If the computer belongs to the Windows domain, you need to turn it on to avoid the dialog box pop-up. Go to Tools->Internet Options->Advanced tab and check "Enable Intergrated Windows Authentication" and then reboot your computer. Computers that are not members of the domain will pop-up no matter what (except for Win9x, so long as they have logged into the domain).

To test Squid, try running as an IP or user that is restricted or denied. Then try as an IP or user who is not restricted or denied. Check out the log files - access.log and cache.log in /var/log/squid; to find information to help you in figuring out problems. Remember in squid.conf I had debug_options ALL,1 33,2? The "33,2" causes more info to be displayed in cache.log. You can set this to debug_options ALL,1 when you no longer need to debug.

Once things are working, you need to make sure Samba, Winbind, and Squid start on boot:

chkconfig smb on
chkconfig winbind on
chkconfig squid on

See Squid's FAQ #23 for ways to keep from having to run smbd and nmbd constantly.

6) Auto configuration of browsers

In IE you can check "Automatically detect settings" to have the browser go out and find what proxy settings should be used. This is quite handy, especially for your laptop users. Other browsers, such as Mozilla, can be given a URL to input rather than the user typing in the proxy info for each supported protocol.

Some links:
Squid FAQ #5
Another WPAD how-to
WPad and Active Directory
A reference made to the DHCP method

Being that I'm still using Windows NT 4 Server for DHCP, and that it does not support a type 252 entry, I decided to go with the DNS method. You can use both and even Active Directory Group Policy, if you run AD. Even if you don't have an internal DNS server, you can always use a host file that is placed on each workstation when they login (do that via a script) in order for the computer to be able to resolve wpad.[domain].[com].

For the DHCP method, create a type 252, AUTO-PROXY-CONFIG, entry that gives a URL to the proxy.pac file and you should be done. At least this is how other sites make it sound.

For the DNS method:

First create an A record of wpad.[domain].[com], or a CNAME record of wpad, that points to your internal web server. If you don't have an internal DNS server you can use a hosts file on the workstation. If your web server is hosted off-site or you don't have one, you can run Apache or TUX on the same box as Squid (if you have enough memory) or another box or even install Apache for Windows on a workstation. IIS on a workstation will be limited to 10 simultaneous connections. (WPAD = Web Proxy Auto-Discovery Protocol)
Now create your proxy.dat, for the DNS method, and/or a proxy.pac, for the DHCP method, in a ASCII text editor, such as notepad or VI. It should look something like (there is a more complex example in the Squid FAQ):

function FindProxyForURL(url,host)
{ if(isPlainHostName(host)||
    isInNet(host,"192.168.1.0","255.255.255.0")) return "DIRECT";
  else return "PROXY 192.168.1.253:3128; DIRECT";
}

You'll also want this file to be called proxy.pac and wpad.dat, for various methods. You can either create them as symbolic links, if using a Unix file system and the web server is configured to allow following of sym links:

ln -s proxy.dat wpad.dat

or use Apache's redirect in either its config file or a .htaccess file in the root directory, if redirect is allowed in the config file overrides:
Redirect /wpad.dat http://wpad.[domain].[com]/proxy.dat

or just copy the files to the new names, remembering to change all of them if you modify one.
Now you need to add the correct mime type to your web server. For Apache it is:
AddType application/x-ns-proxy-autoconfig .dat

Which can go in your Apache config file or in the root .htaccess file.
Then you need to make sure your web server is configured to allow you to access it via the name wpad.[domain].[com]. For Apache you may need to add this to the config file:
NameVirtualHost *:80

<VirtualHost *:80>
     ServerName www.[domain].[com]
     ServerAlias [domain].[com] wpad.[domain].[com]
     DocumentRoot /var/www/html
</VirtualHost>

Restart Apache after making changes to its config file.
Now in IE, go to Tools->Internet Options->Connections->LAN Settings and check "Automatically detect settings". For Mozilla, go to Tools->Options->General->Connection Settings and select "Automatic proxy configuration URL:" and give it a URLlike http://wpad.[domain].[com]/proxy.dat.
If you are having problems, check that wpad.[domain].[com] can be resolved by using nslookup, on Windows, or dig, on Linux. Then check that you can directly access http://wpad.[domain].[com]/proxy.dat. For IE, you may need to "flush" its cache of the proxy info (thank you, MS). To do this, clear the "Auto detect", close IE, re-open IE, re-enable "Auto detect", close IE, re-open IE. Supposedly this started with IE 5.5.

Mozilla/Firefox/Netscape cannot, at this time, use the WPAD method for automatically retrieving proxy settings. However, they do have a place to specify a URL to the config file. For Mozilla/Firefox, see Tools->Options-»General->Connection Settings. To configure this for all users edit all.js or firefox.js, depending on software and version, and add:

// Setup proxy
pref("network.proxy.autoconfig_url", "http://wpad.[domain].[com]/proxy.dat");
pref("network.proxy.no_proxies_on",  "localhost, 127.0.0.1, .[domain].[com]");
pref("network.proxy.type",           2);

Note that Mozilla, or at least my Firefox 0.9, appears to have problems if a startup page uses a URL that requires access through the proxy to load. From a packet capture it appears that occasionally the request for the start page is made before retrieving the proxy settings. See Bug 100022.

7) Misc

If you are having problems with Java applets causing a basic auth pop-up, try upgrading to the latest J2RE, from Sun, or re-installing.

Other Squid related things:
SquidGuard - "An ultrafast and free filter, redirector and access controller"
Viralator - AV scanner plug-in
DansGuardian - web content filter, not free for business use
DG AV plug-in

My /etc/squid/blockads file:

(^|\.)doubleclick\.
(^|\.)fastclick\.
(^|\.)clickstream\.
(^|\.)clickthrutraffic\.
(^|\.)clickthru\.
(^|\.)clickxchange\.
(^|\.)valuestream\.
(^|\.)valuexchange\.
(^|\.)valueclick\.
(^|\.)dimexchange\.
(^|\.)dimeclick\.
(^|\.)adbanner\.
(^|\.)adclick\.
(^|\.)ad-flow\.
(^|\.)adflow\.
(^|\.)adimg\.
(^|\.)adimage\.
(^|\.)adimages\.
(^|\.)adlog\.
(\/|\.)admt\.
(^|\.)ads\.
/ads/
(\/|\.)adserv\.
(^|\.)adserver\.
(^|\.)adservere\.
(^|\.)adsremote\.
(\/|\.)adsrv
(^|\.)adstream\.
(^|\.)adtrix\.
(^|\.)adv\.
(^|\.)advert\.
(^|\.)advertising\.com
(^|\.)adxchange\.
(\/|\.)atdmt\.
(^|\.)banner\.
(^|\.)banners\.
(^|\.)gator\.
us\.yimg\.com/a/

For other methods of blocking ads with Squid:
A list of servers you can download
Ad Zapper
Ad Zapper how-to

How to verify wbinfo_group.pl via command line.

The following is a good way to verify whether your squid configuration with NTLM authentication is properly set up to utilize Windows Active Directory group memberships:

  1. echo “username windowsgroup” | /usr/lib/squid/wbinfo_group.pl -d
Debugging mode ON.
Got username windowsgroup from squid
User: -username-
Group: -windowsgroup-
SID: -S-1-5-21-915438365-207112795-1232828436-3341-
GID: -16777237-
Sending OK to squid
OK

用SAMBA3的Winbind连Windows DC認證squid proxy

http://phorum.study-area.org/index.php?topic=21409.0

Win2000 AD + Samba 3 + Squid Proxy
Jishon (wt.moc.emohcp|nohsij#wt.moc.emohcp|nohsij)
歡迎轉載,但請務必保留原出處和作者

前言:

Squid穩定及強大的功能是其受歡迎的原因, 但在與Windows AD網域整合以提供使用者認證上卻一直是令人頭大的問題, 現在藉由整合samba的winbind,這個問題既可迎刃而解, 也讓您的squid認證方式更加彈性!

目的:

認證AD網域使用者身份, 提供NT Challenge認證, 配合transparent proxy讓登入AD網域使用者開啟IE時自動登入Squid, 至於Netscape及其他使用plain text的瀏灠器仍然需手動輸入帳號及密碼

環境:

Mandrake 9.2
Samba-3.0.2 (請勿使用3.0.1, 如果使用smb時client端會無法登入)
Squid-2.5STABLE4-1mdk
Perl 5.8.1
Shellwords.pl ( Redhat的perl已內建, Mandrake請另外安裝)
Authen::Smb (Perl Module請Redhat另行安裝)
libkrb51-1.3-3mdk (Redhat應是krb5-libs)
Windows 2000 AD Native Domain

安裝方式:

安裝SAMBA, 將squid主機加入AD網域成為member server

1.這邊使用samba-3.0.2的SRC.RPM檔

  1. rpm -i samba-3.0.2.xx.src.rpm

修改/usr/src/RPM/SPECS/samba3.spec
在CFLAGS="$RPM_OPT_FLAGS $EXTRA" ./configure \這段最後加上

—with-winbind > —with-winbind-auth-challenge

重編samba

  1. rpmbuild —bb samba3.spec

安裝

  1. rpm -Uvh samba-3.0.2.xx.rpm

2.修改smb.conf 在global區加入

workgroup = NTDOMAIN
realm = NTDOMAIN.COM            
security = ADS                      #AD網域模式
password server = DC           #你的Domain Controller
encrypt passwords = yes
idmap uid = 10000-20000
idmap gid = 10000-20000
winbind enum users = yes
winbind enum groups = yes
template shell = /bin/bash              #選擇性
template homedir = /home/%D/%U
winbind use default domain = yes

3.修改krb5.conf

[realms]
NTDOMAIN.COM = {  # 注意 : NTDOMAIN.COM要大寫!!
kdc = dc.ntdomain.com # 你的DC
}

4.將主機加入網域

  1. net ads join -U adminuser%password (具有加入網域權限使用者)

5.修改/var/lib/samba/winbindd_privileged的目錄

權限為750, 群組squid, 讓squid可以讀取winbind的socket.

6. 設定與DC溝通時的使用者

  1. wbinfo —set-auth-user=user%password (具有一般權限使用者即可)

7.啟動winbind

  1. service winbind start

修改Squid設定

1.重編squid, 以source rpm為例

  1. rpm -i squid-2.5STABLE4-1mdk.src.rpm

修改/usr/src/SPECS/squid.spec

--enable-auth=ntlm,basic \ 
--enable-basic-auth-helpers=winbind \ 
--enable-ntlm-auth-helpers=winbind \ 
--enable-external-acl-helpers="winbind_group,wbinfo_group"

並在%files加入

%attr(755,root,squid) %{_libexecdir}/wbinfo_group* # 為了找出這行可累了>_<

# rpmbuild --bb squid.spec
# rpm -Uvh squid-2.5STABLE4-1mdk.i586.rpm

2.修改squid.conf

這邊只介紹重點, 其餘請自行參考相關文章

# NT challenge Authentication for IE
auth_param ntlm program /usr/bin/ntlm_auth --helper-protocol=squid-2.5-ntlmssp
auth_param ntlm children 5
auth_param ntlm max_challenge_reuses 0
auth_param ntlm max_challenge_lifetime 20 minutes

# Plain Text Authentication for others
auth_param basic program /usr/bin/ntlm_auth --helper-protocol=squid-2.5-basic
auth_param basic children 5
auth_param basic realm Squid proxy-caching web server
auth_param basic credentialsttl 2 hours

# 
external_acl_type NT_global_group ttl=300 %LOGIN /usr/lib/squid/wbinfo_group.pl

# 
acl UserGroup external NT_global_group "/etc/squid/usergroup"

# 允許該群組者存取
http_access allow UserGroup

3.為了讓程式可以檢驗複數群組,並對應Samba3.0.2(wbinfo -r結果與前版不同)需動手修改/usr/lib/squid/wbinfo_group.pl

#!/usr/bin/perl -w
#
# external_acl helper to Squid to verify NT Domain group
# membership using wbinfo
#
# This program is put in the public domain by Jerry Murdock
# <jmurdock@itraktech.com>. It is distributed in the hope that it will
# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# Author:
#   Jerry Murdock <jmurdock@itraktech.com>
#
# Version history:
#   2002-07-05 Jerry Murdock <jmurdock@itraktech.com>
#               Initial release
#
#   2003-12-16 Jim Barber
#               Added mutiple Group check in Group file

# external_acl uses shell style lines in it's protocol
require 'shellwords.pl';

# Disable output buffering
$|=1;

sub debug {
        # Uncomment this to enable debugging
        # print STDERR "@_\n";
}

#
# Check if a user belongs to a group
#
sub check {
        local($user, @group) = @_;
        local($group);
        foreach $group (@group)
        {
        $groupSID = `wbinfo -n "$group"`;
        chop  $groupSID;
        $groupGID = `wbinfo -Y "$groupSID"`;
        chop $groupGID;
        &debug( "User:  -$user-\nGroup: -$group-\nSID:   -$groupSID-\nGID:   -$roupGID-");
        return 'OK' if(`wbinfo -r \Q$user\E` =~ /^$groupGID$/m);
        }
        return 'ERR';
}

#
# Main loop
#
while (<STDIN>) {
        chop;
        &debug ("Got $_ from squid");
        ($user, @group) = &shellwords;
        $ans = &check($user, @group);
        &debug ("Sending $ans to squid");
        print "$ans\n";
}

4.建立/etc/squid/usergroup檔, 並加入允許存取squid之AD群組, 內容如

Domain Admins
Webusers

5.service squid restart
用戶端IE設定:
這邊假設使用已使用Transparent Proxy
預設狀態下IE X.X(小弟忘了)即使用NT-Challenge為登入模式.不需另外修改

Squid 整合 Win2K AD 認證的 Proxy Server

緣起:
舊的 win proxy server 經常當機, 重建前考量系統穩定及未來病毒侵擾可能, 我們選擇了 Linux 解決方案, 當然低費用的絕對優勢, 企業主們肯定不會反對.

說明:

OS= Redhat Enterprise Linux AS 4(完全安裝)
Kernel= 2.6.9-22.0.1.ELsmp
Squid= squid-2.5.STABLE6-3 (rpm -qa | grep squid)
Samba= Version 3.0.10-1.4E (smbd -V)

相關的套件均使用內建的版本, 也不用重新編譯.

安裝步驟:

Step 1) 設定 Samba

檢查 Samba 編譯時的參數

#/usr/sbin/smbd -b
--with Options:
WITH_ADS
WITH_AUTOMOUNT
WITH_PAM
WITH_QUOTAS
WITH_SENDFILE
WITH_SMBMOUNT
WITH_SYSLOG
WITH_UTMP
WITH_WINBIND <<

參數內需包含 winbind, 如果沒有, 請重新編譯安裝檔, 如果已包含, 請跳過此步驟.

重新編譯 samba rpm:
從官方網站下載相應版本的 source rpm = samba-3.0.10-1.4E.src.rpm
ftp://ftp.redhat.com

#rpm -i samba-3.0.10-1.4E.src.rpm
#cd /usr/src/redhat/SPECS

#vi samba.spec
找到這幾行

CFLAGS=-D_GNU_SOURCE %configure
--with-acl-support
--with-automount
.....
--with-swatdir=%{_datadir}/swat

後方加上這兩項
--with-winbind
--with-winbind-auth-challenge

開始編譯
#rpmbuild -bb samba.spec

如果一切順利且無錯誤訊息, 會產生相關的安裝檔於 /usr/src/redhat/RPMS/i386,
因為要移除原來的 rpm 可能會有相依性的困擾, 由於我們使用相同的原始檔作重新編譯,
當重複安裝時, 可以覆蓋(force)方式安裝.
#service smb stop
#cd /usr/src/redhat/RPMS/i386
#rpm -ivh --force samba-3.0.10-1.4E.i386.rpm
#rpm -ivh --force samba-client-3.0.10-1.4E.i386.rpm
#rpm -ivh --force samba-common-3.0.10-1.4E.i386.rpm
#rpm -ivh --force samba-debuginfo-3.0.10-1.4E.i386.rpm
#rpm -ivh --force samba-swat-3.0.10-1.4E.i386.rpm

修改 smb.conf 及 krb5.conf

#vi /etc/samba/smb.conf

[global]
workgroup = NTDOMAIN
realm = NTDOMAIN.COM
security = ADS #AD網域模式
password server = MyDC #你的Domain Controller
encrypt passwords = yes
wins server = MYWINS #你的WINS server
idmap uid = 10000-20000
idmap gid = 10000-20000
winbind enum users = yes
winbind enum groups = yes
template shell = /bin/bash #選擇性
template homedir = /home/%D/%U
winbind use default domain = yes

#vi /etc/krb5.conf
[[/code]]
[libdefaults]
default_realm = NTDOMAIN.COM
dns_lookup_realm = false
dns_lookup_kdc = false

[realms]
GTTW.COM.TW = { ##要大寫喔
kdc = MyDC
default_domain = NTDOMAIN.COM
admin_server = MyDC
}

[domain_realm]
.gttw.com.tw = NTDOMAIN.COM
gttw.com.tw = NTDOMAIN.COM
[[/code]]
將 Linux 加入 AD 網域

#net ads join -U Administrator%mypass

出現錯誤訊息"KDC has no support for encryption type"
請重設 AD Administrator 的密碼,詳細資訊請參考
http://gentoo-wiki.com/HOWTO_Adding_...ting_AD_Domain

修改/var/lib/samba/winbindd_privileged的目錄權限為750, 群組squid, 讓squid可以讀取winbind的socket.

設定與DC溝通時的使用者

  1. wbinfo —set-auth-user=user%password (具有一般權限使用者即可)

啟動(重啟) Samba & winbind

#service smb restart
#service winbind restart

Step 2) 設定 Squid

檢查 Squid 編譯時的參數支援

#squid -v

確認是否有這幾項

--enable-auth=ntlm,basic
--enable-basic-auth-helpers=winbind
--enable-ntlm-auth-helpers=winbind
--enable-external-acl-helpers="winbind_group,wbinfo_group"

如果未包含, 請重新編譯原始檔, 如果有, 請跳過此步驟.

重新編譯 Squid rpm:
從官方網站下載相應版本的 source rpm = squid-2.5.STABLE6-3.src.rpm
ftp://ftp.redhat.com

#rpm -i squid-2.5.STABLE6-3.src.rpm
#cd /usr/src/redhat/SPECS

#vi squid.spec
請在適當的地方加上編譯所需的參數.

#rpmbuild -bb squid.spec
安裝 RPM 時請參考上述 Samba 的說明.

修改 squid.conf

# NT challenge Authentication for IE
auth_param ntlm program /usr/bin/ntlm_auth --helper-protocol=squid-2.5-ntlmssp
auth_param ntlm children 5
auth_param ntlm max_challenge_reuses 0
auth_param ntlm max_challenge_lifetime 20 minutes

# Plain Text Authentication for others
auth_param basic program /usr/bin/ntlm_auth --helper-protocol=squid-2.5-basic
auth_param basic children 5
auth_param basic realm Squid proxy-caching web server
auth_param basic credentialsttl 2 hours

#設定Authorization program,授與使用者群組讀取權限(如果只需驗證是否為網域使用者則不需要)
external_acl_type NT_global_group ttl=300 %LOGIN /usr/lib/squid/wbinfo_group.pl

#設定Acess Control list, 配合external_acl_type, 若如果只需驗證是否為網域使用者而不限定群組則使用 acl UserGroup proxy_auth REQUIRED 即可
acl UserGroup external NT_global_group "/etc/squid/usergroup"

# 允許該群組者存取
http_access allow UserGroup

為了讓程式可以檢驗複數群組,並對應Samba3.0.2(wbinfo -r結果與前版不同)需動手修改/usr/lib/squid/wbinfo_group.pl

#!/usr/bin/perl -w
#
# external_acl helper to Squid to verify NT Domain group
# membership using wbinfo
#
# This program is put in the public domain by Jerry Murdock
# <jmurdock@itraktech.com>. It is distributed in the hope that it will
# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# Author:
# Jerry Murdock <jmurdock@itraktech.com>
#
# Version history:
# 2002-07-05 Jerry Murdock <jmurdock@itraktech.com>
# Initial release
#
# 2003-12-16 Jim Barber
# Added mutiple Group check in Group file

# external_acl uses shell style lines in it's protocol
require 'shellwords.pl';

# Disable output buffering
$|=1;

sub debug {
# Uncomment this to enable debugging
# print STDERR "@_n";
}

#
# Check if a user belongs to a group
#
sub check {
local($user, @group) = @_;
local($group);
foreach $group (@group)
{
$groupSID = `wbinfo -n "$group"`;
chop $groupSID;
$groupGID = `wbinfo -Y "$groupSID"`;
chop $groupGID;
&debug( "User: -$user-nGroup: -$group-nSID: -$groupSID-nGID: -$groupGID-");
return 'OK' if(`wbinfo -r Q$userE` =~ /^$groupGID$/m);
}
return 'ERR';
}

#
# Main loop
#
while (<STDIN>) {
chop;
&debug ("Got $_ from squid");
($user, @group) = &shellwords;
$ans = &check($user, @group);
&debug ("Sending $ans to squid");
print "$ansn";
}

**紅字為修改的部份

建立/etc/squid/usergroup檔, 並加入允許存取squid之AD群組, 內容如

Domain Admins
Internet User

設定完成, 啟動 Squid ,可以進行測試了.

#service squid start

FAQ:

1. 先確定Squid 可正常工作

為方便除錯進行, 我們建議先不考慮與 AD 認證之設定下, 確定 Squid 可正常工作, 我們也確實因此發現 SELinux service 的影響.

2. squid -v

squid 重啟失敗, squid -v 無輸出等狀況, 請關閉 SELinux 的 Squid 項, Desktop>Applications->security level>SELinuxSELinux Service Protection>Disable SELinux Protection for squid daemon

3. 如何檢查 Linux 與 AD 的連線及帳號存取???

成功 Join win2K AD 後可使用這些指令驗證.
wbinfo -g //顯示AD 的所有群組
wbinfo -u //顯示AD 的所有帳號
wbinfo -a myid%mypass //帳號登入驗證
wbinfo -t //與 AD 連線測試
wbinfo -n "somegroup" //Convert group name to sid

4. wbinfo "Could not lookup name"错误

可顯示 AD 的帳號及群組, 但使用 wbinfo -n 轉換 sid 時出現"Could not lookup name"???
經筆者找遍網路文章, 都無法解決, 最後下載官方最新版 3.0.21 ,以編譯方式安裝才獲得解決.
請注意,此版雖然可正常轉換 sid, 但輸入格式與舊版不同, 當整合 wbinfo_group.pl 時, 需作程式碼修正.

請修改 /usr/lib/squid/wbinfo_group.pl
找到這幾行

sub check {
local($user, $group) = @_;
$groupSID = `wbinfo -n "$group"`;
chop $groupSID;
$groupGID = `wbinfo -Y "$groupSID"`;
chop $groupGID;

改成這樣
sub check {
local($user, $group) = @_;
$groupSID = `wbinfo -n "$group" | cut -d" " -f1`;
chop $groupSID;
$groupGID = `wbinfo -Y "$groupSID"`;
chop $groupGID;
5. 連線不順暢

用戶端數量在超過 15 個時, 會發生連線不順暢, 經常需要重新整理網頁才可顯示正常, 且下載檔案時會不時中斷.
A:請檢查 cache.log 是否有警告訊息

===========================
WARNING: All ntlmauthenticator processes are busy.
2006/04/14 09:17:01|
WARNING: up to 14 pending requests queued
2006/04/14 09:17:01|
Consider increasing the number of ntlmauthenticator processes to at least 19 in your config file.
===========================

請加大這個參數的值—>20
auth_param ntlm children 20
auth_param basic children 20
6. How to avoid JVM authentication dialog box.

A:Add the following

acl java_jvm browser Java
Then,before your http_access for the authenticated users, use:

http_access allow java_jvm

參考連結:
http://phorum.study-area.org/viewtop...ighlight=squid
http://www.flatmtn.com/computer/Linux-SquidNT.html
http://gnu.kookel.org/ftp/squid/http...2-wbinfo_group

Squid中文权威指南

(第12章)

译者序:
本人在工作中维护着数台Squid服务器,多次参阅Duane Wessels(他也是Squid的创始人)的这本书,原书名是"Squid: The Definitive Guide",由O'Reilly出版。我在业余时间把它翻译成中文,希望对中文Squid用户有所帮助。对普通的单位上网用户,Squid可充当代理服务器;而对Sina,NetEase这样的大型站点,Squid又充当WEB加速器。这两个角色它都扮演得异常优秀。窗外繁星点点,开源的世界亦如这星空般美丽,而Squid是其中耀眼的一颗星。
对本译版有任何问题,请跟我联系,我的Email是:nc.moc.oohay|gnep_auhgnoy#nc.moc.oohay|gnep_auhgnoy
彭勇华
目 录

第12章 验证辅助器
12.1 配置Squid
12.2 HTTP基本验证
12.2.1 NCSA
12.2.2 LDAP
12.2.3 MSNT
12.2.4 Multi-domain-NTLM
12.2.5 PAM
12.2.6 SASL
12.2.7 SMB
12.2.8 YP
12.2.9 getpwnam
12.2.10 winbind
12.2.11 基本验证API
12.3 HTTP摘要验证
12.3.1 password
12.3.2 摘要验证API
12.4 Microsoft NTLM验证
12.4.1 SMB
12.4.2 winbind
12.4.3 NTLM验证API
12.5 外部ACL
12.5.1 ip_user
12.5.2 ldap_group
12.5.3 unix_group
12.5.4 wbinfo_group
12.5.5 winbind_group
12.5.6 编写自己的外部ACL辅助器
第12章 验证辅助器

先前我在6.1.2.12章里谈起过代理验证。然而,我仅仅解释了如何编写用于代理验证的访问控制规则。这里,我将告诉你如何选择和配置部分验证辅助器。
回想一下,Squid支持三种方式用于从用户端采集验证信用项:基本,摘要(Digest),和NTLM。这些方式指定squid如何从客户端接受用户名和密码。从安全观点看,基本验证非常脆弱。摘要和NTML验证显然更强壮。对每种方式,squid提供一些验证模块,或辅助进程,用于实际处理认证的过程。
我提到的所有验证辅助器都包含在squid的源代码发布里。你可以在编译时使用./configure选项来指定它们的目录名。例如:
% ls helpers/basic_auth

LDAP NCSA getpwnam

MSNT PAM multi-domain-NTLM

Makefile SASL winbind

Makefile.am SMB

Makefile.in YP

% ./configure —enable-basic-auth-helpers=LDAP,NCSA …
辅助器程序正常安装在$prefix/libexec目录。
如同重定向器一样,squid使用一个验证辅助器进程池。某个验证请求会被送往第一个空闲辅助器。当所有验证器进程都忙时,squid将未处理请求放进队列。假如队列变得太大,squid会以致命错误消息退出。大部分情况下,squid缓存验证结果。这样就减少了辅助器进程的负载,并改进了响应时间。

12.1 配置Squid

auth_param指令控制了配置squid的验证辅助器的每个方面。不同的方式(基本,摘要,NTLM)有一些共性,也有一些唯一的参数。紧跟在auth_param后的第一个参数必须是basic, digest, 或ntlm之一。我将在随后章节里,详细讲解每种验证机制的配置细节。
除了auth_param外,squid还有2个指令影响到代理验证。可以使用max_user_ip ACL来阻止用户与其他人共享用户名和密码。假如squid检测到相同的用户名来自太多不同IP地址,该ACL被匹配,就可以拒绝这样的请求。例如:
acl FOO max_user_ip 2

acl BAR proxy_auth REQUIRED

http_access deny FOO

http_access allow BAR
在该情形中,假如用户从3个或更多的不同IP地址提交请求,squid就拒绝该请求。authenticate_ip_ttl指令控制squid记住每个用户的源IP地址多长时间。对于经常改变IP地址的用户,更小的TTL可能好点。在一个用户的IP地址很长时间不变的环境里,可以使用较大的TTL。

12.2 HTTP基本验证

基本验证最简单,然而最不安全。它本质上以明文来传送用户密码,尽管密码被编码成可打印字符。例如,假如用户敲入其用户名Fannie和密码FuRpAnTsClUb,用户代理首先将这2者结合到一个单一串里,以冒号来分割用户名和密码:
Fannie:FuRpAnTsClUb
然后它用base64方法(定义在RFC 2045)来编码这个串。它在HTTP头部里看起来如此:
Authorization: Basic RmFubmllOkZ1UnBBblRzQ2xVYgo=
若有人碰巧捕获到用户的HTTP请求,他能轻易获取到用户名和密码:
% echo RmFubmllOkZ1UnBBblRzQ2xVYgo= | /usr/local/lib/python1.5/base64.py -d

Fannie:FuRpAnTsClUb
遵循HTTP/1.1 RFC的要求,squid不会转发验证信用项到其他服务器。换句话说,假如信用项是用于访问squid的,Authorization头部会从外出请求里移除。
你会注意到,某些基本验证器可被配置来检查系统密码文件。因为基本信用项不被加密,所以在cache访问密码里包含登陆密码是个坏想法。假如选择使用getpwnam验证器,你应该完全理解让用户密码以明文在网络中传送的意义。
HTTP基本验证支持下列auth_param参数:
auth_param basic program command

auth_param basic children number

auth_param basic realm string

auth_param basic credentialsttl time-specification
program参数指定验证辅助程序的命令及其参数。大多数情况下,这里是到某个验证辅助程序的路径名。它们默认安装在/usr/local/squid/libexec下。
children参数告诉squid使用多少辅助器进程。默认值是5,假如你不了解需要多少进程来处理请求,这个值就是个好起点。假如指定得太少,squid会在cache.log里告警。
realm参数是在提示输入用户名和密码时,用户代理显示给用户看的验证域字符串。可以使用一些简单的句子,例如“访问squid的缓存代理”。
credentialsttl参数指定squid内在的缓存验证结果的时间数量。较大的值减少了外部验证器进程的负载,但加长了刷新期,直到squid检测到验证数据库的改变。注意,这仅影响到积极结果(例如成功的验证),消极的结果不会被squid缓存。默认的TTL值是2小时。
如下是个完整的示例:
auth_param basic program /usr/local/squid/libexec/pam_auth

auth_param basic children 10

auth_param basic realm My Awesome Squid Cache

auth_param basic credentialsttl 1 hour

acl KnownUsers proxy_auth REQUIRED

http_access allow KnownUsers
下面我将讨论squid自带的基本验证辅助器程序。

12.2.1 NCSA

./configure —enable-basic-auth-helpers=NCSA
NCSA验证辅助器相对流行,这归咎于它的简单性和历史原因。它将用户名和密码存储在一个单独的文本文件里,类似于Unix的/etc/passwd文件。这个密码文件格式最初是作为NCSA HTTP服务器项目的一部分发展而来的。在squid.conf里,只须指定密码文件的路径作为程序的单一命令行参数。
auth_param basic program /usr/local/squid/libexec/ncsa_auth

/usr/local/squid/etc/passwd
可以使用Apache自带的htpasswd程序来创建和更新密码文件。也可以在 http://www.squid-cache.org/htpasswd/ 这里下载。在该页面里,你也可以下载chpasswd CGI脚本,它允许用户改变自己的密码(假如必要)。

12.2.2 LDAP

./configure —enable-basic-auth-helpers=LDAP
LDAP辅助器是到轻量级目录访问协议(LDAP)服务器的接口。在编译squid_ldap_auth辅助器之前,OpenLDAP库和头文件必须安装到系统中。可以在这里找到OpenLDAP:http://www.openldap.org/.
squid_ldap_auth程序至少需要2个参数:基本开放名(DN)和LDAP服务器主机名。例如:
auth_param basic program /usr/local/squid/libexec/squid_ldap_auth

-b "ou=people,dc=example,dc=com" ldap.example.com
LDAP辅助器有Unix的man页,描述了其所有选项和参数。然而,在运行make install时,通常并未安装squid的这个man页。进入源代码树,手工运行nroff,你可以读到这个man页。例如:
% cd helpers/basic_auth/LDAP

% nroff -man squid_ldap_auth.8 | less

12.2.3 MSNT

./configure —enable-basic-auth-helpers=MSNT
MSNT验证器是通过服务消息块(SMB)协议到Microsoft NT域数据库的接口。它使用一个小配置文件,叫做msntauth.conf,它必须放在$prefix/etc或—sysconfidr目录。在该配置文件里,最多可以指定5个NT域控制器。例如:
server pdc1_host bdc1_host my_nt_domain

server pdc2_host bdc2_host another_nt_domain
默认情况下,MSNT验证器允许服务器验证任何用户。然而,它也能允许或拒绝指定用户名。假如创建一个allowusers文件,仅仅在该文件里列出的用户可允许访问squid。假如你的NT服务器上有很多用户,但仅仅允许少数用户使用cache,那就可以用到这个功能。另外,可以创建一个denyusers文件。任何列举在该文件里的用户会被拒绝访问,这点甚至发生在检查allowusers文件之前。
可选择的,还可以把用户名放在proxy_auth ACL里,从而允许或拒绝指定用户名,请见6.1.2.12章的描述。
附加的文档,请见helpers/basic_auth/MSNT目录下的README.html文件。

12.2.4 Multi-domain-NTLM

./configure —enable-basic-auth-helpers=multi-domain-NTLM
multi-domain-NTLM验证器类似于MSNT,两者都会查询Windows NT域数据库。不同于MSNT最多查询5个域控制器,multi-domain-NTLM验证器要求用户在其用户名前插入NT域名,象这样:
ntdomain\username
multi-domain-NTLM辅助器程序是个相对较短的perl脚本。它依赖于CPAN的Authen::SMB包。假如你没有在perl脚本里硬编码域控制器的主机名,它会利用Samba包里的nmblookup程序来自动查找它们。perl脚本命名为smb_auth.pl,它在squid.conf里看起来如下:
auth_param basic program /usr/local/squid/libexec/smb_auth.pl
multi-domain-NTLM的文档很少,但假如你熟悉perl,通过阅读源代码就可以了解更多。

12.2.5 PAM

./configure —enable-basic-auth-helpers=PAM
感觉上,插件式验证模块(PAM)是在验证方式(例如一次性密码, kerberos, smart cards)和要求验证服务的应用(例如ssh,ftp,imap)之间的胶合剂。系统的/etc/pam.conf文件描述了对每种应用使用何种验证方式。
为了使用squid的PAM验证辅助器,你必须将"squid"作为一个服务增加到/etc/pam.conf文件,并且指定使用哪个PAM模块。例如,为了使用FreeBSD的Unix密码文件,必须将这个放在pam.conf里:
squid auth required pam_unix.so try_first_pass
为了检查Unix密码数据库,pam_auth进程必须以root运行。这是个安全风险,你必须手工设置可执行setuid root。假如pam_auth不以root运行,并且它被配置为检查Unix密码数据库,那么每个验证请求都会失败。
PAM验证器的文档以man页形式提供,可在helpers/basic_auth/PAM目录下找到。

12.2.6 SASL

./configure —enable-basic-auth-helpers=SASL
简单验证和安全层(SASL)是个IETF提议标准,文档在RFC 2222里。它是个为面向连接的协议(例如FTP,SMTP,HTTP)提供安全参数协商的协议。然而,SASL验证器类似于PAM验证器。它使用第三方库接口,查询许多不同的验证数据库。
特别的,squid的SASL验证器要求Cyrus SASL库,它由Carnegie Mellon大学开发。可在这里找到: http://asg.web.cmu.edu/sasl/.
可以配置SASL验证器来检查传统密码文件,PAM系统,或任何其他被CMU的库支持的数据库。更多信息,请见helpers/basic_auth/SASL目录的README文件。

12.2.7 SMB

./configure —enable-basic-auth-helpers=SMB
SMB是另一个对Microsoft Windows数据库的验证器。该验证器自身是一个C程序。该程序在每次与Windows域控制器会话时,执行一个shell脚本。这个shell脚本包含来自Samba包的命令。这样,在使用SMB验证器之前,你必须安装Samba。
SMB验证器程序,smb_auth取Windows域名作为参数。例如:
auth_param basic program /usr/local/squid/libexec/smb_auth -W MYNTDOMAIN
通过重复-W选项,可以列举多个域。完全的文档,请见:
http://www.hacom.nl/~richard/software/smb_auth.html

12.2.8 YP

./configure —enable-basic-auth-helpers=YP
YP验证器检查系统的"Yellow Pages"(例如NIS)目录。为了在squid里使用它,必须在验证器命令行里提供NIS域名和密码数据库的名字,通常是passwd.byname:
auth_param basic program /usr/local/squid/libexec/yp_auth my.nis.domain passwd.byname
yp_auth程序相对简单,但没有任何文档。

12.2.9 getpwnam

./configure —enable-basic-auth-helpers=getpwnam
该验证器是个简单的到getpwnam()函数的接口,该函数在Unix系统的C库里。对给定的用户名,getpwnam()函数查询系统的密码文件。假如使用YP/NIS,getpwnam()也检查那些数据库。在某些操作系统上,它也利用PAM系统。假如你的cache用户在squid运行的系统上也有登陆帐号,就可使用该验证器。另外,可在密码文件里对cache用户建立nologin帐号。

12.2.10 winbind

./configure —enable-basic-auth-helpers=winbind
Winbind是Samba套件的功能之一。它允许Unix系统利用Windows NT的用户帐号信息。winbind验证器是Samba winbindd服务进程的客户端。在使用该验证器之前,必须安装Samba和运行winbindd服务。
winbind基本验证器的名字是wb_basic_auth。它在squid.conf里看起来如下:
auth_param basic program /usr/local/squid/libexec/wb_basic_auth

12.2.11 基本验证API

在squid和基本验证器之间的接口非常简单。squid发送用户名和密码到验证器进程,它们以空格分开并以新行结束。验证器在其stdin里读取用户名和密码。在检查信用项后,验证器将OK或ERR写入stdout。
任何“不安全的URL”字符会参照RFC 1738规则进行编码。这样,名字 "jack+jill"变成了"jack%2bjill"。squid接受包含空格的用户名和密码。例如"a password"变成了"a%20password"。在解码用户名和密码后,验证器程序能处理空格和其他的特殊字符。
可在命令行上轻易测试基本验证器。简单的在终端窗口里运行验证器程序,并输入用户名和密码。或者,可以这样做:
% echo "bueller pencil" | ./ncsa_auth /tmp/passwd

OK
如下是个用perl写成的简单的验证器模板:
#!/usr/bin/perl -wl

use URI::Escape;

$|=1; # don't buffer stdout

while (<>) {

($u,$p) = split;

$u = uri_unescape($u);

$p = uri_unescape($p);

if (&valid($u,$p)) {

print "OK";

} else {

print "ERR";

}

}

sub valid {
my $user = shift;
my $pass = shift;

}

12.3 HTTP摘要验证

摘要验证被设计为比基本验证更安全。它广泛利用了加密hash函数和其他技巧。本质上,与发送明文密码不同,用户代理发送密码、用户名和其他信息的"消息摘要"(见RFC 2617和O'Reilly's HTTP: The Definitive Guide的更多信息)。
HTTP摘要验证支持下列auth_param参数:
auth_param digest program command

auth_param digest children number

auth_param digest realm string

auth_param digest nonce_garbage_interval time-specification

auth_param digest nonce_max_duration time-specification

auth_param digest nonce_max_count number

auth_param digest nonce_strictness on|off
program, children, 和realm参数与基本验证的一样。与摘要验证相关的唯一不同参数是nonce。
nonce是个特殊的数据串,它偶尔改变。在验证过程中,服务器(这里就是squid)提供一个nonce值到客户端。客户端在产生摘要时要用到这个nonce值。没有nonce数据,攻击者能简单的拦截和重现(replay)摘要值来获取对squid的访问。
nonce_garbage_interval参数告诉squid每隔多久清空nonce缓存。默认值是每5分钟。对于有许多摘要验证客户端的非常忙的cache,更频繁的回收nonce碎片可能有益。
nonce_max_duration参数指定每个nonce值保持多长时间的有效期。当客户端试图使用某个已过期的nonce值时,squid产生401(未验证)响应,并随之发送一个新的nonce值,以便客户端能重新认证。默认值是30分钟。注意任何被截获的Authorization头部能被用于replay攻击,直到nonce值过期。然而将nonce_max_duration值设得过低,导致squid过频繁的产生401响应。对每个401响应,客户端和服务器要重新协商它们的验证信用项,这本质上浪费了用户的时间。
nonce_max_count参数对nonce值可使用多少次设置一个上限。在指定数量的请求后,squid返回401(未验证)响应和一个新的nonce值。默认是50个请求。
nonce计数是另一个设计成阻止replay攻击的功能。squid在401响应里发送qop=auth。这导致用户代理在它们的响应里包含nonce计数,并在产生摘要自身时使用这个nonce计数。nonce计数值必须逐次增加。下降的nonce计数意味着replay攻击。然而,计数可能跳跃的增加,跨过某些数值,例如:5,6,8,9。nonce_strictness 参数决定在这种情形下squid如何做。若设置为on,假如某个nonce计数不等于前次nonce计数加1,squid会返回401响应。若设置为off,squid允许不连续的nonce计数值。
如下是个完整示例:
auth_param digest program /usr/local/squid/libexec/digest_pw

auth_param digest children 8

auth_param digest realm Access to Squid

auth_param digest nonce_garbage_interval 10 minutes

auth_param digest nonce_max_duration 45 minutes

auth_param digest nonce_max_count 100

auth_param digest nonce_strictness on

acl KnownUsers proxy_auth REQUIRED

http_access allow KnownUsers
下面我将讨论squid自带的摘要验证辅助器程序。

12.3.1 password

./configure —enable-auth=digest —enable-digest-auth-helpers=password
这是squid摘要验证的简单可参考执行的方法。它展示了如何编写基于摘要验证的辅助器。这个代码简单的从明文文件里读取用户名和密码。该文件的格式类似如下:
username:password
密码文件的路径是digest_pw_auth程序的单一参数,例如:
auth_param digest program /usr/local/squid/libexec/digest_pw_auth

/usr/local/squid/etc/digest_passwd

auth_param digest realm Some Nifty Realm
squid不提供任何工具来维护这种格式的密码文件。假如你选择使用摘要验证,就必须管理自己的密码文件,可使用文本编辑器或perl脚本来做到。

12.3.2 摘要验证API

假如要编写自己的摘要验证辅助器,你必须理解在squid和辅助器进程间的通信。数据交换类似于基本验证,但稍微复杂点。
第一个不同是squid将用户名和域值,而不是用户名和密码,写往辅助器进程。这些串被引用起来,并以冒号分隔。例如:
"bobby":"Tom Landry Middle School"
第二个不同是假如用户名有效,辅助器进程返回一个MD5摘要串,而不是返回OK。与基本验证一样,假如用户不存在,或者来自squid的输入不可解析,辅助器进程返回ERR。
辅助器随着用户名,域值和密码返回一个MD5摘要。这3个串连在一起,并以冒号分割:
username:realm:password
记住密码不会在HTTP请求里发送。辅助器从数据库里(类似于password辅助器使用的明文文件)获取用户的密码。例如,假设Bobby的密码是CapeRs。辅助器从squid接受用户名和域值,从它的数据库里获取密码,并计算这个串的MD5校验和:
bobby:Tom Landry Middle School:CapeRs
Squid的源代码包含一个库函数叫做DigestCalcHA1( ), 它用来执行这个计算。我们可以在终端窗口里来测试这些,并观察辅助器返回什么:
% echo 'bobby:CapeRs' > /tmp/pw

% echo bogus_input | digest_pw_auth /tmp/pw

ERR

% echo "nouser":"some realm" | digest_pw_auth /tmp/pw

ERR

% echo '"bobby":"Tom Landry Middle School"' | digest_pw_auth /tmp/pw

c7ca3efda238c65b2d48684a51baa90e
Squid存储这个MD5校验和,并将其用于摘要验证算法的其他部分。注意这个校验和仅在用户改变其密码时才会改变。在squid的当前摘要执行里,只要用户保持活跃状态,这些校验和就保存在内存里。假如用户不活跃的时间达到authenticate_ttl秒,MD5校验和可能从squid的内存里移除。若该用户下次请求,squid会要求外部辅助器进程重新计算校验和。

12.4 Microsoft NTLM验证

NTLM是Microsoft的私有连接验证协议。许多组织,包括squid的开发者,通过少许可用信息以及检查网络传输,已经反向工程了该协议。可以在这里找到一些技术细节: http://www.innovation.ch/java/ntlm.html.
NTLM使用三次握手来验证一个连接。首先,客户端发送请求,它带一对标识符。接着,服务器发送回一个挑战消息(译者注:即用于加密的随机种子)。第三步,客户端再次发送其请求,包含了对这个种子的响应。这时,连接验证成功,在同一连接里的任何进一步的请求,不再需要挑战/响应信息。假如关闭了连接,客户端和服务器必须重复整个三次握手过程。持续连接有助于减少NTLM验证的负载。
NTLM使用加密的hash函数和nonce值,类似于摘要验证,尽管专家认为NTLM要脆弱一些。
NTLM验证支持下列auth_param参数:
auth_param ntlm program command

auth_param ntlm children number

auth_param ntlm max_challenge_reuses number

auth_param ntlm max_challenge_lifetime time-specification
program和children参数与基本验证和摘要验证的相同。剩余的参数决定squid每隔多久重用某个挑战令牌。
max_challenge_reuses参数指定某个挑战令牌可被重用多少次。默认值是0,所以这个令牌永不会被重用。增加该值可以减少squid和NTLM辅助器进程的计算负载,但带来了弱化协议安全的风险。
类似的,max_challenge_lifetime参数对令牌重用设置了一个时间限制,即使max_challenge_reuses次数还没有用完。默认值是60秒。
如下是个完整示例:
auth_param ntlm program /usr/local/squid/libexec/ntlm_auth foo\bar

auth_param ntlm children 12

auth_param ntlm max_challenge_reuses 5

auth_param ntlm max_challenge_lifetime 2 minutes

acl KnownUsers proxy_auth REQUIRED

http_access allow KnownUsers
Squid自带了下列NTLM验证辅助器程序:

12.4.1 SMB

./configure —enable-auth=ntlm —enable-ntlm-auth-helpers=SMB
NTLM的服务消息块(SMB)验证器与基本验证的相似。用户简单的提供他们的windows NT域名,用户名和密码即可。该验证器能在多个域控制器间负载均衡。域和控制器名字出现在命令行中:
auth_param ntlm program /usr/local/squid/libexec/ntlm_auth

domain\controller [domain\controller …]

12.4.2 winbind

./configure —enable-auth=ntlm —enable-ntlm-auth-helpers=winbind
该验证器类似于基本验证的winbind。两者都要求安装和运行了Samba winbindd服务。NTLM的winbind验证器名字是wb_nltm_auth。它在squid.conf里的配置看起来如下:
auth_param basic program /usr/local/squid/libexec/wb_ntlm_auth

12.4.3 NTLM验证API

在squid和NTLM验证器之间的通信相对于基本和摘要验证而言,要复杂得多。理由之一是每个辅助器进程实际创建了它自己的挑战令牌。这样,辅助器变得与状态相关,squid必须记住哪个连接属于哪个辅助器。
Squid和辅助器进程使用一些2字符的代码来指示它们正在发送什么。这些代码如下:
YR
在squid需要新的挑战令牌时,它发送这个给辅助器。这总是在两个进程间的第一个通信。它也可能在squid需要新挑战令牌的任何时候发生,归咎于auth_param max_challenge_lifetime和max_challenge_uses参数的设置。辅助器响应一个TT消息。
TT 挑战令牌
辅助器发回这个消息给squid,包含了一个挑战令牌。它是对YR请求的响应。挑战令牌用base64编码,在RFC 2045里有定义。
KK 信用项
当squid想要验证某个用户的信用项时,它发送这个到辅助器。辅助器响应如下几个代码:AF, NA, BH, 或LD。
AF 用户名
当用户的验证信用项有效时,辅助器发回这个消息给squid。辅助器在本消息里发送用户名,是因为squid不去尝试解码NTLM验证头部。
NA 理由
当用户的信用项无效时,辅助器发回这个消息给squid。它也包含了一个“理由”字符串,squid能将其显示到错误页面。
BH 理由
当验证过程失败时,辅助器发回这个消息给squid。这点可能发生在,例如,辅助器进程无法与windows NT域控制器通信的时候。squid拒绝用户请求。
LD 用户名
这个辅助器到squid的响应类似于BH,除了squid允许用户请求之外。类似于AF,它返回用户名。为了使用该功能,必须在编译squid时使用 —enable-ntlm-fail-open选项。
既然该协议相对复杂,你最好从包含在squid源代码发布里的2个基本验证器起步。no_check辅助器用perl写的,fakeauth用C写的。可以在helpers/ntlm_auth目录找到它们。

12.5 外部ACL

在版本2.5,Squid包含了一个新功能,叫做外部ACL。这些ACL元素在外部辅助器进程里被执行。你指示squid将某些信息写往辅助器,然后辅助器以OK或ERR来响应squid。请参考6.1.3章关于external_acl_type语法的描述。这里,我仅仅讨论一些特殊的外部ACL辅助器程序,它们随着squid的源代码发布。

12.5.1 ip_user

./configure —enable-external-acl-helpers=ip_user
该辅助器读取用户名和客户端IP地址作为输入。它根据配置文件来检查这2个值,以决定其是否有效。为了使用这个ACL辅助器,要在squid.conf里增加如下行:
external_acl_type ip_user_helper %SRC %LOGIN

/usr/local/squid/libexec/ip_user -f /usr/local/squid/etc/ip_user.conf

acl AclName external ip_user_helper
对每个请求,%SRC替换成客户端的IP地址,%LOGIN替换成用户名。ip_user.conf配置文件有如下格式:
ip_addr[/mask] user|@group|ALL|NONE
例如:
127.0.0.1 ALL

192.168.1.0/24 bob

10.8.1.0/24 @lusers

172.16.0.0/16 NONE
该配置文件导致ip_user对任何来自127.0.0.1的请求返回OK,对来自192.168.1.0/24网络的Bob的请求返回OK,对来自10.8.1.0/24网络的,位于luser组里的任何用户名返回OK。对来自172.16.0.0/16网络的任何请求返回ERR。它也对任何不在这个列表里出现的地址和用户名对返回ERR。

12.5.2 ldap_group

./configure —enable-external-acl-helpers=ldap_group
该辅助器决定是否某个用户属于一个特殊的LDAP组。在acl行里指定LDAP组名。它可能在你的配置文件里看起来如下:
external_acl_type ldap_group_helper %LOGIN /usr/local/squid/libexec/squid_ldap_group

-b "ou=people,dc=example,dc=com" ldap.example.com

acl AclName external ldap_group_helper GroupRDN …
注意为了编译squid_ldap_group辅助器程序,你必须在系统中安装OpenLDAP库(http://www.openldap.org )。

12.5.3 unix_group

./configure —enable-external-acl-helpers=unix_group
该辅助器在Unix组数据库(例如/etc/group文件)里查找用户名。在辅助器的命令行指定要检查的组:
external_acl_type unix_group_helper %LOGIN

/usr/local/squid/libexec/check_group -g group1 -g group2 …

acl AclName external unix_group_helper
另外,可在acl行指定组。这样就允许对不同的组使用相同的辅助器:
external_acl_type unix_group_helper %LOGIN /usr/local/squid/libexec/check_group

acl AclName1 external unix_group_helper group1 …

acl AclName2 external unix_group_helper group2 …

12.5.4 wbinfo_group

./configure —enable-external-acl-helpers=wbinfo_group
该辅助器是个简短的perl脚本,它利用了Samba包的wbinfo程序。wbinfo是winbindd服务的客户端。对每个请求,该脚本期待一个单一的Unix组名跟随在用户名后。这样,必须在acl行里放置组名:
external_acl_type wbinfo_group_helper %LOGIN /usr/local/squid/libexec/wbinfo_group.pl

acl AclName external wbinfo_group_helper group

12.5.5 winbind_group

./configure —enable-external-acl-helpers=winbind_group
该辅助器用C写成,也要求winbindd服务提供的windows NT用户名的组成员关系。它基于基本验证和NTLM验证的winbind辅助器。可在acl命令行指定多个组名:
external_acl_type winbind_group_helper %LOGIN /usr/local/squid/libexec/wb_check_group

acl AclName external winbind_group_helper group1 group2 …

12.5.6 编写自己的外部ACL辅助器

外部ACL接口提供了许多兼容性,可以用它来执行几乎任何不被squid内在支持的访问控制检测。编写外部ACL分2步走。首先,你必须决定辅助器程序需要对什么样的请求信息来作出决定。在external_acl_type行上放置相应的关键字,紧跟着辅助器程序的路径。例如,假如你想编写一个外部ACL辅助器,它使用了客户端IP地址,用户名,和Host头部的值,那就可这样写:
external_acl_type MyAclHelper %SRC %LOGIN %{Host}

/usr/local/squid/libexec/myaclhelper
第2步是编写myaclhelper程序。它必须在stdin里读取请求元素,作出它自己的决定,然后将OK或ERR写往stdout。继续以前的示例,该perl脚本描述了如何去做:
#!/usr/bin/perl -wl

require 'shellwords.pl';

$|=1;

while (<>) {

($ip,$name,$host) = &shellwords;

if (&valid($ip,$name,$host)) {

print "OK";

} else {

print "ERR";

}

}

sub valid {
my $ip = shift;
my $name = shift;
my $host = shift;

}
参考6.1.3章关于从squid传递到辅助器的元素列表(%SRC, %LOGIN等)。注意当某个元素包含空格时,squid会在双引号里封装它。如同示例显示的那样,可以使用perl的shellwords库来解析被双引号封装的元素。
当然,为了利用外部ACL,你必须在某个acl行里引入它。无论何时,若外部辅助器返回OK,则ACL元素匹配成功。
外部ACL辅助器接口允许从辅助器提交附加的信息到squid(在OK/ERR行)。这些以keyword=value对的形式出现。例如:
OK user=hank
当前squid了解的唯一关键字是error和user。假如设置了user值,squid将它用于access.log。squid当前没有用到error值。