文章目录
一、日志记录入门
读者可能会想知道:为什么要介绍日志记录?我们多年来一直在进行日志记录。还有什么需要知道的吗?
在忙着部署产品的过程中,日志记录几乎总是被忽视。这并不是因为日志记录不重要,而是因为它被认为是产品团队对其产品需求没有特别要求的非功能性使用场景。因此,它们很少被作为优先事项,有时甚至不是讨论的话题。
自问一下:
- 知道为了安全目的,应当何时、何地进行记录,以及记录哪些内容吗?
- 您认为应用程序日志在安全事件中会有用吗?
- 日志对除最初的设计人员或开发人员以外的任何人有帮助吗?
如果读者对以上任何问题的回答为“否”,本文将提供一些方法,帮助您改进日志记录。让我们从一些基础知识开始讲起。
二、日志记录域
日志记录域是许多应用程序中经常出现日志记录问题的较大领域。建议开发命名术语,用于讨论其相关信息可为您的命名术语提供支持的概念和日志。考虑以下更大的日志记录域:
- 诊断日志记录。 诊断日志用于了解需要特别关注的系统状态。诊断日志在确定故障原因和资源规划等方面都很有帮助。它们对于取证也有用,因为应用程序无疑具有在其他地方难以找到或不可能找到的宝贵上下文信息。诊断日志中的事件可能会馈送至 SIEM 或下游事件系统。缺少诊断日志或日志数据获取不便,但是如果缺失,员工或公司也不会面临处罚。
- 安全日志记录。 安全日志可明确责任,对取证很有用。诊断日志中的事件可能会馈送至 SIEM 或其他下游事件系统。缺少安全日志或日志数据获取不便,可能会有针对员工的处罚措施,但不太可能有针对公司的处罚措施。
- 审计日志记录。 审计日志是始终遵循组织政策的数字证据。审计日志或日志数据丢失或被篡改可能会导致员工或组织受到处罚。
应该注意让相应事件与日志中的不同目的正确相关联。保持良好的组织流程有助于确保能在最需要时获得日志信息。它还有助于避免许多组织在日志堆积时(保留太多日志消息)面临的常见问题。
三、日志记录安全使用场景
以下日志记录安全使用场景已经证明了它们对很多组织的价值。
1、确定安全事件
使用数据来发现可能攻击者会利用系统的异常系统行为。
2、策略冲突
威胁不仅来自外部,系统也可能受到内部人士的攻击。监控违反策略的行为,看看哪些人在突破系统边界来发现弱点。
3、监控既定的基线
确立系统行为的基线,并在跨越阈值时触发警报。
4、监控不可否认性控制
部署安全控制和监控,实施针对敏感资产(例如产品、资金和信息)的监管链,包括从资产初始分配到资产的目的地。这样做可以防止系统内的参与者通过虚假声明,滥用系统的完整性和机密性。
5、记录问题和异常情况
记录由底层应用程序基础结构或操作系统返回的异常情况。
6、应用程序环境
除 IT 安全控制之外,应用程序通常还具有其他环境信息。应当在日志中记录此类信息。
7、应用程序防御
应用程序的设计应当为主动参与防御。工程师接口应当与 SIEM 工具有效协作 - 例如在通用日志文件系统 (CLFS) 中发送消息,通过 syslog 发送通用事件格式 (CEF),并且将来可能会使用通用事件表达式 (CEE)。
四、 设计、实现和测试注意事项
应用程序项目的开发人员知道日志是有价值的。应该记录哪些内容?什么是正确的日志粒度?记录太少内容,可能会错过有价值的信息。记录太多内容,系统性能会受到负面影响。
我们来介绍一些来自 OWASP 的注意事项,这将有助于您设计自己的日志系统。
事件数据源
它们是参与生成日志消息的系统中的组件。
- 客户端软件。 企业服务器、云 IaaS、移动应用。
- 嵌入式插桩代码。 JMS、SNMP 和 OS 流日志记录。
- 网络防火墙。
- 网络和主机入侵检测系统(NIDS 和 HIDS)。
- 密切相关的应用程序。
- 应用程序防火墙。 过滤器、防护机制、XML 网关、数据库防火墙和 Web 应用程序防火墙 (WAF)。
- 数据库应用程序。 自动审计跟踪、基于触发的操作。
- 否认性监控服务。 正常运行时间或恶意软件监控。
- 其他应用程序。 欺诈监控、CRM。
- 操作系统。 企业服务器、云 IaaS、移动应用。
来自上述任何来源的数据对于问题确定都有用,特别是跨事件源进行关联时。但是,必须谨慎使用不可信数据。
五、 要记录的事件
以下是进行日志记录时要考虑的一些事件类型。
- 输入验证失败。 违反协议、不可接受的编码、无效的参数名称和值。
- 输出验证失败。 数据库记录不匹配、无效的数据编码。
- 身份验证成功和失败。 用户登录/注销系统。
- 授权失败。 无法访问权限资源。
- 会话管理失败。 Cookie 会话识别值修改。
- 应用程序错误和系统事件。 语法错误、运行时错误、连接问题、性能问题、第三方服务错误消息、文件系统错误、文件上传病毒检测以及配置更改。
六、事件属性
以下是进行日志记录时要考虑的事件属性。
OWASP 备忘表中的“要排除的数据”部分对于这个话题特别有用。这些信息在合规性规范方面是不可知的,并且包括日志中常见的很多类型的个人可识别信息。
七、使用 OWASP 进行安全日志记录
正如所见,进行日志记录时有很多事项需要了解和记忆。OWASP 安全日志记录项目 (OWASP Security Logging Project) 是有关此话题另一个很好的资源。从设计和实现的角度来看,使用像 log4j 这样的日志记录系统便可立即开始充分利用这个日志记录系统的好处,而不需要更改代码。
当然,当调用日志项目的 API 的一些功能时,还有更多好处。该库设计时已考虑到易用性,并支持 Maven,让项目能够快速运行。让我们来看一些快速易得的好处。
监控应用程序基础结构的健康状况
如何知道攻击者是否耗尽了 Web 应用程序服务器的线程池呢?毕竟,服务器不会倒下来警告您。
安全日志项目可通过以下方式提供帮助:默认情况下,“间隔日志记录”功能每 15 秒可产生一次输出,如下所示:
20:10:10.204 [Thread-0] INFO Watchdog: MemoryTotal=64.5MB, FreeMemory=58.2MB, MaxMemory=947.7MB, Threads Total=5, Threads New=0, Threads Runnable=3, Threads Blocked=0, Threads Waiting=2, Threads Terminated=0
要启动间隔记录器,只需要这样做:
IntervalLoggerController wd = SecurityLoggingFactory.getControllerInstance();
wd.start();
默认状态消息为基本选项,但该系统可扩展。可以记录包含更多所关注信息的自定义应用程序特定属性。考虑以下代码片段,当服务应用程序在 *NIX 变体上运行时,会将打开文件句柄数添加到间隔记录器中。
// Add a new property to the list of current properties
DefaultIntervalLoggerModel model = new DefaultIntervalLoggerModel();
model.addProperty( new DefaultIntervalProperty("OpenFiles") {
public void refresh() {
// restricted class, display open file handle count on *nix if we can.
OperatingSystemMXBean os = ManagementFactory.getOperatingSystemMXBean();
if(os instanceof UnixOperatingSystemMXBean)
value = Long.toString(((UnixOperatingSystemMXBean) os).getOpenFileDescriptorCount());
}
}
);
用户可以使用相同的方法将所需的任何属性添加到状态消息中。也可以移除自己不关心的属性。虚拟机内部的监控活动对于诊断和取证目的非常有用。这些信息还为容量规划提供了辅助价值。
日志消息关联
不是每条消息都可以直接划分到登录到某个应用程序的用户。典型的 Web 应用程序具有各种环境概念,但是 Web 应用程序通常包括以下类型的环境信息。
- 未经身份验证的用户环境。 应用程序可能仅会向未经身份验证的用户提供有限的服务。
- 通过身份验证的用户环境。 如果用户登录,应该将其帐户与他们在日志消息中的活动相关联。
- 应用程序环境。 某些应用程序活动归因于管理内部服务器功能的线程。缓存清理、队列处理、支持和监视,以及应用程序和数据库之间的一些交互等活动发生在用户环境之外。
消息关联是通过 log4j2 未被充分利用和未充分认可的特性,以及被称为映射诊断上下文 (MDC) 的 logback 来执行的。MDC 在每个日志消息中都包括其他上下文,无需调整 API 即可传递大量的应用程序状态信息,例如当前登录的用户。这些信息在查看日志文件时非常有用,并且让程序易于阅读。随着解决方案提供商从传统的企业解决方案过渡到在多个虚拟实例上运行相同服务的云环境,对消息关联的需求越来越普遍。
您在启动应用时是否记录足够多的信息?
记录所有关于系统初始状态的实用信息,对于以后确定问题很有帮助。这意味着应当记录此类信息:
- 系统 shell 环境变量。
- 命令行参数。
- J2EE 属性,如 servlet 初始化设置。
这是很容易编写的代码,但做这件事有点像倒垃圾:它并不有趣,大部分人宁愿在其他地方多花时间。下面的代码片段演示了为应用程序捕获大量启动信息所需的少量代码。
public void printPropertiesOnStartup( String[] args) {
SecurityUtil.logCommandLineArguments(args);
SecurityUtil.logShellEnvironmentVariables();
SecurityUtil.logJavaSystemProperties();
// Bada bing, bada boom, your done! Code, 3-lines.
}
有关机器初始化状态的信息,在发生安全事件后执行调试或取证时很有用。
实现自己的代码一点都不复杂。那么为什么不自己做呢?答案分成两部分:如果用户不是专家,使用开箱即用的安全日志框架是更好的选择,因为自己做时可能出错。但即使知道对代码进行日志记录的方法,最好还是为更重要的项目期限节省时间和精力。
八、日志记录技术
对于构建自己的日志记录系统,我们已经介绍了一些注意事项和常见的挑战。现在,让我们来探索一些日志记录技术及其好处。
技术和方法
1、System.out/System.err
System.out 和 System.err 是系统日志流。大量代码使用这些流类,并且它在历史上是语言规范的一部分。如果您在开发过程中需要一些快速输出,它很方便,但是它在生产中的用途是有限的。
2、Java 日志记录
从 JDK 1.4 开始,JSR-47 兼容的日志记录已包括在内。Java 日志记录的一大好处是它内置于平台中。搜索日志层次结构的方式有一些技术上的差异,有一些平台功能可能会对某些应用程序造成麻烦。
3、Log4j 2
它是最初的 log4j 项目的替代品。这个强大的日志记录系统如今很流行。
4、Logback
Log4j 2 的替代方案,是由原来的 log4j 项目设计人员在脱离 Apache 项目之后开发的。
5、OWASP 安全日志记录项目
安全日志记录项目基于 SLF4J 构建,并与现有日志记录平台(例如 log4j 2 和 logback 框架)兼容。如果读者已经使用了流行的日志记录平台,那么就可以使用安全日志记录,只需对现有的代码进行少量(如果有)更改。我们来看看安全日志记录平台所带来好处的简要清单。
- 基于安全的功能:集成 SIEM 工具,记录虚拟机资源使用趋势
- 自定义基本日志记录,可包括元数据、打开文件数及登录的用户等
- 日志消息的信息分类支持(面向政府机构)
- 记录路由,在一个地方记录日常消息,并在另一个地方记录权限消息
- SessionPlugin,将当前登录的用户添加到相应的日志消息中
- 提供的其他插件,例如 ForwardedIPAddressPlugin、IPAddressPlugin、UserNamePlugin,或开发自己的插件
- SecurityUtil.logCommandLineArguements(),记录程序命令行参数
- SecurityUtil.logShellEnvironmentVariables(),记录应用程序的 shell 环境
- SecurityUtil.logJavaSystemProperties(),在启动时或您希望的任何时间记录您的系统属性
- SecurityUtil.bindSystemStreamsToSLF4J(),捕获来自 System.out/System.err 的输出,并重定向到 log4j/logback
- 为过滤来自日志的密码提供有限的支持
6、相关标准
- JSR-47。这是驱动 Java 日志记录的标准。记住这一点非常重要:尽管 Java 日志记录与 log4j 和 logback 具有类似功能和类似界面,但 JSR-47 与 log4j 仍然存在区别。
- SLF4J。它是为便于在不同日志记录平台之间轻松迁移而开发的规范。使用 SLF4J 的好处是用户可以在部署时切换日志记录框架。
选择的日志记录技术取决于用户的项目。开发人员并不总是能够自由选择他们想要的任何平台。这就是为什么说,了解一些平台以及其扩展方式很有好处。