12.4 Microsoft NTLM Authentication

NTLM[2] is a proprietary connection authentication protocol from Microsoft. A number of groups, including the Squid developers, have reverse-engineered the protocol from what little information is available and by examining network traffic. You can find some technical details at http://www.innovation.ch/java/ntlm.html.

[2] NTLM apparently stands for "NT LanMan" or perhaps "NT Lan Manager."

NTLM uses a three-way handshake to authenticate a connection. First, the client sends its request with a couple of identifiers. Second, the server sends back a challenge message. Third, the client sends its request again with a response to the challenge. At this point, the connection is authenticated and any further requests on the same connection don't require any challenge/response information. If the connection is closed, the client and server must repeat the entire three-way handshake. Persistent connections help reduce this overhead for NTLM.

NTLM uses cryptographic hash functions and nonce values, similar to Digest authentication, although experts believe NTLM is weaker.

NTLM authentication supports the following auth_param parameters:

  • 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

The program and children parameters are the same as for Basic and Digest authentication. The remaining parameters determine how often Squid may reuse a single challenge token.

The max_challenge_reuses parameter specifies how many times a challenge token may be reused. The default value is 0, so that challenges are never reused. Increasing this value may reduce the computational load on Squid and the NTLM helper processes, at the risk of weakening the protocol's security.

Similarly, the max_challenge_lifetime parameter places a time limit on challenge reuses, even if the max_challenge_reuses count has not been reached. The default value is 60 seconds.

Here is a complete example:

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 comes with the following NTLM authentication helper programs:

12.4.1 SMB

./configure enable-auth=ntlm enable-ntlm-auth-helpers=SMB

The Server Message Block (SMB) authenticator for NTLM is similar to those for Basic authentication. Your users can simply supply their Windows NT domain, username, and password. This authenticator can load balance between multiple domain controllers. The domain and controller names go on the command line:

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

This authenticator is similar to winbind for Basic authentication. Both require that you have the Samba winbindd daemon installed and running. The name of the winbind Basic authenticator is wb_nltm_auth. It typically looks like this in squid.conf:

auth_param basic program /usr/local/squid/libexec/wb_ntlm_auth

12.4.3 NTLM Authentication API

The communication between Squid and an NTLM authenticator is much more complicated than for Basic and Digest. One reason is that each helper process actually creates its own challenge. Thus, helpers become "stateful" and Squid must remember which connections belong to which helpers.

Squid and the helper processes use a handful of two-character codes to indicate what they are sending. Those codes are as follows:


Squid sends this to a helper when it needs a new challenge token. This is always the first communication between the two processes. It may also occur at any time that Squid needs a new challenge, due to the auth_param max_challenge_lifetime and max_challenge_uses parameters. The helper should respond with a TT message.

TT challenge

A helper sends this message back to Squid and includes a challenge token. It is sent in response to a YR request. The challenge is base64-encoded, as defined by RFC 2045.

KK credentials

Squid sends this to a helper when it wants to authenticate a user's credentials. The helper responds with either AF, NA, BH, or LD.

AF username

The helper sends this message back to Squid when the user's authentication credentials are valid. The helper sends the username with this message because Squid doesn't try to decode the NTLM Authorization header.

NA reason

The helper sends this message back to Squid when the user's credentials are invalid. It also includes a "reason" string that Squid can display on an error page.

BH reason

The helper sends this message back to Squid when the validation procedure fails. This might happen, for example, when the helper process is unable to communicate with a Windows NT domain controller. Squid rejects the user's request.

LD username

This helper-to-Squid response is similar to BH, except that Squid allows the user's request. Like AF, it returns the username. To use this feature, you must compile Squid with the enable-ntlm-fail-open option.

Since this protocol is relatively complicated, you'll probably be better off to start with one of the two skeleton authenticators included in the Squid source distribution. The no_check helper is written in Perl, and fakeauth is written in C. You can find them in the helpers/ntlm_auth directory.

    Appendix A. Config File Reference