SQL Server安全(11/11):审核(Auditing)

在保密你的服务器和数据,防备当前复杂的攻击,SQL Server有你需要的一切。但在你能有效使用这些安全功能前,你需要理解你面对的威胁和一些基本的安全概念。这篇文章提供了基础,因此你可以对SQL Server里的安全功能充分利用,不用在面对特定威胁,不能保护你数据的功能上浪费时间。


SQL Server审核

SQL Server里的审核指的是你可以在数据库或服务器实例里监控事件。审核日志包含你选择捕获的一系列事件,对于数据库和服务器对象,主体和操作,在服务器上形成活动记录。你可以捕获发生的几乎任何数据,同时包括成功和不成功的登录;读取的,更新的,删除的数据;管理任务;还有更多。审核可以深入数据库和服务器。

回顾追溯已经发生事件可能是一种很奇怪的方法。但设计日志常是你用来监控攻击的第一个且最好的资源,尤其是当攻击者只探测数据库还没有成功访问数据或进行破坏。但入侵发生时,监管部门和媒体会下来对你,审核日志就是可能会帮你找出发生了什么,什么数据被访问,和入侵的源头。没有日志,很可能你必须抓住攻击者并审问他们才可以明确知道到底发生了什么!

SQL Server有长期有提供支持审核的功能,但直到SQL Server 2008,审核才真正成为一个核心功能,有内建对象,T-SQL支持,在SSMS里有用户界面。微软从这个初始版本学到很多教训,在SQL Server 2012里做出一些漂亮的增强。其中一个最大的改变是微软在SQL Server的所有版本里支持审核,并不单单企业版。这就是说限制你可以在任何版本里,指定在所有的数据库里创建审核。但这个消息是混合的:只在企业、开发和评估版本里,可以进行单个数据库监控。因此如果你测试或评估SQL Server,最终在生产里使用企业版,确定你使用的版本有你需要的功能。

多年来推动的审核的一部分是全世界各个政府对不同类型组织的法律要求。结果,现在SQL Server用来保护世界上一些最严格的监管组织,行业和数据。

SQL Server审核对象

不管你使用T-SQL还是SSMS的用户界面操作审核,你会与三个对象打交道。

  • 服务器审核:对于你的审核,服务器审核对象是最高级别的容器;你经常为一个审核使用这个对象。通常你会为特定的目的,创建服务器审核到组,包含一个或多个审核规范,例如承诺,或为一系列的服务器或数据库对象。你会使用这个对象到特定的审核名称,那里用来保存审核日志,限于日志,和在审核失败事件里发生了什么。你也可以定义筛选来给你在事件日志里颗粒级别的控制。
  • 服务器审核规格:使用这个对象在审核日志里来定义特定服务器级别的事件来捕获。规格与你刚才创建的具体服务器审核相关。这里是你定义的地方,即你在想要记录的对象上的事件。
  • 数据库审核规格:这个对象和服务器审核规格类似,除了你会在单个数据库里用它来捕获事件。它也和一个服务器审核对象关联。

你会经常用到服务器审核对象,连同一个或其它对象,取决于在日志里你想要捕获的事件类型。如果你想要记录的所有事件在单个数据库,使用数据库审核规格对象。否则,如果事件跨越两个或更多数据库,或是服务器级别的事件,使用服务器审核规格对象。

当你创建一个服务器审核时,你可以为审核日志选择三个位置之一:Windows应用程序日志,Windows安全日志,或文件系统里的一个文件。对你写入审核数据的位置你要非常仔细,因为它很可能包含像社会保障号,信用卡号,工资,企业财务数据等敏感信息。因此,你要使用未授权用户不能访问的位置。这就是说Windows应用程序日志不是个好选择,因为默认情况下,用户不需要更高的许可来查看它。但安全日志可以是个好选择,因为访问需要管理员许可。文件夹中的文件也可以是个好选择,因为你可以安全化文件夹或它里面的文件使用Windows内建的安全系统。

创建一个服务器审核

你可以使用SSMS里的图形话界面工具或T-SQL语句创建SQL Server审核。使用SSMS的审核的图形界面更加简单,以为我们从这里开始。打开SSMS连接到本地SQL Server实例。在对象浏览器里,切换到最高层的【安全性】节点——不是数据库里的【安全性】节点——展开节点,你会看到审核。

提示:这里我使用的是SQL Server 2012和AdventureWorks2012样本数据库。

