Configuring APM Client Side NTLM Authentication
Introduction
There have been a ton of requests on the boards for a simplified client side NTLM configuration, so based on Michael Koyfman’s excellent Leveraging BIG-IP APM for seamless client NTLM Authentication, I’ve put together this article to show the very basic requirements for setting up APM client side NTLM authentication.
So why APM client side NTLM? Like Kerberos, NTLM can provide seamless (i.e.. transparent) logon for local clients. It’s arguably not as secure as Kerberos as authentication protocols go, but if you’ve ever worked with Kerberos, you’ll likely appreciate that NTLM is simpler and a bit more flexible. APM’s client side NTLM authentication is also considerably different than the other client side methods that generally include visual policy authentication agents and a AAA configuration. This difference allows client side NTLM to be enabled and disabled per request as needed by Microsoft Exchange and Secure Web Gateway access features. APM’s client side NTLM is controlled by a feature called ECA, or External Client Authentication. Let’s jump right in and look at how ECA is used to configure NTLM. There have been some changes to the way client side NTLM functions between APM versions, so this article will focus on 11.6.
Configuration
Step 1: Create a virtual server
It may seem counter-intuitive to create the virtual server first, but you’ll need it in step 5 below. Nothing fancy here, just create a standard virtual server and assign an HTTP profile and pool. Of course if you’re offloading SSL (which you should be) also include a client SSL profile.
Step 2: Configure system DNS
APM needs to be able to resolve the Active Directory domain controller(s), so you’ll need to specify the DNS for the domain. In the BIG-IP management GUI, navigate to System -> Configuration -> Device -> DNS. In the DNS Lookup Server List section, add the IP address of any AD DNS server(s).
You can do the same in the TM shell as follows:
tmsh modify sys dns name-servers replace-all-with { [IP address of DC DNS server] }
Step 3: Create an Active Directory NTLM machine account
This step creates a computer account in the Active Directory that APM will use to validate the NTLM tokens from clients. This machine account will be used in a pass-through authentication capacity. Please see the following Microsoft article for more information on NTLM Pass-Through Authentication. In the BIG-IP management GUI, navigate to Access Policy -> Access Profiles -> NTLM -> Machine Account. Click the Create button. At a minimum you need an arbitrary profile object name, the name of the computer account to create (it must not already exists), the domain FQDN (the DCs will be resolved via DNS SRV queries), and the credentials of a user with privileges to create computer accounts. To specify a single domain controller, enter that DC’s FQDN into the Domain Controller FQDN field. Click the Join button to proceed.
You can do the same in the TM shell as follows:
tmsh create apm ntlm machine-account [profile object name] domain-fqdn [domain FQDN] machine-account-name [new machine account name] administrator-name [admin name] administrator-password ["admin password"]
If the command is successful you’ll see a new computer account in the Active Directory.
Step 4: Create an NTLM Auth Configuration
Now let’s add that computer account object to an NTLM Auth configuration. In the BIG-IP management GUI, navigate to Access Policy -> Access Profiles -> NTLM -> NTLM Auth Configuration. Click the Create button. Give it an arbitrary object profile name and specify the previously-created machine account name. Add the FQDN for a domain controller to the Domain Controller FQDN List field.
Note: You must add at least one domain controller here. If you don’t specify anything, users will be allowed access without any NTLM token validation. In some APM versions the Domain Controller FQDN List field displays as mandatory and in others optional. In all cases it is absolutely required.
Click the finished button to proceed. You can do the same in the TM shell as follows:
tmsh create apm ntlm ntlm-auth [profile object name] machine-account-name [machine account object name]
Step 5: Enable the ECA profile for a specific virtual server
Unlike the other APM client side authentication methods, there’s no GUI option to enable APM client side NTLM. To do that you need to apply the ECA profile to a virtual via the TM shell.
tmsh modify ltm virtual [virtual server name] profiles add { eca }
Step 6: Create an iRule to enable client side NTLM
This is where all of the magic happens. Create this very simple iRule and apply it to your virtual server:
when HTTP_REQUEST { ECA::enable ECA::select select_ntlm:/Common/my-ntlm-machine-auth }
That’s it. You need to enable ECA and then specify the name of the NTLM Auth configuration object (created in step 4 above). I would also point out here that client side NTLM authentication is a bit different from Kerberos in that ECA is generally going to issue a 401 Unauthorized NTLM challenge on every new request. If this proves to add too much overhead, the following modification to the above iRule will allow NTLM to be processed once at the beginning of the session. The APM session cookie is used thereafter to maintain the session.
when HTTP_REQUEST { if { [ACCESS::session data get session.ntlm.last.result] eq 1 } { ECA::disable } else { ECA::enable ECA::select select_ntlm:/Common/my-ntlm-machine-auth } }
Step 7: Create an access profile
Create a standard access profile and configure the visual policy like this:
There’s nothing to configure inside the NTLM Auth Result agent so it’s just there to validate the returned session.ntlm.last.result session variable. Add this access profile to the virtual server.
Step 8: Modify the client browser to support NTLM authentication
By default modern browsers do not, for obvious security reasons, send credentials to any web site that asks for them, so you have to explicitly define what sites the browser can send credentials to. For Microsoft Internet Explorer that’s as simple as adding the site to the Local Intranet Sites list. In Internet Explorer, go to Tools -> Internet Options. Open the Security tab, select Local intranet and then click the Sites button. Now click the Advanced button. Add the APM virtual server’s URL here. You can specify the exact URL here (ex. https://ntlm-test.domain.com) or a wildcard (ex. *.domain.com) to cover everything under a given domain.
This should also cover Chrome and Opera running in Windows. For Firefox, navigate to the config URL at about:config and type “trusted” in the Search field. You’ll see a short list of keys with the word “trusted” in them. Double click the “network.automatic-ntlm-auth.trusted-uris” key and add either the full FQDN of a specific APM virtual server (ex. ntlm-test.domain.com) or for an entire domain just the domain component itself (ex. .domain.com).
Testing and Troubleshooting
With your browser(s) configured, go ahead and test. If you get prompted for username and password, NTLM authentication has failed. Probably one of the best first things to do is to open a console (SSH) shell and tail the APM and LTM logs. In many cases the error will be screaming at you from one of these logs.
# cd /var/log # tail –f ltm apm
Here are some possible causes for client side NTLM authentication to fail:
-
Your browser isn’t correctly configured to send credentials to this site: Review the browser’s security configurations. I mentioned earlier that IE’s Local intranet sites list must include the FQDN of the APM virtual server. Make sure you’re indeed using the Local intranet sites list and not one of the other sites lists. There is also another setting in IE that can cause issues. This setting is enabled by default, but you could be in an environment where it has been disabled by policy. Under the Security tab of IE’s Internet Options, click on the “Custom level…” button, scroll all the way to the bottom of that list and look for the “Automatic logon only in Intranet zone” option. This needs to be checked and is the reason why you add the APM virtual server to the Local intranet sites list.
-
You’re not logged in as a domain member and/or your workstation is not domain joined: Check that you’re actually logged into the domain from a domain-joined workstation.
-
APM can’t access the specified domain controller in the NTLM Auth config: You may see messages in the LTM log like “NT_STATUS_INVALID_COMPUTER_NAME”. This is indicating that APM cannot resolve the address of the domain controller specified in the NTLM Auth configuration. If the domain controller just isn’t available, you may see the “NT_STATUS_HOST_UNREACHABLE” error message.
-
NTLM is not enabled or configured correctly in the Active Directory: You may see messages in the APM log like “NT_STATUS_NETWORK_ACCESS_DENIED” or “NT_STATUS_PIPE_NOT_AVAILABLE”. These are indication that there’s probably something wrong on the Windows domain controller side. You may want to take a look at local or domain group policy settings and NTLM event logs.
-
Worst case the NTLM machine account is corrupt: If all else fails, delete and recreate the NTLM machine account. You’ll need to delete it in APM and in the domain. Wait for replication to finish if there are multiple DCs and you’re using the same machine name, or simply use a different machine name.
Let’s now see what that client side NTLM authentication looks like on the wire. For this part I’m going to fire up WireShark and filter on “ntlmssp”
The ECA profile is responsible for generating the 401 Unauthorized response to the client’s initial request. In that 401 response is the WWW-Authenticate header and NTLM challenge. If there’s something wrong you may also see error messages manifest in the Wireshark captures.
Cross-domain Considerations
Client side APM NTLM authentication natively works across domains if the domains are in a forest trust, external two-way trust, or external one-way outgoing trust. For non-trusting domains, since the NTLM Auth config profile is assigned first, there’s no native way to switch between profiles based on something in the client’s NTLM challenge response. If you can identify the clients by some other characteristic, a unique IP subnet for example, that might be an option.
Expanding Possibilities
Now that we have APM client side NTLM humming along, let’s look at some other things you can do with it. A successful client side NTLM authentication will produce a few interesting session values:
-
session.logon.last.username – the APM session variable that contains the logged in username
-
session.logon.last.domain – the APM session variable that contains the domain of the logged in user
-
session.logon.last.machinename – the APM session variable that contains the logged in user’s workstation name
These session variables can be used and evaluated inside the visual policy and in iRules. For example, let’s say you want to do an AD query with the username to see if the user is in a specific AD group:
The ECA profile also creates three other values that can be used in iRules:
-
ECA::status – the authentication status for that individual request. It’s usually either STATUS_SUCCESS or STATUS_ACCESS_DENIED
-
ECA::username – the same information in the username session variable
-
ECA::domainname – the same information in the domain session variable
-
ECA::client_machine_name – the same information in the machine name session variable
Since the ECA profile is also enabled at will, there are some other things you can do with it. One example would be to enable and disable client side NTLM based on the requested URI:
when HTTP_REQUEST { if { [HTTP::uri] starts_with “/protected_uri” } { ECA::enable ECA::select select_ntlm:/Common/my-ntlm-machine-auth } else { ECA::disable } }
And finally you have two ECA events, ECA_REQUEST_ALLOWED and ECA_REQUEST_DENIED that can be used to trigger specific actions on successful authentication or denied logon attempts, respectively. Well that’s it for now. If you have any questions please post them below and I’ll try to answer. Otherwise stay tuned for more BIG-IP APM articles.
Thanks.
- Steph_69890Nimbostratus
From my point of view, when facing this, the user/pass is correct, but the user only need to change is password. If user access the backend RDP server, then the user will be force to change it. Michael, do you have any idea how I can let a user access when facing STATUS_PASSWORD_MUST_CHANGE? Probably an iRules.
- Ali_KhanNimbostratus
Hi Kevin,
I tried this setup in my Lab but i am really struggling with APM to respond with a 401 Unauthorized response. ECA profile enabled in Vs Machine account working correctly irule gets triggered but whenever i try logging an ECA status i get TCL error which confirms that APM is not generating a 401 unauth response.
TCL error: /Common/NTLM-AUTH-ECA-IRULE - plugin_tcl_command_execute: Error sending plugin message. invoked from within "ECA::status"
Checked browser settings (IE), machine is domain joined and i logged in using domain user etc Just running out of ideas. I just get Your session could not be established and in APM logs i see entries of:
Msg: variable "session.ntlm.last.result" was not found in the local cache for session "e5f4c05e"
Any tip will be greatly appreciated. I can share full config if that helps, please let me know. Regards, Ali
- Ali_KhanNimbostratus
OK Just started seeing below TCL error,
Apr 6 16:12:57 BigIp-01 err tmm[16353]: 01220001:3: TCL error: /Common/NTLM-AUTH-ECA-IRULE - Operation not supported (line 1) invoked from within "ECA::select select_ntlm:/Common/NTLM_Auth_Config"
Apr 6 16:12:57 BigIp-01 err tmm1[16353]: 01220001:3: TCL error: /Common/NTLM-AUTH-ECA-IRULE - Operation not supported (line 2) invoked from within "ECA::select select_ntlm:/Common/NTLM_Auth_Config"
- Ali_KhanNimbostratus
Well!! I had to upgrade to 11.6 HF8 in the end from 11.6.0 Base version. All working with following iRule.
when HTTP_REQUEST { if { [ACCESS::session data get session.ntlm.last.result] eq 1 } { ECA::disable } else { ECA::enable ECA::select select_ntlm:/Common/NTLM_Auth_Config } }
If i dont check for session.ntlm.last.result APM keeps generating 401 and the pop-up.
Thanks to the contributor.
- AneshCirrostratus
Can this solution be applied for an explicit forward proxy?
What are you looking for with explict forward proxy? If you're looking to do NTLM auth to explicit proxy, then it's already built into the product: https://support.f5.com/kb/en-us/products/big-ip_apm/manuals/product/apm-secure-web-gateway-implementations-12-1-0/6.html
- AneshCirrostratus
I dont have SWG licensed, the F5 will be a ssl forward proxy and decrypt https traffic and sends it through a Bluecoat device, the Authentication of the client will be done by F5 and credentials passed to Bluecoat via HTTP header. So will the above mentioned solution work for this setup?
It's a bit misleading, but you don't need to have SWG licensed in order for NTLM-authenticated Explicit proxy to work - that can be done just via APM. You'll need to insert a X-User header in the request to indicate username to Bluecoat upstream via Per-Request Policy VPE agent.
- AneshCirrostratus
is the requirement misleading?
- AneshCirrostratus
And in the document linked under section "Creating an access profile for explicit forward proxy"..there is an option to select "SWG-Explicit.", what do i select here when SWG is not licensed?