NTLM Squid Setup using antivirus
How to Enable NTLM with Squid (with AD Integration)
Let’s discuss how to enable NTLM authentication with Squid. Before jumping into the “how”, we need to understand the components required to make this work.
Components (Our Recipe)
NTP Client
We need the Linux machine to be time-synced with Active Directory so we don’t encounter strange Kerberos errors (often caused by clock skew).Kerberos Client
We need to authenticate against Active Directory. Kerberos is the authentication platform for Windows Domain Controllers, and it’s required by Samba/Winbind to communicate with AD.Samba Winbind
We need Winbind to join the Linux machine to AD and retrieve Active Directory users/groups.Squid Server
This is the proxy server we are enabling NTLM authentication on.Antivirus with ICAP Capability
We need to protect the gateway from viruses. The antivirus must be ICAP-enabled because Squid will use ICAP as the client protocol to communicate with it.
Now that we know the recipe, let’s start.
1) NTP Client
Active Directory and the Linux machine hosting Squid must be time-synced.
If AD allows a clock skew of (for example) 5 minutes, and your Linux machine differs by 6 minutes, Kerberos authentication will fail—and we don’t want that 🙂.
Edit /etc/ntp.conf and add your NTP servers. It’s best practice to configure three servers:
1
2
3
server 1.1.1.1 iburst
server 2.2.2.2 iburst
server 3.3.3.3 iburst
The iburst option enables faster initial sync (often 10–15 seconds instead of 5–9 minutes), which is very useful during setup.
After saving the file, enable and start the service (name may differ depending on distro: ntp vs ntpd):
1
2
chkconfig ntp on
service ntp start
To validate sync and debugging:
ntptracentpdc(listpeers,monlist,sysinfo,ctlstats)
2) Kerberos Client
There are two common Kerberos implementations:
- MIT Kerberos
- Heimdal
Both are RFC-compliant and open source.
Before configuring, it helps to understand:
KDC (Key Distribution Center) Proposed to reduce key exchange risk. It includes:
- Authentication Server (AS)
- Ticket Granting Server (TGS)
The KDC maintains a database of secret keys for entities (hosts, users, services). These keys are used to prove identity, and the KDC also generates session keys for encrypted communication.
Kerberos Realm The realm represents the domain where that database is stored.
Example /etc/krb5.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
[libdefaults]
default_realm = DOMAIN.COM
clockskew = 3000
[realms]
DOMAIN.COM = {
kdc = 10.1.0.74
default_domain = domain.com
admin_server = 11.11.11.11
}
[logging]
kdc = FILE:/var/log/krb5/krb5kdc.log
admin_server = FILE:/var/log/krb5/kadmind.log
default = SYSLOG:NOTICE:DAEMON
[domain_realm]
.domain.com = DOMAIN.COM
[appdefaults]
pam = {
ticket_lifetime = 1d
renew_lifetime = 1d
forwardable = true
proxiable = false
minimum_uid = 1
}
The clockskew should match Active Directory configuration. For PAM options, check the man pages—they’re fairly self-explanatory.
Testing Kerberos
Run:
1
2
kinit "user"
klist
Expected output will look like:
1
2
3
Valid starting Expires Service principal
10/04/11 12:52:35 10/04/11 22:52:36 krbtgt/DOMAIN.COM@DOMAIN.COM
renew until 10/05/11 12:52:35
If you get similar output, your Kerberos config is likely correct.
3) Samba Winbind
Once Winbind is configured successfully, the Linux machine acts as a domain member. AD users/groups are mapped to local UIDs/GIDs using RID translation.
RID range sizing depends on how many objects exist in AD. My advice: keep the range large—it won’t harm.
Example smb.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
[global]
workgroup = DOMAIN # domain short name
netbios name = squid-01
security = ADS
realm = KERBEROS.REALM # DOMAIN.COM
idmap backend = rid
password server = 1.1.1.1 # AD server IP
ldap admin dn = cn=winbind,dc=Users,dc=domain,dc=com
preferred master = no
local master = no
domain master = no
dns proxy = no
# Wins should be configured: it will spare you netbios broadcast
wins server = 2.2.2.2
idmap uid = 1000-99999
idmap gid = 1000-99999
idmap backend = idmap_rid:DOMAIN=15777216-37554431
idmap config DOMAIN: default = yes
idmap config DOMAIN: backend = rid
idmap config DOMAIN: range = 15777216-37554431
idmap alloc DOMAIN: range = 15777216-37554431
winbind separator = + # some applications get confused with \
winbind enum users = yes
winbind enum groups = yes
winbind nested groups = Yes
winbind use default domain = yes
winbind refresh tickets = yes
allow trusted domains = no
encrypt passwords = yes
map to guest = Bad User
# Winbind socket tuning
socket options = TCP_NODELAY SO_RCVBUF=16384 SO_SNDBUF=16384
log level = 3 passdb:5 auth:3 winbind:3
Man pages are extremely helpful—use them.
Required Winbind Steps
1) DNS Records
Add A and PTR records in AD DNS, refresh zones on the server side, and flush DNS on the client side.
2) Join the Domain and Validate
1
2
net ads join -U winbind
net rpc join -U winbind
Test join:
1
net ads testjoin -U winbind
Validate keytab:
1
net ads keytab list -U winbind
Check trusted domains:
1
net rpc trustdom list -U winbind
List users/groups:
1
2
net ads user -U winbind
net ads group -U winbind
3) Start Winbind
Service name may be winbind or winbindd:
1
2
chkconfig winbind on
service winbind start
Validation commands:
1
2
3
4
5
6
wbinfo -a winbind%password
wbinfo -D domain
wbinfo -t
wbinfo -i winbind
wbinfo -u
wbinfo -g
If all of the above succeed, you’re ready for the next step.
4) Squid (NTLM Authentication)
Before configuration, verify a few things.
4.1 Squid Compilation Options
Squid should be compiled with these features (either install a build that includes them, or compile it yourself):
--enable-icap-client(for ICAP integration)--enable-auth(basic, negotiate, ntlm)--enable-basic-auth-helpers(ldap, multi-domain ntlm, etc.)--enable-ntlm-auth-helpers(fakeauth, no_check, etc.)--enable-external-acl-helpers(custom LDAP queries as ACL rules)
4.2 Winbind Pipe Access
Squid must be able to access the Winbind privileged pipe:
1
/var/lib/samba/winbindd_privileged
4.3 Test the NTLM Helper
1
ntlm_auth --helper-protocol=squid-2.5-basic
Provide username password and validate that it succeeds.
Squid Configuration (squid.conf)
Add these lines before your http_access rules:
1
2
3
4
5
6
7
8
9
10
auth_param ntlm program /usr/bin/ntlm_auth --helper-protocol=squid-2.5-ntlmssp
auth_param ntlm children 10
auth_param ntlm keep_alive off
auth_param basic program /usr/bin/ntlm_auth --helper-protocol=squid-2.5-basic
auth_param basic realm Squid proxy-caching web server
auth_param basic casesensitive off
auth_param basic credentialsttl 8 hours
authenticate_ttl 8 hour
Add ACL before http_access:
1
acl authenticated_users proxy_auth REQUIRED
Optional: Custom LDAP Query Authentication
Example authenticating users by sAMAccountName:
1
2
auth_param basic program /usr/sbin/squid_ldap_auth -u cn -b "bind dn" \
-D "DOMAIN\winbind" -w password -f "(sAMAccountName=%s)" 1.1.1.1
5) Antivirus Configuration (ICAP)
First, let’s define ICAP.
ICAP (Internet Content Adaptation Protocol) is a lightweight point-to-point protocol similar to HTTP. It extends proxy servers with services like:
- Content filtering
- Virus scanning
When a user requests an HTTP object, it can be:
- Fetched and scanned by the ICAP server, then returned to the proxy if clean
- Fetched by the proxy, forwarded to the ICAP server for scanning, then returned to the user if clean
These two modes are:
- REQMOD (request modification)
- RESPMOD (response modification)
We won’t cover configuring the ICAP server itself, since that depends on the antivirus vendor.
Example ICAP Client Config (Kaspersky for Proxy v5.5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
icap_enable on
icap_send_client_ip on
icap_service is_kav_req reqmod_precache 0 icap://127.0.0.1:1344/av/reqmod
icap_service is_kav_resp respmod_precache 0 icap://127.0.0.1:1344/av/respmod
adaptation_access is_kav_req allow all
adaptation_access is_kav_resp allow all
icap_preview_enable on
# Added by Kaspersky Anti-Virus installer
adaptation_service_set c1 c2
adaptation_access c1 deny icap_bypass
adaptation_access c1 deny POST
adaptation_access c1 deny url_allowed_dst_domains
adaptation_access c1 deny url_allowed_regex
adaptation_access c1 deny java_jvm
adaptation_access c1 deny apple_itunes
adaptation_access c1 allow all
Note: adaptation_service_set is used for redundancy. If you have multiple ICAP servers, this becomes very useful.