Lawliet LAWLIET
Book a demo

65. Active Directory: Kerberos-only (no NTLM) and Kerberos hardening

This guide describes Lawliet 1.6.3.b (the current release, a beta: earlier releases are beta. The first stable release will be 2.0.0). Screens, commands and procedures may change in later versions; the usage guide is updated with each release. Check the version your server runs under Settings > Platform or with ./lawliet version, and see the Releases page for what changed.

The Kerberos tab of a domain (AD assessment > domain > Kerberos) does two things:

Every change is made by the Lawliet agent on a domain controller of the domain (an AD write, chapter 14.5); the server holds no AD credentials. The tab needs at least one domain controller with an agent. The NTLM audit reads what the agents of the domain's Windows hosts collect, so the more hosts run an agent, the more complete the picture.

TaskPermissionFour-eyes
See the tab, the NTLM users, previewsView compliance-
Start the NTLM auditWrite to Active Directoryyes - "Write to Active Directory"
Approve enforcement (stage 3)Write to Active Directoryyes
Roll back the migration (enforcement only, or everything)Write to Active Directoryyes
Collect now, Evaluate now, pause or resume auto-advance, withdraw the approvalWrite to Active Directoryno - none of them changes the domain
Run a Kerberos action, roll one backWrite to Active Directoryyes
Check krbtgt, cancel the second krbtgt rotationWrite to Active Directoryno - read only / only stops a change

65.1 The four stages#

Before stage 1 changes anything, every Windows host with an agent reports the NTLM values it has (the snapshot, up to ten minutes; a host that does not answer is listed and gets the Windows defaults on a rollback). A rollback puts these values back.

StageWhat happensEnds when
1 AuditLawliet writes two GPOs: Lawliet NTLM Policy - Domain Controllers (linked to the Domain Controllers OU) and Lawliet NTLM Policy - Members (linked to the domain root, or the OUs you name). They only turn NTLM auditing on: Audit NTLM authentication in this domain = Enable all (DCs, events 8003/8004), Audit incoming NTLM traffic = Enable for all accounts (8002), Outgoing NTLM traffic to remote servers = Audit all (8001). Nothing is denied.the audit has run at least the minimum days (7 by default, never fewer)
2 AnalysisTwice a day Lawliet collects the NTLM findings from every Windows host with an agent (NTLM-USAGE; NTLM-DC-USAGE and KERB-RC4-USAGE on the DCs) and merges them into one list: account, client, server, event, count, last use, and a suggested fix per row.no NTLM use is left outside the exceptions, and none for the clean days (7 by default) in a row
3 ApprovalYou approve once, with the exception list exactly as it will be written (the servers, and the servers the excepted accounts were seen using). Four-eyes.- (can come any time during stages 1-2)
4 EnforcementAutomatic when stages 1-3 are done: each Lawliet GPO is backed up on the DC (Backup-GPO), then rewritten to Restrict NTLM: Deny all (in the domain on the DCs, incoming and outgoing everywhere) with the exception list, and LAN Manager authentication level = Send NTLMv2 response only, refuse LM and NTLM (LmCompatibilityLevel 5).the DC reports both GPOs written

Auto-advance. Every five minutes Lawliet re-evaluates. When every condition holds - audit GPOs written, minimum audit days, no blocker, no NTLM use outside the exceptions, the clean days, the approval, auto-advance not paused - it starts enforcement by itself. Without the approval it waits and notifies ("The NTLM audit is clean: enforcement waits for the approval"), at most once a day. The Auto-advance conditions list on the tab shows each condition as done or open.

What counts as clean. The streak is counted only from proof: from the newest NTLM use outside the exceptions, and never earlier than the audit GPOs, the first collection that shows the audit in effect on each host, or the oldest record each host's NTLM log still holds (a log that overwrote itself proves nothing before its oldest record; a collection in between that overlaps closes the gap).

Blockers (each listed with its host): an excepted account using NTLM to a server that is not on the approved list (Windows would block it: approve again), Lawliet's own directory sign-in over LDAP without TLS (signed-and-sealed or plain: switch it to LDAPS or StartTLS first), a host with no data yet, data older than 36 hours (agent offline), auditing not in effect on a host (the GPO has not applied yet, or a GPO with higher precedence overrides it - run gpupdate /force or wait for the next refresh), a list cut off in transit, more events than one collection reads, more distinct uses than one collection lists, no domain controller with an agent, and Lawliet's own deployment credentials that log in with NTLM (they would stop working: switch them to Kerberos first). Computers without an agent are a warning: NTLM with domain accounts to them is still seen at the domain controllers, NTLM with their local accounts is not.