你可以使用这个对话框来设置你创建的服务器审核对象的各种属性:

  • 审核名称:SQLServer默认以当前的日期和时间自动生成,如Audit-20160430-084903格式,你也可以设置为你需要的名称。我设置为Sample Audit来更好的区分
  • 队列延迟:接下来你可以用毫秒来设置队列延迟,默认是1秒,这表示你愿意等待系统写入日志条目的最大时间是1秒。这个值是性能和完全之间的权衡:更短的时间限制,在灾难故障前,更容易记录关键事件,但会影响到服务器性能。对于这服务器审核,我保持默认设置,意味着最坏的情况我会丢失一秒的条目。对于范例审核,完全可以接受。
  • 接下来的设置决定在审核日志失败时会发生什么当SQL Server不能写入一条审核日志条目时,可能因为没有可用的磁盘空间。默认是【继续】,在系统事件日志里有会有一条错误,但潜在的操作还是继续。当审核至关重要,面对审核失败,不管操作还是服务器执行都不应该继续,可以使用【关闭服务器】选项。这是一个严厉的操作——关闭SQL Server服务——但审核至关重要时这个是必须的。【操作失败】是在这2个极端之间,引起造成失败的事务回滚。这个设置我也保持默认。
  • 对话框上剩下的选项与你选择的审计目标有关。有3个选项:文件,安全日志,和应用程序日志。如果你选择了后2个系统事件日志选项,没有可用的其它选项,剩下的选项只针对【文件】.
  • 如果你选择了【文件】选项,你需要指定一个文件路径。对于这个例子,我选择D:Junk。你可以把审核文件放在你想要的任何地方,例如其它盘甚至在网络硬盘上。
  • 其它选项与存储日志文件有关,让你在数据量和文件输上有限制。你可以指定【最大滚动更新文件数】,也可以指定【最大文件数】。使用【最大滚动更新文件数】选项,一旦文件夹里文件数达到最大数,SQL Server开始用最新的文件覆盖最老的文件。使用【最大文件数】选项,一旦达到指定的文件数,写入审核日志会失败。如果你勾选了关联的【无限制】选项,对于滚动更新数和文件数没有限制。你也可以指定【最大文件大小】,也可以设置【无限制】选项。对话框上的最后一个选项,【保留磁盘空间】,告诉SQL Server预留磁盘空间到你指定的最大文件大小,对于最大文件大小,只有在选择了【无限制】的情况下才会有。因此对于指定硬盘上的空间量,你有大量的控制选项。

插图11.1显示了对于Sample Audit完整的创建审核对话框信息。

插图11.1:在SSMS里,使用创建审核对话框创建一个服务器审核对象。

你也可以使用T-SQL代码创建审核。代码11.1显示了创建刚才一样配置的审核,使用CREATE SERVER AUDIT语句。我使用脚本按钮生成了这个代码,在创建审核对话框上,我修改了我想要的配置后,我还修改了一些代码。

USE master;
GO
CREATE SERVER AUDIT [Sample Audit]
TO FILE 
(    FILEPATH = N'D:Junk'
    ,MAXSIZE = 0 MB
    ,MAX_ROLLOVER_FILES = 2147483647
    ,RESERVE_DISK_SPACE = OFF
)
WITH
(    QUEUE_DELAY = 1000
    ,ON_FAILURE = CONTINUE
);
GO

代码11.1:你可以用来创建Sample Audit的T-SQL代码

代码11.2向你展示了如何创建一个服务器审核,写入日志到系统应用程序事件日志,而不是文件。没有其它可以设置选项,因此语句比刚才的例子小很多。

CREATE SERVER AUDIT SQLServerAudit
    TO APPLICATION_LOG
    WITH ( QUEUE_DELAY = 1000,  ON_FAILURE = CONTINUE);
GO

代码11.2:创建写入系统应用程序日志的SQL Server 审核的代码

在创建这2个审核后,可以看下对象浏览器的【安全性】节点里的【审核】节点(你要刷新下节点内容来查看它们),如插图11.2所示。看下,在放大镜图标上独有一个向下的红色箭头。这表示审核还没启用,创建后默认都没启用。你可以在对象浏览器里右击审核,在弹出菜单里选择【启用审核】来启用它们,或者用代码11.3使用ALTER SERVER AUDIT语句来修改审核。一旦启用审计,红色向下箭头会消失,在对象浏览器里你要刷新下来才可以看到。如果你在SSMS里和我们一起来操作,启用它们吧,一会我们要用到。

插图11.2:在对象浏览器里新建但没启用的服务器审核

1 ALTER SERVER AUDIT SQLServerAudit WITH (STATE = ON);
2 GO

代码11.3:启用SQLServerAudit审核的代码

创建一个服务器审核规范

一旦你创建了一个服务器审核,你可以定义你想要写入的审核时间。一个服务器审核基本上是审核规范的容器。记住有2类审核规范:服务器和数据库审核规范。

这里我创建的服务器审核规范会记录所有SQL Server失败的登陆。这个是服务器层级操作,不是单个数据库,因此我需要在服务器层级创建一个规范,而不是单个数据库层级。在SSMS里使用图形化用户界面,在服务器层级【安全性】节点里,右击【服务器审核规范】,从弹出菜单里选择【新建服务器审核规范】来打开【Create Server Audit Specification】对话框。

