在本文中,将探讨如何创建一个关联ID,以便将IIS、域和SQL Server审计日志相关联。作为安全分析师,希望能够追踪请求的来源,以便识别恶意用户,进而阻止该用户或将该用户的身份信息传递给公司。同时,也希望追踪用户请求的变化,以识别软件缺陷或恶意用户行为。作为软件工程师,不希望在应用程序中记录Web请求元数据或SQL请求,因为不希望维护这些代码和数据。
问题在于,如何关联以下日志?IISW3C日志、应用程序域事件日志和SQL Server审计日志。显然,答案是某种关联ID。这种方法在应用程序内部是有意义的,因为对它有控制权。但是,IIS呢?每个Web请求元数据在(有时甚至在)击中应用程序之前就被写入日志。
1. 创建关联ID哈希
IIS将在日志中捕获诸如IP地址、用户代理、路径、动词等变量(见上文)。由于知道在IIS日志中存储了什么,可以在应用程序中从请求头中获取这些变量,并创建一个W3C关联ID哈希。
public interface IRequestCorrelationIdentifier
{
string CorrelationID { get; }
}
public class W3CWebRequestCorrelationIdentifier : IRequestCorrelationIdentifier
{
public string CorrelationID { get; private set; }
public W3CWebRequestCorrelationIdentifier()
{
// 自定义关联ID
string rawCorrelationID = string.Join(
"_",
HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"],
HttpContext.Current.Request.Params["LOGON_USER"],
HttpContext.Current.Request.UserAgent != null ?
HttpContext.Current.Request.UserAgent.ToString().Replace(" ", "+")
: "-",
HttpContext.Current.Request.Path,
HttpContext.Current.Request.QueryString.ToString() ?? "-",
new DateTime(HttpContext.Current.Timestamp.Ticks).ToUniversalTime().ToString("yyyy-MM-dd HH:mm:ss")
);
StringBuilder hashBuilder = new StringBuilder();
using (MD5 md5 = MD5.Create())
{
byte[] hash = md5.ComputeHash(Encoding.UTF8.GetBytes(rawCorrelationID));
for (int i = 0; i < hash.Length; i++)
hashBuilder.Append(hash[i].ToString("X2"));
}
this.CorrelationID = hashBuilder.ToString();
}
}
2. 注册关联标识符
IRequestCorrelationIdentifier然后可以与依赖注入框架注册,生命周期为每个Web请求。这将确保该Web请求管道中的所有组件都获得相同的关联ID。
container.Register(Component.For().ImplementedBy().LifeStyle.PerWebRequest);
3. 使用关联ID记录一切
现在已经准备好在应用程序中使用IRequestCorrelationIdentifier了。以下是如何将其与域事件记录一起使用的方法:
public class DomainEventHandle : Handles
where TDomainEvent : DomainEvent
{
IDomainEventRepository domainEventRepository;
IRequestCorrelationIdentifier requestCorrelationIdentifier;
public DomainEventHandle(IDomainEventRepository domainEventRepository,
IRequestCorrelationIdentifier requestCorrelationIdentifier)
{
this.domainEventRepository = domainEventRepository;
this.requestCorrelationIdentifier = requestCorrelationIdentifier;
}
public void Handle(TDomainEvent @event)
{
@event.Flatten();
@event.CorrelationID = this.requestCorrelationIdentifier.CorrelationID;
this.domainEventRepository.Add(@event);
}
}
4. 启用IIS日志记录
5. 启用SQL Server审计
微软最近发布了SQL Server审计功能。它记录了对数据库执行的所有原始SQL语句。由于现在有关联ID,所要做的就是获取关联ID并搜索XEL文件。以下是一个XEL筛选器屏幕示例,在其中搜索关联ID:
如果它在"statement"字段中找到关联ID,它将返回相关行:
通过点击行,将获得审计事件分解:
这非常强大,因为可以识别所有变化,现在可以将它们全部关联起来。
可能会出现以下情况:
IIS将在应用程序已经处理请求几秒钟后记录Web请求。应用程序将在IIS记录Web请求几秒钟后处理请求。
为什么这很重要?关联ID哈希代码是在应用程序内部使用日期时间变量生成的。应用程序不知道IIS使用了什么时间戳。这意味着当搜索IIS W3C日志并且哈希相同的变量时,可能找不到预期的关联ID。IIS和应用程序之间的延迟只有+-2秒(这是在测试中发现的)。所以,当搜索IIS W3C日志时,只需生成4个额外的哈希代码并搜索它们。