65.2 Procedure: start the NTLM audit#

  1. AD assessment, select the domain, open the Kerberos tab.
  2. Under Kerberos-only migration (no NTLM), optionally list the Member OUs to link (one per line, for example OU=Servers,DC=corp,DC=lan; empty links the members' GPO at the domain root, so every computer gets it).
  3. Set Audit at least (days) (7 or more) and Clean days before enforcing.
  4. Click Start the NTLM audit. The request waits for a second administrator (Approvals); once signed, the DC agent writes both GPOs. Stage 1 shows Audit GPO write pending until the DC has reported, then counts the audit days.

Hosts pick the GPOs up at their next policy refresh (up to 90 minutes, or gpupdate /force). The first collection is queued two hours after the GPOs are written; Collect now queues one at once.

65.3 Reading the NTLM users and the suggested fixes#

The NTLM users table lists every use the audit saw, uses outside the exceptions first:

Suggested fixMeaning
Reached by IP addressThe client connects to an IP address; Kerberos needs a name. Use the DNS name.
Local or foreign accountA local (or another domain's) account never gets a ticket from this domain. Use a domain account, or except the server.
Client is not a computer of this domainA non-domain host cannot get tickets. Join it, or except the server it reaches.
Server is not a computer of this domainExcept it, or move the service into the domain.
Application ... register an SPNA web or database application falls back to NTLM: register an SPN for its service account (setspn -S HTTP/name account) and set it to Negotiate/Kerberos.
Short nameConnect with the FQDN, or register the short-name SPN too.
Anonymous NTLMA null session: give the program an account, or except the server.
Find why Kerberos was not usedA missing or duplicate SPN (setspn -X), clock skew, or no DC in reach; klist on the client shows its tickets.

Except server on a row adds its server to the exception list of the approval form. Hosts (collapsed) shows each host's audit state, newest data and problems.

65.4 Procedure: approve enforcement (stage 3)#

  1. Fix what you can (the suggested fixes), then fill Server exceptions (a name, an FQDN, a *.suffix with at least two labels, an SPN or an IPv4 address) and Account exceptions (DOMAIN\name - with the domain: OTHER\svc is not CORP\svc).
  2. Set Clean days required.
  3. Click Check the exception list. It shows the servers excepted through the accounts: the servers the audit saw those accounts use NTLM to. They are part of what is signed.
  4. Click Approve enforcement (offered only after the check, and checked again after any edit); a second administrator signs it under Approvals and reads the servers, the accounts, the servers excepted through the accounts and the clean days. If those servers have changed by the time the approval runs (a new collection saw the account somewhere else), the approval is refused: check and approve again.

Windows can only except servers (Add server exceptions in this domain on the DCs, Add remote server exceptions everywhere); a short name is written in its FQDN form too. An excepted account keeps NTLM only to the servers signed with the approval: if it later uses NTLM to another server, that use is not clean and blocks enforcement until it is approved again. Excepted servers that are computers of the domain also get a Deny Apply Group Policy on the members' GPO, so they keep accepting incoming NTLM. Each such server must be found as a computer object in the latest AD collection by its sAMAccountName (<name>$, as the domain controller looks it up); until it is, enforcement does not start (blocker "Excepted server(s) with no computer object"). A domain server is excepted by its computer name only. An IP address in the exception list is refused ("10.0.0.5 is an address: add the computer name if it is a domain computer"), unless it is not a domain computer (a NAS, an appliance, a workgroup host): tick ... is not a domain computer under Check the exception list. A marked address only goes into the clients' allow list (ClientAllowedNTLMServers), never the domain controllers' list. The address of a domain controller is never accepted: after each collection (and every 12 hours; every 15 minutes while a lookup failed) the DC agent lists the domain controllers live from the directory and resolves the DNS A/AAAA records of each (a failed query is retried once). A result older than 24 hours is not trusted. No address can be marked while any domain controller has no address or a lookup error, or while the live list, the collection and the enrolled DC agents disagree ("a domain controller was added or removed since the last collection: collect again"). An address written in another numeric form (10.9.0.01, 0x0a.9.0.1, 167772161) is read as the address it is. The domain controller names and addresses the marks were checked against are signed with the approval; if they change before enforcement, enforcement is refused until the list is approved again. If the domain controller still reports it could not deny one when writing, enforcement counts as failed ("exception not in force on <server>"): what was written is rolled back and the approval withdrawn; the reason stays in the final message and notification.

Withdraw approval removes it (enforcement will not start, even if Lawliet had already evaluated the audit as clean). Pause auto-advance stops the automatic start without withdrawing the approval; Resume auto-advance re-arms it.

65.5 Enforcement and what to watch#

When enforcement starts you are notified ("NTLM enforcement started"). The DC writes the domain controllers' GPO first and the members' GPO once the first is reported. Once the DC has written both GPOs, every host with an agent runs gpupdate /force and reads its NTLM values back; the stage becomes enforced ("NTLM is denied in the domain") only when every host reports the deny values. A host that does not (not refreshed yet, a GPO with higher precedence overriding the Lawliet one) is named after two hours as Partially enforced (notified once), and read again every 15 minutes. An excepted server that runs an agent is not read back: it does not apply the members' GPO by design, and is listed as excepted ("NTLM is still allowed on the excepted servers"). Blocked attempts keep being logged (the audit settings stay on). Enforcing again after a rollback first removes the Preferences "Delete" items the rollback left in the GPOs, so they cannot undo the deny values.

A Lawliet GPO someone changed during the audit. Every write to a Lawliet GPO carries the version Lawliet left on it at its last write. If someone edited either NTLM GPO since then (for example during the audit weeks), the first enforcement write is refused before anything is written: the stage stays in the audit, the approval is withdrawn, you are notified, and the stage says Someone changed the Lawliet policy (name) since Lawliet wrote it, with its version and when it changed. There is no automatic rollback, because nothing changed. Review the change; to go on, approve again (65.4) and tick Overwrite the changes someone made to (GPO). The approval summary the second administrator signs says it overwrites the change, and the GPO is backed up before the write. If the GPO was removed, Lawliet does not recreate it to enforce: roll back everything (65.6), which writes the values from before back through a temporary rollback policy, and start again.

The members' GPO is checked again when it is written. If someone edits it in the short gap between the two writes, that write is refused and the enforcement fails as described below.

If writing either GPO fails, the DC agent restores that GPO from its backup itself, Lawliet rolls back what was written (as in 65.6: the values from before put back on the hosts and read back), and withdraws the approval: you approve again to retry.

65.6 Procedure: roll back#

The NTLM settings are Security Options outside the Policies registry keys: a host keeps them when a GPO stops carrying them ("tattooing"), and Windows has no Policies-key form of them. So removing or restoring a GPO would leave NTLM denied on every host. A Lawliet rollback therefore:

  1. writes the values from before into the Lawliet GPOs (on the DC that wrote them, which holds their backups; the GPO is backed up again first): a value the hosts had is written back (for example LmCompatibilityLevel 3), a value they did not have is deleted on the hosts by a Group Policy Preferences registry item (action Delete). Where hosts had different values, the Windows default is written and the hosts are listed. The Deny Apply that kept the excepted servers out of the members' GPO is taken off, so they apply the values written back too;
  2. has every host with an agent run gpupdate /force and read its NTLM values back, and waits until each has the values from before (or the audit values, for Roll back enforcement). A host that does not yet is listed with the values it still has; after two hours the stage says Partially rolled back: hosts ... still deny NTLM, and Lawliet reads those hosts again every 15 minutes - the reverted policy stays linked meanwhile;
  3. for Roll back everything only, keeps the GPOs linked for the rollback grace (2 hours by default, set at start: computers without an agent refresh too), then removes the GPOs Lawliet created (or restores one that existed before from its backup), and reads every host once more.

Only then is it Rolled back (or back to auditing). Both need a second signature, and are refused while a GPO write is still in flight.


65.7 Kerberos hardening: preview, approval, rollback#

Under Kerberos hardening, each action has Preview: what it changes, what may break, what blocks it now, and how it is undone. Request this change is offered only when nothing blocks it, and needs a second signature; the preview is computed again on the approved run (never taken from the request). Actions are listed under Actions with their state, Roll back where a rollback exists, and Cancel second rotation for a waiting krbtgt rotation.

65.8 Enable AES on service accounts, then turn RC4 and DES off#

  1. Enable AES on service accounts (aes_enable): adds AES128 and AES256 (0x18) to msDS-SupportedEncryptionTypes of each account - by default the service accounts the RC4 audit of the domain controllers lists without AES, or the ones you tick. RC4 keeps working. The previous value of each account is recorded; Roll back writes it back. AES tickets need AES keys: an account whose password predates 2008-level domain controllers has none until its password is changed (with the service).
  2. Turn RC4 and DES off (AES only) (rc4_disable): blocked until the RC4 audit (KERB-RC4-USAGE on every domain controller, events 4768/4769 by encryption type, audited for at least the minimum days) shows no RC4 or DES ticket and no service account without AES. It then writes the GPO Lawliet Kerberos AES only (Configure encryption types allowed for Kerberos = AES128, AES256, future types), linked to the Domain Controllers OU and the domain root, and sets the service accounts to AES only. The accounts are changed only once the GPO is written. Roll back restores the GPO from its backup (or removes it) and each account's previous value. If someone changed the GPO since an earlier run of this action wrote it, the write is refused and nothing is changed: the action fails with Someone changed the Lawliet policy Lawliet Kerberos AES only since Lawliet wrote it. Run again, overwriting the changes sends it once more after a second signature, and the GPO is backed up first.

65.9 krbtgt: the safe double rotation#

  1. Click Check krbtgt: the DC agent reads AD replication health, the krbtgt key version on every domain controller and the maximum ticket lifetime (Default Domain Policy, 10 hours by default).
  2. Preview shows the result, the wait between the two rotations (maximum ticket lifetime + 2 hours, at least 12) and what blocks it: unhealthy replication, an unreachable domain controller, a check older than an hour, a krbtgt changed less than the wait ago.
  3. Request this change (four-eyes). The DC agent checks again itself and refuses on any of the above, or if the key version changed since the check; then it resets the krbtgt password once (a random password made on the DC, never sent or shown).
  4. Lawliet waits the wait time, checks again that replication is healthy and every writable DC has the new key, and only then rotates the second time. If the check fails, it holds and retries every hour, and notifies you.

A rotation cannot be undone (the old key is gone), so there is no rollback. Cancel second rotation stops the double rotation where it still can be stopped, and says exactly what happened: while it waits (or checks), the second rotation is never sent; once the second rotation is queued but not yet received by the DC agent, it is taken back ("it was not sent, krbtgt was rotated once only"); once the DC agent has it, cancel is refused ("already delivered ... it cannot be stopped"). Only one krbtgt rotation of a domain can be in flight at a time, and the agent runs directory changes one at a time. Read-only domain controllers have their own krbtgt_##### accounts; they are not rotated here.

65.10 Protected Users for privileged accounts#

Preview lists the privileged users that are not in Protected Users. These are never added (shown, not selectable, and refused if named): the built-in Administrator, Lawliet's break-glass / recovery account (lawliet-recovery), the accounts of Lawliet's deployment credentials and the directory sign-in bind account - Lawliet must keep logging on with them when Kerberos or the network fails. The others each show their impact: no NTLM, no DES/RC4 Kerberos, no credential caching (no offline logon), no delegation, 4-hour tickets; and, where it applies, the account has SPNs (a service running as it may fail), is configured for delegation, used NTLM in the audit, or is the built-in Administrator (keep it out as the break-glass account). Accounts with such an impact are not ticked by default. Request this change adds the ticked accounts; Roll back removes exactly the members this action added. The protections on the domain controller side need the domain functional level 2012 R2 or later.

65.11 Kerberoastable accounts#

The Kerberoastable accounts table lists enabled user accounts with an SPN (any domain user can request a ticket for them and crack it offline), ranked: privileged first, then RC4 or an old (or unknown-age) password. Each row says what to do: replace it with a group-managed service account (gMSA), until then a long random password (25+ characters), enable AES, take it out of admin groups. Tick accounts and Preview AES for N account(s) to enable AES on them (65.8).