db2 audit
DB2 UDB 审计功能是 DBA 工具箱中一件重要的安全性工具。它可以生成对一系列预定义的数据库事件的审计跟踪,并允许 DBA 维护审计跟踪。它可以对一些数据库事件,例如授权检查、数据库对象维护、安全性维护、系统管理和用户验证等做日志记录。本文向您展示如何有效地使用该功能 对可疑的系统活动进行跟踪和调查。
审计发生在实例级,这意味着一旦启动审计功能,它就会审计那个实例中所有数据库的活动。审计功能必须单独启动和停止。例如,如果使用 db2stop 命令停止一个实例,那么审计功能不会自动停止;它必须单独使用 db2audit stop 命令来停止。 只有具有 SYSADM 权限的用户才能配置和使用审计功能。 关于 SYSADM 权限级别以及如何将该权限授予用户组的描述,请参阅本系列的 第 4 部分。在 DB2 UDB 文档 中也提供了该信息。
图 1 概要展示了审计功能以及它在整个 DB2 UDB 架构中的地位。
图 1. DB2 UDB 架构中的 DB2 审计功能
在这个图中,外面的蓝色椭圆表示一个 DB2 数据库服务器。里面的红色矩形表示一个 DB2 实例。如图所示,审计功能运行在实例级,为实例中的所有数据库服务。另外还有一个配置文件,用来设置审计选项。
启动审计功能后,生成的审计记录被写入到一个缓冲区,然后刷新到磁盘上的一个审计文件中。审计结束后,便可以将审计文件从它本地的原始格式转换成一种易读的文本文件。还可以将审计记录装载到 DB2 表中,以便于使用 SQL 查询数据和生成定制的报告。
审计功能的文件存储和维护在实例的 security 文件夹中。图 2 展示了实例 DB2 在一个 Windows 服务器上 security 文件夹中的示例内容。
图 2. Windows 服务器上的 security 文件夹
db2audit.cfg 文件存储审计功能的配置信息。这是一个二进制文件,只能使用 db2audit 命令行语法对它进行修改。db2audit.log 文件存储原始的审计记录。可以将审计记录从该文件提取到一个文本文件中,以便作进一步的分析。db2audit.log 文件在默认情况下并不存在,只有在生成了审计记录或者刷新了审计缓冲区的情况下,该文件才会出现。当创建一个新的实例时,系统会在这些文件上设置适当的读 /写权限,建议不要修改这些权限。G
审计功能的配置主要有两个方面。一方面是设置缓冲区的大小,另一方面是配置所审计的事件的类型。接下来的两个小节将更详细地谈到这些配置。
审计记录通常首先被写入到一个内存缓冲区,然后才刷新到磁盘。缓冲区的大小是由 AUDIT_BUF_SZ 这个数据库管理器配置参数决定的。该参数指定为审计缓冲分配的 4K 大小的页面的数量。缓冲区大小的选择将在很大程度上影响审计的性能,因为可能要将很多记录写到审计日志中。
如果将缓冲区大小设置为 0,那么将发生同步写日志操作,而不使用审计缓冲区。在这种配置中,生成审计记录的事件必须等到记录被写到磁盘上,才能返回它的状态。由于对于每条记录都 要进行这样的等待,DB2 的性能将有所降低。如果缓冲区的大小大于 0,那么审计记录是异步写的。也就是说,审计记录在被刷新到磁盘之前,是先存放在审计缓冲区中的。为了防止缓冲时间过长,DB2 定时强制地写审计记录。还可以使用 db2audit flush 命令手动地刷新审计缓冲区。在异步写日志的情况下,生成审计记录的事件无需等到审计记录被写到磁盘便可返回它的状态。
假设您想将审计缓冲区的大小增大到 40KB,以便采用异步写日志方式,并提高性能。那么可以通过发出以下命令来完成这个任务:
update dbm cfg using audit_buf_sz 10
db2stop
db2start
注意,在更新这个参数之后,为了使参数的更改生效,必须重新启动实例。
在选择同步还是异步写日志时,要考虑的一个重要因素就是当数据库管理器发生错误时情况会怎样。如果采用异步写日志的方式,那么在发生错误时,可能会丢失多 条审计记录,因为这些审计记录在被写到磁盘之前都在缓冲区中。如果同步写日志,那么只会丢失一条记录,因为发生的错误最多只能阻止一条审计记录被写到磁 盘。
审计功能可以监视不同类型的数据库事件。在关注用于配置审计功能的 db2audit 命令的语法之前,有必要回顾一下这些事件类型。
表 1 列出了可以审计的不同类型的数据库事件,并描述了审计记录是何时生成的。每个事件类型后面括号中的大写单词是 db2audit 命令的配置子句中使用的相应关键词。
表 1. 可以审计的数据库事件类型
事件类型 | 描述 |
---|---|
审计 (AUDIT) |
|
权限检查 (CHECKING) |
|
对象维护 (OBJMAINT) |
|
安全性维护 (SECMAINT) |
|
系统管理 (SYSADMIN) |
|
用户验证 (VALIDATE) |
|
操作上下文 (CONTEXT) |
|
例如,如果只需要审计数据库连接和系统管理事件类型,那么在配置审计功能时应该仅指定 VALIDATE 和 SYSADMIN 事件类型。
决定了审计哪些类型的事件之后,还可以指定只记录成功的事件,或者只记录失败的事件,还是两种事件都记录。如果记录成功的事件,那么生成的记录数将显著增加,所以应该少用这种选项。
还可以在 db2audit 命令中使用 ERRORTYPE 子句来配置审计功能处理错误的方式。您可以指定是将审计功能错误返回给用户(AUDIT),还是忽略掉(NORMAL)。在前一种情况下,所有错误,包括在审计功能内部发生的错误,都由 DB2 来管理,并且所有为负的 SQLCODE 都被报告给应用程序。在后一种情况下,审计功能生成的任何错误都被忽略,并且只有与正在执行的操作相关的错误的 SQLCODE 才会返回给应用程序。
现在您已经回顾了可以监视的各种不同类型的事件以及状态和错误处理选项,接下来我们来看一下用于配置和使用审计功能的实际的命令语法。清单 1 展示了用于配置和操作审计功能的 db2audit 命令的语法。
清单 1. db2audit 实用程序的语法
|
为了更好地理解如何使用该命令语法,本文给出了一些例子。在第一个例子中,需要将审计功能配置成只记录失败的 AUDIT 和 VALIDATE 事件,并使用 NORMAL 错误处理选项。为此,发出以下 db2audit 命令:
db2audit configure scope audit, validate status failure errortype normal |
为了将审计功能配置成监视所有事件类型,同时记录成功的和失败的尝试,并且使用 AUDIT 错误处理选项,可发出以下 db2audit 命令:
db2audit configure scope all status both errortype audit |
为了查看当前审计配置设置和状态,请使用以下 db2audit 命令:
db2audit describe |
清单 2 显示了该命令的输出:
清单 2. Windows 上 db2audit describe 命令的输出
|
通过查看清单 2 中的输出,可以看出记录了哪些事件,审计功能是否已启动。为了重新设置当前的审计配置设置,并将它们还原成初始的配置(SCOPE 是所有类别,除了 CONTEXT,STATUS 是 FAILURE,ERRORTYPE 是 NORMAL,审计功能状态是 OFF),可发出以下 db2audit 命令:
db2audit configure reset |
如果初始的审计配置文件已丢失或被毁坏,则该命令还创建一个新的审计配置文件。
配置了要监视的事件的类型,并且也配置了状态和错误处理选项之后,便可以启动审计功能。还记得审计功能是独立于实例启动和停止的。为了启动审计功能,发出以下命令:
db2audit start |
当用完审计功能,并且希望停止该功能时,发出以下命令:
db2audit stop |
db2audit.log 文件中的审计记录是以一种原始格式存储的。您必须从该文件中将所有审计记录提取到一个文本文件中,然后才可以进行分析。也可以将审计记录提取到定界 ASCII 文件中,然后可以将这些文件装载到 DB2 关系表中,以便进行分析和查询。
在从 db2audit.log 文件提取审计记录之前,发出以下命令将缓冲区中的所有审计记录刷新到磁盘:
db2audit flush |
为了从 db2audit.log 文件中将记录提取到一个文本文件,发出以下 db2audit 命令:
db2audit extract file c:\temp\audit_01_22_2006.aud |
其中 "c:\temp\audit_01_22_2006.aud" 是所需的输出文件的文件名的路径。如果不指定一个文件名,那么这些记录将被写入到 $INSTHOME/sqllib 的 security 子目录中的 db2audit.out 文件中,其中 INSTHOME 是实例的主目录。如果不指定目录,则输出文件被写入到当前的工作目录中。
为了从 db2audit.log 文件中将记录提取到定界 ASCII 文件,以便将这些定界 ASCII 文件装载到 DB2 关系表,可以发出以下 db2audit 命令:
db2audit extract delasc delimiter ! |
输出被放入到 sqllib 的 security 子目录下一些不同的文件中(每个文件用于一种事件类型)。这里使用的文件名是:
- audit.del
- checking.del
- objmaint.del
- secmaint.del
- sysadmin.del
- validate.del
- context.del
在前面的命令中,如果包括 DELIMITER 子句,后面跟上一个新的记录字段分界符(在这里是一个 ! 号),在从审计日志中提取记录时便可以覆盖默认的字段分界符(0xff)。
还可以通过分别指定 CATEGORY、DATABASE 和 STATUS 子句来限制所提取的审计记录的数量和类型。通过 CATEGORY 子句可以指定从审计日志中提取哪些类型的审计事件。如果该子句未指定任何内容,那么所有类型的事件都将被提取。通过 DATABASE 子句可以限制只提取一个特定数据库中的记录。如果该子句未指定任何内容,那么可以提取来自实例中任何数据库的审计记录。通过 STATUS 子句可以指定是提取成功的事件、失败的事件或者成功的和失败的事件都提取。如果该选项未指定内容,则提取所有记录。
例如,假设只需要将 AUDIT 事件类型的记录提取到以 ! 作为字段分界符的定界 ASCII 文件中,并且只需要数据库 SAMPLE 中的记录,并且只对 FAILURE 状态的事件感兴趣。那么可以发出 db2audit 命令:
db2audit extract delasc delimiter ! category audit database sample status failure |
如果只将 SAMPLE 数据库的 SYSADMIN 审计事件提取到一个名为 audit.db2 的标准文本文件中,包括状态为 SUCCESS 和 FAILURE 的事件,可发出以下 db2audit 命令:
db2audit extract file audit.db2 category sysadmin database sample |
审计日志文件(db2audit.log)可能增长很快,所以定期对该文件进行修剪是一种好做法。对已经提取到文本文件的审计日志中的记录进行修剪,还可以防止再次提取相同的记录。要修剪 db2audit.log 文件,可发出以下 db2audit 命令:
db2audit prune date YYYYMMDDHH |
其中 YYYYMMDDHH 是当前的年、月、日和时。此时所在的所有记录都将被修剪。如果将审计记录存放在 DB2 表中,那么应该将这个日期值的记录放在一个方便的地方。
要修剪整个日志,可发出以下 db2audit 命令:
db2audit prune all |
提取过程所产生的文本文件由一些审计记录组成,每个记录之间以一个空白行隔开。清单 3 展示了使用 FILE 选项提取的审计记录的一个片段。
清单 3. 使用 FILE 选项提取的审计记录的片段
|
从这些记录可以看出,用户 'TEDWAS' 首先启动审计实用程序,然后两次修改了配置,接着刷新了审计缓冲区。所有这些事件都发生在近乎相同的时间帧上,这从 TIMESTAMP 字段很接近的值可以看出。还可以看出,这些事件代表 AUDIT 事件类型,因为在 category 字段中有 AUDIT 值。
清单 4 展示了从审计日志提取的相同审计记录的一个片段,这次使用 DELASC 选项和 ; 字段定界符。 这些记录是从提取过程中生成的 audit.del 文件中摘录的。
清单 4. 使用 DELASC 选项提取的审计记录的片段
|
注意出现在清单 4 中最后的那条记录。该记录是在生成为清单 3 产生的文本文件时生成的。之所以会生成这条记录,是因为审计功能被配置为在发生提取操作时记录所有审计事件。
表 2 总结了清单 3 和清单 4 中显示的 AUDIT 事件类型的审计记录中每个字段的意思。
表 2. 对 AUDIT 事件类型审计记录格式的描述
名称 | 格式 | 描述 |
---|---|---|
时间戳 | CHAR(26) | 审计事件的日期和时间 |
类别 | CHAR(8) | 审计事件的类别。可能的值为:AUDIT |
审计事件 | CHAR(32) | 特定的审计事件。可能的值包括:CONFIGURE、DB2AUD、EXTRACT、FLUSH、PRUNE、START、STOP 和 UPDATE_ADMIN_CFG |
事件相关符 | INTEGER | 被审计的操作的相关标识符。可用于标识哪些审计记录与某个事件相关 |
事件状态 | INTEGER | 审计事件的状态,由一个 SQLCODE 表示,其中:
|
用户 ID | VARCHAR(1024) | 审计事件发生时的用户 ID |
权限 ID | VARCHAR(128) | 审计事件发生时的权限 ID |
将审计记录提取到定界 ASCII 文件之后,就可以将 ASCII 文件的内容装载到 DB2 表中。然后,可以对这些表发出 SQL 查询,并对数据执行高级的分析。首先必须创建容纳审计数据的表。最好的做法是在一个单独的模式中创建这些表,以便将数据与未授权的用户隔离开来,并且有更 好的组织。关于应该使用的实际的 CREATE TABLE 语句。
创建了所有必需的表之后,便可以向它们装载来自提取过程创建的定界 ASCII 文件中的记录。使用 LOAD 实用程序将数据装载到这些表。例如,要使用之前提取过程创建的相应的 audit.del 文件装载 AUDIT 表,可以发出以下 LOAD 命令:
LOAD FROM audit.del OF del MODIFIED BY CHARDEL! INSERT INTO MYSCHEMA.AUDIT |
其中 MYSCHEMA 是存放审计表的模式,AUDIT 是表名。注意 MODIFIED BY CHARDEL! 子句的使用。 由于被提取的定界 ASCII 文件是使用一个不同于 LOAD 实用程序预期的字符(一个逗号)的字段定界符创建的,所以 LOAD 实用程序被配置为接受不同的定界符。
从您装载的表中删除被修剪过的行,确保以后不会将重复的行装载到表中,这是一种很好的做法。提取的审计文件可能包含审计日志被修改之后写入的记录,因此这 些记录也应该从表中删除,以免影响分析。以下命令删除 AUDIT 表中时间戳大于一个特定时间戳的行,这个特定的时间戳用于修剪审计日志文件:
DELETE FROM MYSCHEMA.audit WHERE TIMESTAMP > TIMESTAMP('YYYYMMDDHH0000') |
其中 MYSCHEMA 是审计表所在的模式,AUDIT 是表名,YYYYMMDDHH0000 是修剪审计日志时指定的值。
将审计数据装载到表中有很多好处。虽然您可以编写自己的程序来分析被提取的包含审计记录的文本文件的内容,但是当审计数据存储在关系表中时,从关系表中查询它们要容易和快捷得多。
假设您配置了审计功能,使之对重新配置审计功能的失败的和成功的尝试都进行审计。监视过程完成之后,您刷新审计缓冲区,将审计记录提取到定界 ASCII 文件,然后将这些文件装载到 DB2 表中。如果您想查询审计数据,看看在更改审计配置方面进行了最多次数的失败尝试的前 5 名用户,那么可以 发出以下查询:
SELECT userid, COUNT(*) AS count FROM MYSCHEMA.audit |
您已经看到了如何配置和使用审计功能,接下来我们来体验一个完整的场景,这个场景展示了从开始到结束的完整过程。
假设您从某个应用程序用户那里得到匿名消息,说一个名为 SAM 的用户正在试图访问数据库对象和表,而实际上在午休时间他并没有这样的访问权。于是,您决定在午休时间监视 DB2 实例,看有无失败的权限检查尝试。
首先配置审计功能,使之审计 CHECKING 事件类型,只记录失败的尝试,并使用 NORMAL 错误处理:
db2audit configure scope checking status failure errortype normal |
通过将数据库管理器参数 AUDIT_BUF_SZ 的大小设置为 40,确保审计功能将使用异步日志记录:
update dbm cfg using audit_buf_sz 40 |
一直等到中午 12 点,启动审计功能:
db2audit start |
在审计期间,用户 SAM 走向数据库服务器,然后登录。他打开一个命令行窗口,连接到 SAMPLE 数据库,试图更新 EMPLOYEE 表中的雇员薪水但是没有成功。他发出以下 SQL 语句:
connect to sample user sam using bad123boy |
于是收到以下错误消息:
DB21034E The command was processed as an SQL statement because it was not a |
这条消息表明他没有更新那个表的权限,于是他很快就登出服务器,并离开了,自以为没有人看到他做的事。
一个小时过去了,您决定检查审计日志的内容。首先刷新审计缓冲区,确保将所有仍然缓冲在内存中的审计记录写到磁盘上:
db2audit flush |
然后从 db2audit.log 文件将记录提取到定界 ASCII 文件中,这里以分号作为字段定界符,并且只提取状态为 FAILURE 的 CHECKING 事件:
db2audit extract delasc delimiter ; category checking database sample status failure |
由于审计记录现在是文本格式,于是您决定修剪日志,使之更易于管理,并防止有重复的记录:
db2audit prune date 2006020613 |
为了用之前创建的 DB2 表来存放审计数据,将提取的数据从 checking.del 文件装载到 CHECKING 表中,可以使用以下命令:
LOAD FROM checking.del OF del MODIFIED BY CHARDEL; INSERT INTO audit.checking |
为了避免分析重复的记录,从 CHECKING 表中删除时间戳大于一个指定的、用于修剪日志的时间戳的行:
DELETE FROM audit.checking WHERE TIMESTAMP > TIMESTAMP('20060206130000') |
然后通过查询 AUDIT.CHECKING 表试着发现关于失败的权限检查尝试的更多信息:
SELECT category, event, appid, appname, userid, authid FROM audit.checking |
从 清单 5 显示的查询结果可以看出,针对失败的更新语句有一条审计记录。
清单 5. 查询 CHECKING 表得到的结果
|
最后您决定停止今天的审计分析,并停止审计功能,以免生成更多的审计记录,为此可以使用以下命令:
db2audit stop |
现在您的怀疑得到了证实,您将继续收集更多的证据来呈交给领导,以便他们可以采取行动。
虽然这个场景非常简单,但是足以让您体验整个过程。这个例子中所做的分析工作非常简单,其目的是确认用户 SAM 正在尝试更新表,而他本来不能做这样的事。在您自己的实际情况当中,分析工作可能有很大的不同,这取决于您想调查什么。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/24177460/viewspace-701343/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/24177460/viewspace-701343/