你可以使用默认生成的名称,但我这里命名为TestSQLServerAuditSpec。然后从【审核】下拉列表里选择【Sample Audit】,这里包含了SQL Server实例里已存在的所有服务器审核,选择【Sample Audit】意味着审核日志项目会进入审核里定义的文件系统。

然后你可以使用对话框里【审核操作类型】来定义你想要记录的事件或事件组。可用操作类型很丰富,如插图11.3所示。对于这个规范,选择【FAILED_LOGIN_GROUP】类型。

插图11.3:你可以选择记录的服务器操作审核类型很多

对于FAILED_LOGIN_GROUP操作类型剩下的列都停用了,因为对于这个类型没有其它可用选项。但其它类型会让你关联多个服务器对象。对话框如插图11.4所示,但你点击【确定】的时候会创建规范。

插图11.4:使用SSMS定义新的服务器审核规范

新定义的服务器审核规范会在对象浏览器里的【服务器审核规范】节点里出现,默认是停用的。你可以右击这个规范从弹出菜单里选择【启用服务器审核规范】来启用它。

你也可以使用代码11.4来创建新的服务器审核规范。这个代码使用WITH子句来接受用ON或OFF的STATE参数值,来启用或停用规范。如果你忽略这个子句,状态默认是OFF。

1 CREATE SERVER AUDIT SPECIFICATION TestSQLServerAuditSpec
2     FOR SERVER AUDIT [Sample Audit] ADD (FAILED_LOGIN_GROUP)
3     WITH (STATE = ON);
4 GO

代码11.4:使用可选的WITH子句来创建新的立即生效服务器审核规范。

测试审核,连接到SQL Server实例,尝试用不正确的登陆来连接实例。你可以用另一个的SSMS实例,也可以在对象浏览器的工具栏新开一个。

然后在对象浏览器里右击【安全性】【审核】下的【Sample Audit】,从弹出菜单里选择【查看审核日志】。你会看到如插图11.5的里列表。每行包含事件的一些信息,你可以拉伸下窗体看到更多的栏目信息。但当你点击一条记录时,数据会显示在窗体下方,更容易阅读。遗憾的是,列的格式并不好,如你在图中所示。

插图11.5:对Sample Audit查看它的审核日志

注意服务器审核自动捕获修改审核日志的事件,这里是我启用服务器审核的事件。即在图里表显示的第二行。

提示:

在它们捕获并写入事件前,你要启用服务器审核和服务器审核规范。通常,你在创建它们的时候就会启用它们。

创建一个数据库审核规范

创建一个数据库审核规范和创建服务器审核规范基本一样。最大的区别是在日志里你可以捕获的事件范围。数据库审核规范只能在单个数据库捕获事件,例如通过T-SQL语句访问数据,修改数据库对象的结构或许可,或执行存储过程。其它最大的区别是你在数据库对象里创建规范,而不是在对象浏览器里的服务器层级里创建。

假设你想创建审核记录什么时候,什么用户或进程在AdventureWorks2012数据库里对Person.Person表执行了SELECT语句。在数据库里,找到AdventureWorks2012数据库,展开节点,在【安全性】【数据库审核规范】右击,从弹出菜单里选择【新建数据库审核规范】,这会打开【创建数据库审核规范】对话框,修改自动生成的【名称】为Person Data Access,【审核】里选择Sample Audit,在操作里选择如插图11.6的内容。

插图11.6:创建数据库审核规范记录在AdventureWorks2012数据库里什么时候什么用户查询了Person.Person

你可以设置主体名称为任何数据库用户或角色,包括公共数据库角色来包含访问数据库的所有人。和服务器审核规范一样,你可以增加多个操作。

一旦你创建了规范,记得启用它。

同样,你也可以使用T-SQL代码来创建这个规范,有自动启用的选项WITH子句。

1 USE AdventureWorks2014;
2 GO
3 
4 CREATE DATABASE AUDIT SPECIFICATION [Person Data Access]
5     FOR SERVER AUDIT [Sample Audit]
6     ADD (SELECT ON OBJECT::Person.Person BY public)
7     WITH (STATE = ON);
8 GO

代码11.5:创建数据库审核规范记录Person.Person被查询

接下来,你可以通过执行对表的SELECT操作测试审核规范。一旦这样做后,再次检查下Sample Audit的审核日志,如插图11.7所示。如你所见,日志包含了事件的完整信息,包括引起它的SQL语句。

插图11.7:当查询Person.Persion表时的审核日志

注意在图中的【其它信息】是空的。这是因为生成日志条目的事件是直接的SELECT语句。但当SELECT语句在存储过程里或其它代码模块里执行时,其它信息会包含T-SQL堆栈信息,以XML格式。这个用来识别查询是语句还是代码模块实行非常有用。

