Collect Microsoft Active Directory domain controller logs
Active Directory (AD) is a directory service developed by Microsoft for Windows network domains. An AD domain controller responds to security authentication requests within a Windows domain. Most Active Directory logging, especially for security-related activity, is done via the Windows Event Log.
Active Directory logs are essential for many reasons. They provide insights into user and group activities, including changes to permissions, account lockouts, failed logins, and other security-related events. AD logs can help in detecting suspicious activity or security breaches, troubleshooting issues, and monitoring the health and performance of your Active Directory environment. Additionally, you can use your domain controller logs to meet regulatory compliance requirements and auditing policies.
There are two crucial logs to monitor on a domain controller:
- Active Directory security logs
-
These logs contain information about authentication and authorization attempts, such as successful and failed logins, changes to security policies, and account lockouts.
- Directory Service logs
-
These logs provide information about Active Directory operations, such as changes to user accounts, group memberships, and permissions.
Ultimately, both fall into the "critical logs" category from an IT security perspective.
Collect Active Directory security logs
The domain controller generates events for suspicious activities, including attempts to change Active Directory modes or attempted replay attacks.
You can monitor these security logs via Windows Event Log by filtering for event source ActiveDirectory_DomainService
.
The event IDs to monitor always depends on your use case. There is no silver bullet here. Nevertheless, below is a list of essential event IDs we consider a must-collect in any scenario.
Event ID | Description |
---|---|
4618 |
A monitored security event pattern has occurred. |
4649 |
A replay attack was detected. May be a harmless false positive due to a misconfiguration error. |
4719 |
System audit policy was changed. |
4765 |
SID History was added to an account. |
4766 |
An attempt to add SID History to an account failed. |
4794 |
An attempt was made to set the Directory Services Restore Mode. |
4897 |
Role separation was enabled. |
4964 |
Special groups have been assigned to a new logon. |
5124 |
A security setting was updated on OCSP Responder Service. |
1102 |
The audit log was cleared. |
For a complete list of Active Directory events, see Events to Monitor on Microsoft Learn.
This example uses the im_msvistalog input module to capture critical security logs on a Windows Server 2022 AD domain controller.
Windows Event Log only supports a limited number of event IDs per query. Due to this limitation, the configuration uses an Exec block to collect the required event IDs instead of listing every event ID in the query.
<Extension json>
Module xm_json
PrettyPrint TRUE
</Extension>
define SecurityIDs 4618, 4649, 4719, 4765, 4766, 4794, 4897, 4964, 5124, \
4621, 4675, 4692, 4693, 4706, 4713, 4714, 4715, 4716, \
4724, 4727, 4735, 4737, 4739, 4754, 4755, 4764, 4780, \
4816, 4865, 4866, 4867, 4868, 4870, 4882, 4885, 4890, \
4892, 4896, 4906, 4907, 4908, 4912, 4960, 4961, 4962, \
4963, 4965, 4976, 4977, 4978, 4983, 4984, 5027, 5028, \
5029, 5030, 5035, 5037, 5038, 5120, 5121, 5122, 5123, \
5376, 5377, 5453, 5480, 5483, 5484, 5485, 6145, 6273, \
6274, 6275, 6276, 6277, 6278, 6279, 6280, 4608, 4609, \
4610, 4611, 4612, 4614, 4615, 4616, 4624, 4625, 4634, \
4647, 4648, 4656, 4657, 4658, 4660, 4661, 4662, 4663, \
4672, 4673, 4674, 4688, 4689, 4690, 4691, 4696, 4697, \
4698, 4699, 4700, 4701, 4702, 4704, 4705, 4707, 4717, \
4718, 4720, 4722, 4723, 4725, 4726, 4728, 4729, 4730, \
4731, 4732, 4733, 4734, 4738, 4740, 4741, 4742, 4743, \
4744, 4745, 4746, 4747, 4748, 4749, 4750, 4751, 4752, \
4753, 4756, 4757, 4758, 4759, 4760, 4761, 4762, 4767, \
4768, 4769, 4770, 4771, 4772, 4774, 4775, 4776, 4778, \
4779, 4781, 4783, 4785, 4786, 4787, 4788, 4789, 4790, \
4869, 4871, 4872, 4873, 4874, 4875, 4876, 4877, 4878, \
4879, 4880, 4881, 4883, 4884, 4886, 4887, 4888, 4889, \
4891, 4893, 4894, 4895, 4898, 5136, 5137
define BitLockerIDs 24586, 24592, 24593, 24594
define EventlogID 1102
define SecuritySrc Microsoft-Windows-Security-Auditing
define BitLockerSrc Microsoft-Windows-BitLocker-Driver
define EventlogSrc Microsoft-Windows-Eventlog
<Input events>
Module im_msvistalog
<QueryXML>
<QueryList>
<Query Id="0">
<Select Path="Security">*[System[Provider[
@Name='%EventlogSrc%' or
@Name='%SecuritySrc%']]]
</Select>
<Select Path="System">*[System[Provider[
@Name='%BitLockerSrc%']]]
</Select>
</Query>
</QueryList>
</QueryXML>
<Exec>
if not (defined($SourceName) and
(($EventID IN (%SecurityIDs%) and $SourceName == "%SecuritySrc%") or
($EventID IN (%BitLockerIDs%) and $SourceName == "%BitLockerSrc%") or
($EventID == %EventlogID% and $SourceName == "%EventlogSrc%")))
drop();
to_json();
</Exec>
</Input>
{
"EventTime": "2023-04-04T09:28:57.792328+02:00",
"Hostname": "DC001.nxlogtest.com",
"Keywords": "4620693217682128896",
"LevelValue": 4,
"EventType": "INFO",
"SeverityValue": 2,
"Severity": "INFO",
"EventID": 1102,
"SourceName": "Microsoft-Windows-Eventlog",
"ProviderGuid": "{FC65DDD8-D6EF-4962-83D5-6E5CFE9CE148}",
"Version": 0,
"TaskValue": 104,
"OpcodeValue": 0,
"RecordNumber": 36405,
"ExecutionProcessID": 380,
"ExecutionThreadID": 3088,
"Channel": "Security",
"Message": "The audit log was cleared.\r\nSubject:\r\n\tSecurity ID:\tS-1-5-21-3589175892-3624815508-1412135724-500\r\n\tAccount Name:\tAdministrator\r\n\tDomain Name:\tNXLOGTEST\r\n\tLogon ID:\t0x800A8",
"Category": "Log clear",
"Opcode": "Info",
"Level": "Information",
"LogFileCleared.SubjectUserSid": "S-1-5-21-3589175892-3624815508-1412135724-500",
"LogFileCleared.SubjectUserName": "Administrator",
"LogFileCleared.SubjectDomainName": "NXLOGTEST",
"LogFileCleared.SubjectLogonId": "0x800a8",
"EventReceivedTime": "2023-04-04T09:28:58.795764+02:00",
"SourceModuleName": "events",
"SourceModuleType": "im_msvistalog"
}
Advanced security audit policy on an AD domain controller
The goal of security auditing is to track who did what and when. Unfortunately, auditing all users' activities generates tremendous amounts of logging and can quickly become overwhelming. However, Windows security auditing supports advanced audit policies, allowing you to implement fine-grained auditing.
You can enable AD audit logs via the Group Policy Advanced Audit Policy. This policy comprises several activity-specific subcategories, including Directory Service access. Follow these steps to enable the Advanced Audit Policy and configure DS auditing:
-
Log in to the server as a domain administrator.
-
Load the Group Policy Management Editor from Server Manager > Tools.
-
Expand the Domain Controllers organizational unit (OU), right-click on Default Domain Controllers Policy, and click Edit….
-
Expand Computer Configuration > Policies > Windows Settings > Security Settings > Advanced Audit Policy Configuration > Audit Policies > DS Access.
-
Enable all the policies in this category to start auditing Directory Service access.
Refer to Step-By-Step: Enabling Advanced Security Audit Policy via DS Access on Microsoft Learn for more information on the Advanced Audit Policy and descriptions of event IDs.
Once you enable security auditing, you can collect the relevant events with the NXLog Agent im_msvistalog input module. For example, this configuration collects all Windows security audit events of critical, warning, or error level.
<Extension json>
Module xm_json
PrettyPrint TRUE
</Extension>
<Input SecurityAuditEvents>
Module im_msvistalog
<QueryXML>
<QueryList>
<Query Id="0" Path="Security">
<Select Path="Security">*[System[Provider[@Name='Microsoft-Windows
-Security-Auditing'] and (Level=1 or Level=2 or Level=3) and
((EventID=4928 and EventID=4931) or (EventID=4932 and EventID=4937)
or EventID=4662 or (EventID=5136 and EventID = 5141))]]</Select>
</Query>
</QueryList>
</QueryXML>
<Exec>
$EventData = extract_xml("/Event/EventData", $EventXML);
if $EventData == ""
{
delete($EventData);
}
$UserData = extract_xml("/Event/UserData", $EventXML);
if $UserData == ""
{
delete($UserData);
}
delete($EventXML);
to_json();
</Exec>
</Input>
{
"EventTime": "2023-04-03T12:28:30.349741+02:00",
"Hostname": "DC001.nxlogtest.com",
"Keywords": "9232379236109516800",
"LevelValue": 0,
"EventType": "AUDIT_SUCCESS",
"SeverityValue": 2,
"Severity": "INFO",
"EventID": 5136,
"SourceName": "Microsoft-Windows-Security-Auditing",
"ProviderGuid": "{54849625-5478-4994-A5BA-3E3B0328C30D}",
"Version": 0,
"TaskValue": 14081,
"OpcodeValue": 0,
"RecordNumber": 36383,
"ExecutionProcessID": 672,
"ExecutionThreadID": 776,
"Channel": "Security",
"Message": "A directory service object was modified.\r\n\t\r\nSubject:\r\n\tSecurity ID:\t\tS-1-5-21-3589175892-3624815508-1412135724-500\r\n\tAccount Name:\t\tAdministrator\r\n\tAccount Domain:\t\tNXLOGTEST\r\n\tLogon ID:\t\t0x84C17\r\n\r\nDirectory Service:\r\n\tName:\tnxlogtest.com\r\n\tType:\tActive Directory Domain Services\r\n\t\r\nObject:\r\n\tDN:\tCN={31B2F340-016D-11D2-945F-00C04FB984F9},CN=POLICIES,CN=SYSTEM,DC=NXLOGTEST,DC=COM\r\n\tGUID:\t{88db9c05-2adb-4fe6-8dfe-26897bc823c7}\r\n\tClass:\tgroupPolicyContainer\r\n\t\r\nAttribute:\r\n\tLDAP Display Name:\tversionNumber\r\n\tSyntax (OID):\t2.5.5.9\r\n\tValue:\t7\r\n\t\r\nOperation:\r\n\tType:\tValue Added\r\n\tCorrelation ID:\t{f696f890-7c5b-41f0-bc82-aaaf73a80646}\r\n\tApplication Correlation ID:\t-",
"Category": "Directory Service Changes",
"Opcode": "Info",
"Level": "Information",
"OpCorrelationID": "{f696f890-7c5b-41f0-bc82-aaaf73a80646}",
"AppCorrelationID": "-",
"SubjectUserSid": "S-1-5-21-3589175892-3624815508-1412135724-500",
"SubjectUserName": "Administrator",
"SubjectDomainName": "NXLOGTEST",
"SubjectLogonId": "0x84c17",
"DSName": "nxlogtest.com",
"DSType": "%%14676",
"ObjectDN": "CN={31B2F340-016D-11D2-945F-00C04FB984F9},CN=POLICIES,CN=SYSTEM,DC=NXLOGTEST,DC=COM",
"ObjectGUID": "{88db9c05-2adb-4fe6-8dfe-26897bc823c7}",
"ObjectClass": "groupPolicyContainer",
"AttributeLDAPDisplayName": "versionNumber",
"AttributeSyntaxOID": "2.5.5.9",
"AttributeValue": "7",
"OperationType": "%%14674",
"EventReceivedTime": "2023-04-03T12:52:38.154964+02:00",
"SourceModuleName": "events",
"SourceModuleType": "im_msvistalog",
"EventData": "<EventData><Data Name=\"OpCorrelationID\">{f696f890-7c5b-41f0-bc82-aaaf73a80646}</Data><Data Name=\"AppCorrelationID\">-</Data><Data Name=\"SubjectUserSid\">S-1-5-21-3589175892-3624815508-1412135724-500</Data><Data Name=\"SubjectUserName\">Administrator</Data><Data Name=\"SubjectDomainName\">NXLOGTEST</Data><Data Name=\"SubjectLogonId\">0x84c17</Data><Data Name=\"DSName\">nxlogtest.com</Data><Data Name=\"DSType\">%%14676</Data><Data Name=\"ObjectDN\">CN={31B2F340-016D-11D2-945F-00C04FB984F9},CN=POLICIES,CN=SYSTEM,DC=NXLOGTEST,DC=COM</Data><Data Name=\"ObjectGUID\">{88db9c05-2adb-4fe6-8dfe-26897bc823c7}</Data><Data Name=\"ObjectClass\">groupPolicyContainer</Data><Data Name=\"AttributeLDAPDisplayName\">versionNumber</Data><Data Name=\"AttributeSyntaxOID\">2.5.5.9</Data><Data Name=\"AttributeValue\">7</Data><Data Name=\"OperationType\">%%14674</Data></EventData>"
}
Troubleshooting Active Directory domain controller promotion (DCPROMO) issues
Microsoft provides a comprehensive guide on Troubleshooting Domain Controller Deployment.
One of the most important log sources you will come across in the guide is the C:\Windows\debug\dcpromo.log
file, where the DCPROMO tool logs the entire DC promotion and demotion process.
Each consecutive run of DCPROMO
creates an additional log file in the format C:\Windows\debug\dcpromo.001.log
, etc.
This configuration uses the im_file input module to read all DCPROMO log files. It then parses each log record into structured data using a regular expression. Furthermore, it uses the parsedate() function to parse the event timestamp to datetime.
04/03/2023 04:43:47 [INFO] Creating directory partition: CN=Configuration,DC=nxlog,DC=org; 1270 objects remaining
04/03/2023 04:43:47 [INFO] Creating directory partition: CN=Configuration,DC=nxlog,DC=org; 1269 objects remaining
04/03/2023 04:43:47 [INFO] Creating directory partition: CN=Configuration,DC=nxlog,DC=org; 1268 objects remaining
<Extension json>
Module xm_json
PrettyPrint TRUE
</Extension>
<Input dcpromo>
Module im_file
File 'C:\Windows\debug\DCPROMO.log'
File 'C:\Windows\debug\DCPROMO.*.log'
<Exec>
if $raw_event =~ /^(\d\d)\W(\d\d)\W(\d{4}) (\d\d:\d\d:\d\d) \[(\S+)\] (.+)$/
{
$EventTime = parsedate($3 + '-' + $1 + '-' + $2 + ' ' + $4);
$Severity = $5;
$Message = $6;
}
to_json();
</Exec>
</Input>
{
"EventReceivedTime": "2023-04-03T04:43:48.841091+02:00",
"SourceModuleName": "dcpromo",
"SourceModuleType": "im_file",
"EventTime": "2023-04-03T04:43:47.000000+02:00",
"Severity": "INFO",
"Message": "Creating directory partition: CN=Configuration,DC=nxlog,DC=org; 1270 objects remaining"
}