-- Test it using a stored procedure
CREATE PROCEDURE tempPerson
AS
BEGIN
    SET NOCOUNT ON;

    SELECT BusinessEntityID, Title, FirstName, MiddleName, LastName, Suffix
        FROM Person.Person
    ORDER BY LastName, FirstName, MiddleName;
END
GO
EXEC dbo.tempPerson;

重新运行后,我们再次来看日志。

插图11.8:当通过存储过程运行SELECT语句,会包含T-SQL堆栈信息

其它信息包含XML片段,包含引起审核日志条目的一些信息,架构和存储过程名。

写自定义审核信息

对每类事件,你不限于把默认信息写入日志条目。你也可以创建用户自定义审核事件,它让你写入任何你想写的东西。代码11.6展示了这个方法。当审核规范(不管服务器还是数据库)被停用时,你才可以修改它。因此代码首先停用它,然后它添加使用USER_DEFINED_AUDIT_GROUP的TestSQLServerAuditSpec到审核规范,并立即启用它。最后一行代码使用sp_audit_write系统存储过程来写入一些信息到审核日志。

USE master;
GO

ALTER SERVER AUDIT SPECIFICATION TestSQLServerAuditSpec
    WITH (STATE = OFF);
GO

ALTER SERVER AUDIT SPECIFICATION TestSQLServerAuditSpec
    ADD (USER_DEFINED_AUDIT_GROUP)
    WITH (STATE = ON);
GO

-- Write some custom audit information
EXEC sp_audit_write 9999, 1, N'Something in SQL Server succeeded!'

代码11.6:使用USER_DEFINED_AUDIT_GROUP操作类型来写自定义审核信息到服务器审核规范

当然,你也可以用SSMS的可视化用户界面来修改服务器审核规范。

如果你执行刚才的代码并查看日志,你会看到如插图11.9的信息。你还是会看到审核事件的上下文,包括引起事件的T-SQL语句,但在底部,你会看到用户定义的信息。

插图11.9:包含用户自定义信息的审核日志条目

  提示:如果USER_DEFINED_AUDIT_GROUP服务器审核规范停用的话,SQL Server会忽略sp_audit_write

筛选审核事件

SQL Server也包含筛选写入审核日志事件的能力,这个和扩展事件使用同样的筛选机制。筛选给你颗粒度的控制,SQL Server写入审核日志的内容。但是SQL Server还是为你在规范里定义的事件生成所有的日志条目,然后使用筛选来觉得是否写入事件到日志,理解这个非常重要。因此你还是有大量的日志事件生成,即使这些条目不写入日志。这就是说还是为特定的对象创建审核事件,而不是筛选它们。

现在假设你想创建一个审核,记录特定类型的所有事件,除用特定登陆关联之外。代码11.7第一部分在AdventureWorks2012数据库里创建carol登录和登录的用户。然后使用SUSER_ID方法获得新用户的主体ID(这里是267)。然后第二部分创建一个服务器审核使用WHERE子句筛选主体ID不为267的事件,并启用服务器审核。现在carol在数据库里有自由领域,在服务器审核事件里是安全的。

CREATE LOGIN carol WITH PASSWORD = 'GEP2zYDt+5Cqw';
CREATE USER carol FOR LOGIN carol;
SELECT SUSER_ID('carol');

-- Part 2: Create the server audit
-- Change principal id from 307 based on SUSER_ID from previous statement
USE master;
GO

CREATE SERVER AUDIT FilterAudit
    TO APPLICATION_LOG
WITH
(    QUEUE_DELAY = 1000
    ,ON_FAILURE = CONTINUE
)
WHERE server_principal_id <> 267;

ALTER SERVER AUDIT FilterAudit WITH (STATE = ON);
GO

代码11.7:在AdventureWorks2012数据库里创建一个登录和用户,然后创建除这个用户外的服务器审核

你也可以只用审核属性对话框筛选事件,在对象浏览器里右击服务器审核,在弹出菜单里选择属性。选择【Filter】页,如插图11.10所示。注意,这里没有WHERE语句。

插图11.10:使用审核属性对话框来添加筛选到服务器审核

小结

SQL Server的审核功能,让你为数据库实例和数据库范围里的各个不同事件,记录日志。你可以使用SSMS里的用户图形界面或T-SQL代码来创建不同审核对象,有很多选项来完成,例如筛选记录,写自定义信息到日志,和查看T-SQL的堆栈信息。审核是SQL Server一个重要的安全功能,在你的数据库里帮你找出可疑的活动,这样的话你可以消除掉你数据的安全漏洞。

原文链接

http://www.sqlservercentral.com/articles/Stairway+Series/130498/

原文地址:https://www.cnblogs.com/woodytu/p/5374230.html