DBA必读:SQL Server 2008安全概述

SQL Server 专栏收录该内容
9 篇文章 0 订阅

作者:戴羽 来源:互联网   酷勤网收集 2008-01-09

1.导言

  随着网络越来越多的连接到一起,安全就变得更为重要。必须保护你的公司的设备,特别是它的数据库,它包含了你公司的非常重要的信息。安全是一个数据库引擎的重要特性之一,它保护企业免受众多威胁。Microsoft® SQL Server™ 2008的安全特性是设计用来使它更加安全并使得对于那些有责任保护数据安全的人们来说安全是触手可及和容易理解的。

  在过去的几年,人们已经对什么是基于计算机的系统的安全开发了一套非常成熟的理念。Microsoft 站在这个开发的最前沿,而SQL Server 是第一代完全贯彻了这个理念的服务器产品中的一个。它采用了最小权限的重要原则,所以你不需求为用户授予比他们执行他们的工作所需的更多的权限。它为防范提供了深入渗透工具,以便你可以实施措施来阻止最具技巧的攻击者。

  讨论了许多关于Microsoft指导公司里所有软件部署的可信赖计算计划(Trustworthy Computing initiative)。要获得更多的信息,请查看可信赖计算网站(http://www.microsoft.com/mscorp/twc/default.mspx).

  这个计划的四个重要组成部分是:

  · 设计安全。软件需要一个安全的设计作为抵制攻击者和保护数据的基础。

  · 缺省安全。系统管理员应该不需要花费时间去做一个新的安装安全;它应该可以按缺省来完成。

  · 部署安全。软件应该帮助保持它自己的最新安全补丁包的更新和协助维护。

  · 通信。传达最佳方法和威胁信息,以便管理员可以预先保护他们的系统。

  在SQL Server 2008中体现了这些指导原则,它提供了你需要保护你的数据库所需的所有工具。

  这篇白皮书探讨了对于系统和数据库管理员来说最重要的安全特性。它从讲述SQL Server 2008是怎样简单而安全地进行安装和配置。它探讨了验证和授权特性,这些控制对服务器的访问和决定一个用户一旦通过了验证他可以做什么。它最后讲述了一个管理员所需要了解的数据库安全特性,以便能够为数据库和访问这些数据库的应用程序提供一个安全的环境。

  2.安全配置

  一个安全的SQL Server 安装的第一个要求就是要有一个安全的环境。一个运行SQL Server 2008的服务器的外部安全要求没有什么改变。你需要保护服务器和定时地备份数据,如果它连接到网络上那么将它放到一个或多个防火墙后面,避免在一个装有其它服务器应用程序的计算机上安装SQL Server,并只使用所要求的最少的网络协议。在一个Microsoft Windows Server® 2003或Microsoft Windows Server® 2008计算机上安装SQL Server,以便它可以充分利用操作系统级别的安全保护。进一步的,在一个或多个NTFS分区上的安装是最安全的。

  确保环境是安全的之后,安全地安装SQL Server 2008是极为重要的。这个安装过程执行所有常规的安全工作,并有一个System Configuration Checker 会通知你所有可能会引起问题的漏洞。安装SQL Server 2008默认情况下不使用所有的特性。而是安装核心关键的和广泛使用的特性。其它可能在生产环境中不需要的特性会被默认的关闭。你可以使用所支持的工具将你需要的特性打开。

  这是可信赖计算安全所默认的所有要求。它意味着SQL Server 2008在你安装的时候是安全的,默认设置也是安全的。一个基本的数据库服务器所不需要的特性没有被安装,旨在降低外围应用。因为按默认的情况下不是系统中所有的特性都可用,这在系统安装图象方面推出了一个异构。因为这样限制了具有易受潜在攻击的特性的系统的数目,所以它帮助防范大范围的攻击或是蠕虫。

  2.1 Windows更新

  你在企业中部署了SQL Server 之后就很容易发现新的威胁和漏洞。Windows 更新是设计用来确保及时下载可以显著减少特殊的安全问题的应用程序补丁包。你可以使用Windows 更新来自动地应用SQL Server 2008补丁包,从而减少由已知的软件漏洞所引起的威胁。在大多数企业环境中,你应该使用Windows Server Update Service (WSUS)来管理补丁包的发送和在整个企业中进行更新。

  2.2 外围应用配置

  SQL Server 2008具有许多特性,其中许多是以关闭状态安装的。例如,CLR集成、数据库镜像、调试、Service Broker 和邮件功能都安装了,但是没有运行也不可用,除非你明确地将它们打开或是配置它们。这个设计与SQL server所默认的安全中的外围应用范例的缩减是一致的,它导致降低了攻击外围应用。如果一个特性不可用或没有开启,那么一个攻击者是不能利用它的。

  要权衡的是,要跟踪所有开启特性的Transact-SQL语句是很耗时的。甚至当你发现sp_configure system存储过程做了许多你所需要的,但仍然需要编写非原有的代码,如下所示:

以下是引用片段:
  sp_configure 'show advanced options', 1
  reconfigure with override
  sp_configure 'clr enabled', 1

  有许多配置选项要花费时间来编写这种代码——特别是当你在企业中部署了多个SQL server实例的时候。SQL Server 2008包含一个基于政策的管理技术,叫做声明式管理框架(Declarative Management Framework,DMF)。DMF提供了一些配置分面,其中每一个都定义了一组相关的配置设置或属性。你可以使用这些分面来创建指定想要的配置选项的设置的条件,并将这些条件作为政策实施到企业中的SQL Server实例上。

  在SQL Server 2008中所包含的分面的其中之一是Surface Area 分面,你可以使用这个分面来定义一个控制许多SQL Server 2008特性的状态的政策。通过创建一个定义你想要的用于你的服务器的surface area设置的政策,你可以很容易地在你公司里的所有SQL Server实例上实施最小限度的surface area,并且可以降低恶意攻击的可能性。

  3. 验证

  Microsoft部署SQL Server 2000时是当数据和服务器要求保护但不需要抵挡如今在网络上所看到的攻击的时候。基本的验证问题仍然相同,“你是谁、你怎样证明?”但是SQL Server 2008提供更多强大的验证特性,它们提供了更好的支持,在服务器的安全防卫上让好人通过,把坏人阻挡在外。

  SQL Server 验证提供了对不是基于Windows的客户端或应用程序的验证,它使用一个简单的连接字符串,其中包含用户ID和密码。尽管这个登陆易于使用并在应用程序开发人员中很流行,但是它不像Windows 验证一样安全,是不建议使用的验证机制。

  SQL Server 2008改进了SQL Server验证的选项。首先,它支持默认情况下通过使用SQL产生的证书进行路线加密。管理员不需要获得和安装一个有效的SSL证书来确保SQL证书流程的路线是安全的。有了SQL Server 2008 自动生成这些证书,当传送登陆包时它在默认情况下自动加密路线。这发生在客户端是SQL Server 2005级别或以上的情况下。

  注意 当攻击者在网络上搜寻时,SQL Server产生的本地证书防止被动的中间人攻击。为了更有效地保护你的系统免受中间人攻击,你应该部署和使用客户端信任的证书。

  SQL Server 2008进一步地加强了SQL Server验证,因为默认情况下,在与Windows 2003 server或以上版本结合使用时,数据库引擎目前采用Windows Group Policy用于密码复杂度、密码期限和在SQL登陆中的账户锁定。这意味着你可以对你的SQL Server帐户实施Windows密码政策。

  3.1 实施密码政策

  对于SQL Server 2008,密码政策的实施是内嵌到服务器中的。使用NetValidatePasswordPolicy()API,它是Windows Server 2003上的NetAPI32 库的一部分,SQL Server 在验证期间和按照Windows对于密码强度、期限和帐户锁定的政策进行密码的设置和重置期间进行密码验证。表3列出了这个政策的组成部分。

 

种类

名称

注释

密码政策

实行密码历史

防止用户重用旧的密码,例如在两个密码间转换。

 

最小的密码长度

 

 

密码必须满足复杂度要求

看下面的文本。

 

使用可逆的加密来存储密码

允许从Windows获得密码。你应该永远不使用这个,除非应用程序不要求安全的密码。(这个政策不适用于SQL Server。)

密码期限

最大密码期限

 

 

最小密码期限

 

帐户锁定政策

帐户锁定持续时间

帐户锁定的Windows持续时间,以分钟计。当锁定极限>0时,Windows 使得这个可用。

 

帐户锁定极限

不成功的登陆尝试的最大次数。

 

解锁后重置帐户锁定计数器

Windows 重置了不成功的登陆尝试的计数器后以分钟来计时。当锁定极限>0时,Windows 使得这个可用。

  表 3 Windows Server 2003密码政策组成部分

 

  如果你不是运行Windows Server 2003或以上版本,那么SQL Server 还会使用简单的检查来实施密码增强,防止密码是如下情况的:

  · Null或空

  · 与计算机名称或登陆名相同

  · 任何是“password”、“ admin”、“ administrator”、“ sysadmin”的密码

  相同的复杂度标准应用于你在SQL Server中创建和使用的所有密码,包括用于sa 登陆、应用角色、用于加密的数据库主键、以及相应的密钥的密码。

  SQL Server 总是默认检查密码政策,但是你可以对单个的登陆实行挂起,通过使用如下所示的代码中的CREATE LOGIN或ALTER LOGIN:

以下是引用片段:
  CREATE LOGIN bob WITH PASSWORD = 'S%V7Vlv3c9Es8',
  CHECK_EXPIRATION = OFF, CHECK_POLICY = OFF

  CHECK_EXPIRATION 使用Windows Server 2003政策的最大和最小密码期限部分,而CHECK_POLICY 使用其它的政策设置。

  管理设置还允许打开和关闭密码期限检查,并使得当一个用户第一次登陆时要修改密码。在CREATE LOGIN 中的MUST_CHANGE 选项使得用户在他们下一次登陆的时候修改密码。在客户端,它允许在登陆的时候修改密码。所有的新客户端数据访问技术将支持这一点,包括OLE DB和OLE DB ,还有客户端工具,例如管理套件。

  如果用户登陆尝试失败了太多次,超过了密码政策的允许次数,SQL Server会基于在Windows 政策中的设置锁定这个帐户。一个管理员可以使用ALTER LOGIN语句为这个帐户解锁:

以下是引用片段:
  ALTER LOGIN alice WITH PASSWORD = '3x1Tq#PO^YIAz' UNLOCK

  3.2 终端验证

  SQL Server 2008支持传统的用于客户端访问数据的二进制表格数据流(Tabular Data Stream),还支持本地的使用HTTP的XML Web service 访问。允许通过HTTP来访问的主要好处是了解Web service的任何客户端软件和开发工具都可以访问存储在SQL Server中的数据。这意味着SQL Server 2008可以提供独立的Web service 方法,并且是服务面向架构(SOA)中的一个完整的终端。

  使用SQL Server 2008作为一个Web service 主机需要两个常规步骤,每一个都有许多可能:定义存储过程和用户定义的提供了Web service方法的功能、定义一个通过HTTP接收方法调用和将它们发送到适合的过程中去的HTTP终端。这篇白皮书专注于相关的安全问题。要查看配置和使用HTTP终端的细节,请查看SQL Server在线书籍的CREATE ENDPOINT(Transact-SQL)。

  因为SQL Server 中的XML Web service使用HTTP和默认情况下的80端口,大多数防火墙允许它通过。然而,一个不受保护的终端对于攻击者来说是一个潜在的美味,你必须保护它,所以SQL Server 拥有强大的验证和授权能力。默认情况下,SQL Server 没有任何终端,你不得不具有一个高级别的权限来创建、修改和开启HTTP终端。

  SQL Server 2008提供了五个验证类型,和IIS用于网站验证所使用的类似。

  · 基本验证

  基本验证是HTTP 1.1协议的一部分,它将登陆凭证放在基于-64编码的文本中传输。这个凭证必须与一个Windows登陆相匹配,然后SQL Server 使用它来验证对数据库资源的访问。如果你使用基本验证,你不能将PORTS参数设置为CLEAR ,而是必须设置它为SSL,并使用一个SSL的数字证书来加密与客户端软件的通信。

  · 摘要验证

  摘要验证也是HTTP 1.1协议的一部分。它在发送给服务器之前使用MD5哈希了凭证以便它不能通过电线发送它们,甚至是以加密的形式。这个凭证必须匹配一个有效的Windows域帐户;你不能使用本地用户帐户。

  · NTLM验证

  NTLM使用一开始在Microsoft Windows NT®中推出的挑战响应协议,并在之后的所有的Windows客户端和服务器版本中获得支持。它在客户端和服务器都是Windows系统时提供了安全验证,并要求一个有效的域帐户。

  · Kerberos验证

  Kerberos验证在Windows 2000和之后的版本中有效,它基于一个在许多操作系统中可用的行业标准协议。它允许相互验证,其中客户端和服务器都会一定程度上确定另一个的验证,并提供一个非常安全的验证形式。为了在Windows Server 2003上使用Kerberos,你必须使用SetSPN.exe工具用Http.sys注册Kerberos服务主体名称(Service Principal Name,SPN),SetSPN.exe工具是Windows支持工具的一部分。

  · 集成验证

  集成验证提供了最好的NTLM和Kerberos 验证。服务器使用客户端所要求的这两个验证类型之一,允许客户端支持最安全的验证,同时使得服务可用于Windows的之前版本。你可以在Windows 2003中配置Http.sys以决定它应该使用哪个协议。

  这个用于终端的验证方法使用CREATE或ALTER ENDPOINT语句的AUTHENTICATION属性来设置。例如,下面的代码创建了一个使用Kerberos来验证的终端:

以下是引用片段:
  CREATE ENDPOINT myEndpoint
  STATE=STARTED
  AS HTTP (PATH = '/MyHttpEndpoint',
  AUTHENTICATION = (KERBEROS),
  PORTS = (CLEAR),
  SITE = 'MySqlServer')
  FOR SOAP (WSDL = DEFAULT,
  DATABASE = 'myDB',
  NAMESPACE = 'http://example.com/MySqlServer/myDB/WebService')

  SQL Server 2008支持监听HTTP和在TCP上的用户定义的端口的终端。你还可以使用许多格式来格式化请求:SOAP、Transact-SQL 、专用于Service Broker 的格式、和另一个用于数据库镜像的格式。当使用SOAP时,你可以利用Web服务安全性(WS-Security)头来验证SQL Server 登陆。

  Microsoft 实行Web Service 终端验证来支持极广泛的协议和规格,本篇白皮书描述了其中的一部分。你将需要打开你的验证选项并确保客户端可以提供所需的凭证类型。一旦SQL Server 验证通过了客户端,你就可以授予这个登陆被授权可以访问的资源,如下一节所描述的。

  4. 授权

  在验证之后,该考虑验证过的登陆可以做些什么了。在这个领域,SQL Server 2008和SQL Server 2005比之前的版本更加灵活。现在的权限更加细粒度了,因此你可以授予所要求的专门的权限,而不是授权给具有一个固定角色的成员,这很可能会承载比它所需的权限更多的权限。你现在具有更多的要保护的实体,你可以对它们分配更细粒度的权限。

  除了加强用户数据的保护,关于一个细粒度的要保护的结构信息和元数据现在只可用于具有权限访问这要保护的信息的主体。

  此完,还可以使用一个机制创建定制权限集合,这个机制允许一个人定义安全上下文,存储过程可以运行在这个上下文之下。

  此外,SQL Agent 使用灵活的代理scheme 来允许工作步骤运行和访问所要求的资源。所有这些特性使得SQL Server更加复杂但是更加安全。

  4.1 细粒度权限

  SQL Server 2008和SQL Server 2005在许多方面比之前的版本更加安全,其中之一就是改进的细粒度权限。之前,一个管理员需要给一个在固定的服务器角色或固定的数据库角色中的用户成员授予权限,以执行特定的操作,但是通常情况是,这些角色具有比执行这些简单工作所需的权限多很多的权限。这个最小权限的原则要求一个用户只有要做这个工作的最少的权限,所以分配给用户广泛的角色以执行很少的工作违反了这个原则。

  固定服务器和数据库角色的集合从SQL Server 2000以来没有怎么改变,所以你仍然可以在用户或应用程序要求所有或大部分定义的权限时利用这些预定义的权限集。可能最大的改变就是添加了一个public服务器角色。然而,最小权限的原则要求你不使用一个不是正好适用于这个原则做这个工作所需要的角色。尽管它要求更多的工作来发现和指派某原则所需的权限,但是它可以生成一个更加安全的数据库环境。

  4.2 主体和可得到的

  在SQL Server 2008中,一个主体是任何单独的、可以要求访问受保护的资源并可被授予权限来访问它的个体、组或过程。在SQL Server的之前版本中,你可以定义一个Windows中的主体或者你将它基于一个SQL Server登陆而不和Windows主体关联。下面的列表显示了SQL Server 2008主体的层次,不包括固定服务器和数据库角色,以及你可以怎样匹配登陆和数据库用户来保护对象。这个主体的影响范围取决于它的定义的范围,因此一个Windows级别的主体比一个SQL Server级别的主体范围更广。每一个数据库用户会自动地属于固定的公共(public)角色。

  Windows级别主体

  · Windows域登陆

  · Windows本地登陆

  · Windows组

  SQL Server级别主体

  · SQL Server登陆

  · 与一个Windows 登陆相匹配的SQL Server登陆

  · 与一个证书相匹配的SQL Server登陆

  · 与一个非对称密钥相匹配的SQL Server登陆

  数据库级别的主体

  · 数据库用户

  · 与一个SQL Server登陆相匹配的数据库用户

  · 与一个Windows 登陆相匹配的数据库用户

  · 与一个证书相匹配的数据库用户

  · 与一个非对称密钥相匹配的数据库用户

  · 数据库角色

  · 应用程序角色

  · 公共角色

  授权的另一个部分是你可以通过授予或拒绝授予权限来保护的对象。图4列出了SQL Server 2008中可保护的对象的层次。在服务器级别,你可以保护网络终端来控制通信路线进出服务器,还有数据库、绑定和角色以及登陆。在数据库和schema级别,事实上你可以创建的每一个对象都是可得到的,包括那些存在于schema之中的。

  图 4在SQL Server 2008中的可得到的对象的层次

  4.3 角色和权限

  要想知道在SQL Server中可用的权限的数目,你可以调用fn_builtin_permissions系统功能:

以下是引用片段:
  SELECT * FROM sys.fn_builtin_permissions(default)

  这些是SQL Server 2005中的新的权限类型:

  · CONTROL。 授予所有者想要的权限,这些权限可以有效地对这个对象授予所有定义的权限,并且所有对象在它的范围内,包括授予其它受权人任何权限的能力。CONTROL SERVER授予等价于sysadmin的权限。

  · ALTER。授予权限来修改可得到的对象的任何属性,除了修改所属关系。固定地授予权限给相同范围内的ALTER、CREATE或 DROP 可得到的对象。例如,授予一个数据库上的ALTER权限,包括修改它的表。

  · ALTER ANY <可得到的对象>。 授予权限以修改可得到的指定类型的对象。例如,授予ALTER ANY ASSEMBLY允许修改数据库中的任何.NET 集合,而在服务器级别授予ALTER ANY LOGIN 使得用户修改任何在服务器上的登陆。

  · IMPERSONATE ON <登陆或用户>。 授予权限来模拟特定的用户或登陆。你在本篇文章的后面可以看到,这个权限对于为存储过程转换执行上下文是很必要的。你在一个批处理中进行模拟也需要这个权限。

  · TAKE OWNERSHIP。 授予权限给受权人以使用可得到的所有权,使用ALTER AUTHORIZATION语句。

  SQL Server 2008仍然使用类似的GRANT、DENY和REVOKE scheme来指派或拒绝给一个主体授予对一个可得到的对象的权限。现在ANT 语句涵盖了所有新的权限选项,例如授予的范围和是否主体可以授予这个权限给其它主体。SQL Server 不允许数据库交叉权限。为了授予这样的权限,你要在每一个数据库中创建一个复制的用户,并单独的给每一个数据库用户指派这个权限。

  如同SQL Server 之前的版本一样,激活一个应用程序角色会在这个角色活动的期限内挂起其它的权限。然而,在SQL Server 2008和SQL Server 2005中,你具有卸载应用程序角色的能力。SQL Server 2000和之后版本的另一个不同之处是,当激活一个应用程序角色时,这个角色还会挂起任何服务器权限,包括public。例如,如果你授予VIEW ANY DEFINITION给public,应用程序不会受益于它。这是当在一个应用程序角色上下文中访问服务器级别的元数据时值得注意的。

  注意 这个新的首选的应用程序角色选择将使用代码模块中的执行上下文。要获得更多的信息,请查看本文中的执行上下文一节。

  授予一个特殊的权限可以传递其它暗含的权限。例如在一个schema 上的ALTER 权限暗含了更细粒度和较低级别的权限。图5显示了ALTER SCHEMA暗含的权限。

  图 5: ALTER SCHEMA 所暗含的权限层次

  当你考虑可用的主体的数目和类型、服务器和一个典型的数据库中的可得到的对象的数目、可用的权限和隐藏的以及暗含的权限的数目时,“在SQL Server 2008中的细粒度权限是怎样的”就立刻清楚了。现在创建一个数据库要求更细致地分析它的安全需求和谨慎地控制在所有对象上的权限。然而,这个分析是很值得的,在SQL Server 2008中使用这些功能会使得数据库更安全。

  4.4 元数据安全

  细粒度权限scheme 的一个好处是SQL Server保护元数据和数据。在SQL Server 2005之前,一个用户对数据库的任何访问都会看到数据库中的所有对象的元数据,无论这个用户是否可以访问其中的数据或执行存储过程。

  SQL Server 2008检查主体在数据库中具有的权限,并仅当这个主体是所有人或他具有这个对象的一些权限时才可以显示这个对象的元数据。还有一个VIEW DEFINITION 权限可以授予查看元数据信息的权限,它甚至不需要这个对象的其它权限。

  这个保护扩展到因用户没有权限所做的访问或更新对象的操作所返回的错误信息。不只是承认确实有一个表叫做Address ,还给攻击者一个信息说她被跟踪了,SQL Server返回一个具有选择可能性的错误信息。例如,如果一个用户没有对数据库中的任何对象的权限,他试图删除Address表,那么SQL Server 会显示下面的错误信息:

以下是引用片段:
  Msg 3701, Level 14, State 20, Line 1
  Cannot drop the table 'Address', because it does not exist or you do not have permission.

  在这种方式下,攻击者不能确定一个Address表是否真的存在。然而,调试这个问题的人仍然只需要探究有限的可能性。

  4.5 SQL Server Agent代理

  在SQL Server 2008中的授权模型的一个最好的例子就是SQL Server Agent。你可以定义许多常常与Windows登陆关联的凭证,链接到具有必要的权限的用户以执行一个或多个SQL Server Agent步骤。然后一个SQL Server Agent 代理会使用一个工作步骤链接这个凭证来提供必要的权限。

  这为下面的最小权限的主体提供了一个细粒度的方法:授予一个工作步骤所需的权限,除此以外没有其它权限。你可以创建任何数目的代理,将它们的每一个同一个或多个SQL Server Agent子系统关联起来。这是对SQL Server 2000中的所有强大的代理帐户的完全约束,它使得用户可以在任何SQL Server Agent子系统中创建工作步骤。

  注意 当你对一个SQL Server 2000服务器进行升级的时候,会创建一个单独的代理账户,所有的子系统会被分配到这个单独的代理账户上以便现有的工作可以继续运行。在升级之后,创建凭证和代理账户来实现一组更加安全的、更细粒度的代理来保护服务器资源。

  图6显示了管理套件中的对象资源管理器和一列SQL Server Agent中可用的子系统。每一个子系统可以有与它关联的一个或多个代理,它们授予这个工作步骤所需的适当的权限。这个scheme的一个例外是Transact-SQL子系统以模块所有者的权限来执行,这和在SQL Server 2000中是一样的。

  图 6: 你可以将之与代理相关联的SQL Server Agent子系统

  在一个新安装的SQL Server 之上,只有System Administrator 角色具有维护SQL Server Agent 工作的权限,管理套件资源管理器中的管理面板只对sysadmins开放。SQL Server 2008具有一些其它的、你可以用来授予多级权限的角色。你可以将用户分配到SQLAgentUser、SQLAgentReaderRole或SQLAgentOperator 角色,其中的每一个授予逐渐增长的权限级别来创建、管理和运行工作,或是MaintenanceUser 角色,它具有SQLAgentUser的所有的权限和创建维护计划的能力。

  sysadmin 角色的成员当然可以在任何子系统中做任何他们想要做的。为了授权给任何其他的用户以使用子系统,要求至少创建一个代理帐户,它可以授权给一个或多个子系统。图7显示一个代理帐户MyProxy怎样被分配到多个主体上,这里是一个用户和一个角色。这个代理帐户使用一个凭证,这个凭证将它链接到一个帐户,通常是一个域帐户,它要具有操作系统执行子系统所要求的所有任务所必需的权限。每一个代理可以有一个或多个相关联的子系统,这些子系统授予主体以运行这些子系统的能力。

  图 7:用于多个子系统的SQL Server Agent代理帐户

  下面的代码显示了执行图7所示的scheme所必需的Transact-SQL代码。它一开始创建了一个凭证,一个提供了对具有执行子系统中想要的活动的权限的操作系统帐户的链接的数据库对象。然后它添加一个代理帐户——MyProxy,这只是一个用于凭证的友好名称。然后,它将这个代理分派到两个首要角色上,在这里是一个SQL Server登陆和一个定制角色。最后它将这个代理和四个SQL Server Agent子系统的每一个相关联。

以下是引用片段:

CREATE CREDENTIAL MyCredential WITH IDENTITY = 'MyDOMAIN\user1'
GO
msdb..sp_add_proxy @proxy_name = 'MyProxy',
    @credential_name = 'MyCredential'
GO
msdb..sp_grant_login_to_proxy @login_name = 'MyLogin',
    @proxy_name = 'MyProxy'
GO
msdb..sp_grant_login_to_proxy @login_name = 'MyRole',
    @proxy_name = 'MyProxy'
GO

sp_grant_proxy_to_subsystem @proxy_name = 'MyProxy',
    @subsystem_name = 'ActiveScripting'
GO
sp_grant_proxy_to_subsystem @proxy_name = 'MyProxy',
    @subsystem_name = 'CmdExec'
GO
sp_grant_proxy_to_subsystem @proxy_name = 'MyProxy',
    @subsystem_name = 'ANALYSISQUERY'
GO
sp_grant_proxy_to_subsystem @proxy_name = 'MyProxy',
    @subsystem_name = 'DTS'
GO

  SQL Server管理套件提供了对创建凭证和代理的充分支持,如图8所示。它创建了与之前的代码相同的代理。

  图 8:在SQL Server管理套件中的一个新的SQL Server Agent代理

  一个代理不是操作系统中围绕安全的一个方式。如果和代理一起使用的凭证没有在Windows中的权限,例如写到网络上的一个目录中,那么代理也没有这个权限。你还可以使用一个代理来授予有限的执行权限给xp_cmdshell ,因为它是攻击者所喜爱的一个工具,一旦他们危及一个SQL Server计算机他们就能扩展他们在网络中的范围。这个代理提供了这个保护,因为即使主体具有在网络上的无限的权限,例如域管理员,但是通过代理执行的任何命令只具有凭证帐户所具有的有限的权限。

  4.6 执行上下文

  SQL Server 很久以来就支持所有权链接作为一个确保管理员和应用程序开发人员对访问数据库的入口检查其权限而不是对所有访问的对象的权限进行检查的概念。只要调用模块(存储过程或函数)或者视图的用户具有对这个模块的执行权限,或者具有对视图的选择权限,并且这个模块或视图的所有人是访问对象的所有人(一个所有权链),那么就不会检查对基本对象具有的权限,而调用者会得到请求的数据。

  如果所有权链接由于代码的所有者不拥有引用的对象的原因而被破坏了,那么SQL Server将对调用者的安全上下文检查权限。如果调用者具有访问这个对象的权限,那么SQL Server 返回数据。如果她没有,那么SQL Server 将报错。

  所有权链接有一些局限性;它只适用于数据操作而不适用于动态SQL。进一步的,如果你穿过所有权限定访问对象,所有权链接就不可用。因此,这个预先的权限检查行为只能用于特定的情况。

  SQL Server 2008具有使用一个执行上下文标识模块的能力,这样在模块中的语句就可以作为与调用用户相反的特殊用户来执行。这个方式,当调用用户仍然需要权限来执行模块时,SQL Server为模块内的语句对模块的执行上下文检查权限。你可以使用这个行动来克服所有权链接的一些缺点,因为它适用于模块内的所有语句。管理员如果想执行预先的权限检查的话可以使用执行上下文来完成这个工作。

  现在当你定义用户定义的功能(除了在线的值为表的情况),存储过程和触发器时你可以使用EXECUTE AS 条件来指定SQL Server 使用哪个用户的权限来验证对由以下过程引用的对象和数据的访问:

以下是引用片段:
  CREATE PROCEDURE GetData(@Table varchar(40))
  WITH EXECUTE AS 'User1'

  SQL Server 提供了四个EXECUTE AS选项。

  · EXECUTE AS CALLER 指定了在模块的调用者的安全上下文中执行的代码;没有发生身份模拟。调用者必须具有对所有引用的对象的访问权限。然而,SQL Server 只检查对所有权断链的权限,所以如果这个代码的所有者还拥有后台的对象,那么只会检查模块的执行权限。这是向后兼容性的默认执行上下文。

  · EXECUTE AS 'user_name' 指定了代码执行在指定用户的安全上下文下。如果你不想依赖于所有权链那么这是一个很好的选择。相反,你创建一个具有必要权限的用户来允许这个代码和创建定制的权限集合。

  · EXECUTE AS SELF 是一个缩写符号,用于指定要创建或修改这个模块的用户的安全上下文。SQL Server 在内部保存和这个模块相关联的实际的用户名称,而不是“SELF”。

  · EXECUTE AS OWNER 指定这个安全上下文是模块执行时的模块当前所有者的安全上下文。如果这个模块没有所有者,那么使用所包含的schema的所有者的上下文。当你想能够改变这个模块的所有者而不改变模块本身的时候这是一个很好的选择。

  只要用户上下文使用EXECUTE AS选项进行变更,那么模块的创建者或更改者必须具有对指定的用户的IMPERSONATE权限。你不能从数据库中删除指定的用户,除非你将所有模块的执行上下文更改为其它的用户。

  4.7 用户/schema分离

  SQL Server 2000没有schema的概念,而在ANSI SQL-99规范中将schema定义为一个数据库对象的集合,由形成了对象的一个单独的命名空间的一个单独的主体所有。Schema是数据库对象的一个容器,例如表、视图、存储过程、函数、类型和触发器。它在.NET框架中更多的是作为一个命名空间函数,而XML是一种组织对象的方式,以便数据库可以重用对象名称,例如允许dbo.Customer和Fred.Customer存在于一个单独的数据库中,并将对象分类到不同的所有者下面。

  注意你将需要使用目录视图例如sys.database_sys.principals、sys.schemas, sys.objects等等。因为老的sysobjects系统表不支持schemas,因此不能支持U/S分离。此外,老的目录视图是不被支持的,所以它们在SQL Server的未来版本中将被删除。

  图9的上面部分显示了SQL Server 2000中schemas是怎样工作的。当一个管理员在数据库中创建一个用户Alice 时,SQL Server 会自动地创建一个隐藏在用户Alice之后的schema Alice。如果Alice 登陆到一个运行SQL Server而他没有所有权的服务器上创建Table1,那么表的实际名称是Alice.Table1。Alice 创建的其它对象也是一样,例如Alice.StoredProcedure1和Alice.View1。如果Alice 是一个数据库所有人或者是sysadmin ,那么她创建的对象将是dbo schema的一部分。尽管我们习惯说dbo拥有对象,但是它其实是一回事。

  图 9:在SQL Server 2000和2008中的用户/schema/对象

  在SQL Server 2000 中当你需要改变对象的所有权时就会遇到用户和schemas的统一问题,例如当Alice离开公司而Lucinda接替了Alice的工作。那么一个系统管理员需要将Alice所拥有的所有对象的所有权改变为Lucinda的。一个更大的问题是在Lucinda具有了表的所有权之后你需要将所有涉及到Alice.Table1的Transact-SQL或客户端应用程序代码改变为Lucinda.Table1。这取决于Alice所拥有的对象的数目和有多少应用程序中内嵌了这个名字;这是一个很大的消耗。Microsoft很久以前就建议内置的dbo用户拥有所有的数据库对象来解决这些问题。更改一个数据库所有权比更改许多对象和客户端应用程序要容易得多。

  注意 不要被SQL Server 2000的CREATE SCHEMA语句混淆。这只是一个创建特定用户所拥有的表和视图和授权的简便方法。你可以使用这个语句来命名一个schema的所有者但是不能命名这个schema。因为要改变所有权的问题,SQL Server仍然不能将所有者链接到schema上。

  SQL Server 2008通过将用户和schema分离开来从而解决了这个问题并实现了SQL-99 schema,如图9的下面部分所示。当你使用新的CREATE USER DDL创建一个新的用户Alice,SQL Server不再自动地创建具有相同名称的schema。相反地,你必须显式创建一个schema并将它的所有权分配给一个用户。因为显示的所有数据库对象现在包含在Schema1 schema中,这是Alice一开始拥有的,因此通过简单地更改schema的所有权给Lucinda来更改所有的schema对象的所有权就很简单了。每一个用户还可以拥有一个分配给它的默认的schema,因此SQL Server假定在默认的schema中,所有对象按名称引用而没有按schema引用。在图9的下面部分,如果Alice将Schema1作为她的默认schema,那么她可以将这个表作为Schema1.Table1或简单地作为Table1。用户Carol可能没有一个默认的与她的用户名关联的schema,她需要将这个表作为Schema1.Table1。任何没有定义默认schema的用户默认的schema是dbo。在SQL Server 2008中完全标准的对象名称具有一个四部分组成的结构,这与SQL Server之前版本中的类似:

  server.database.schema.object

  如同在之前版本中的一样,如果对象是在代码运行的同一台服务器上那么你可以省略服务器名称。如果连接打开了同一个数据库那么你可以忽略数据库名称。而如果它是当前用户默认的schema或者是dbo所拥有的,那么你可以忽略schema 名称,因为那是当SQL Server 试图消除一个对象名称的歧义时采取的最后手段的schema。

  使用CREATE USER 语句替代sp_adduser 来创建新的用户。这个系统存储过程仍然围绕向后的兼容性,并已被修改了一点来适应新的用户和schemas的分离。sp_adduser 创建了一个schema,它使用相同的名称作为新的用户名称或应用程序角色,并指定这个schema 作为用户默认的schema,模仿SQL Server 2000行动但提供了一个单独的schema。

  注意 在使用ALTER AUTHORIZATION 语句时,它可能会导致你拥有一个在我的中的表(反之亦然)。这会导致严重的问题。例如,谁拥有这个表上的触发器,你还是我?底线是它现在能够巧妙地发现schema范围的对象或类型的所有者。这有两个方法:

  · 使用OBJECTPROPERTY(id, 'OwnerId')来发现一个对象的真正所有者。

  · 使用TYPEPROPERTY(type,'OwnerId')来发现一个类型的真正所有者。

  SQL Server 可以使用同义字来帮助保存按键。你可以为任何使用两部分、三部分或四部分完整对象名称的对象创建一个同义字。SQL Server 使用同义字来访问定义的对象,在下面的代码中,History 同义字显示了AdventureWorks数据库中指定的schema.table。SELECT 语句返回了EmployeeDepartmentHistory表的内容。

以下是引用片段:
  USE AdventureWorks
  GO
  CREATE SYNONYM History FOR HumanResources.EmployeeDepartmentHistory
  SELECT * FROM History

  你还可以为完整的四部分名称定义History 同义字,如下面的代码所示:

以下是引用片段:
  CREATE SYNONYM History
  FOR MyServer.AdventureWorks.HumanResources.EmployeeDepartmentHistory

  使用像这样的完整的四部分名称允许使用从另一个数据库上下文得到的同义字,假设当前的用户具有使用这个同义字和读取表的权限:

以下是引用片段:
  USE pubs
  SELECT * FROM AdventureWorks..History

  还要注意,如果你不提供一个schema名称作为新的同义字名称的一部分,那它将成为默认schema 的一部分。

  5. 加密和密钥管理

  服务器级别的安全可能是系统管理员最为关注的,但是数据库是一个生产环境中所有活动发生的地方。对于大多数情况,数据库管理员可以让数据库开发人员关注于数据库的细节,只要开发人员是在环境的约束之下。SQL Server 2008提供了大量的特性用于保护数据库。

  5.1 数据加密

  SQL Server 2000 和之前的版本没有对数据库中存储的数据进行加密的内置支持。为什么你需要对安全地放置在防火墙之后的很安全的服务器上存储在很安全的数据库中的数据进行加密?这是因为有一个出现了几年的重要的安全原则——defense in depth。Defense in depth意味着分层防范,以便即使攻击者突破了你最外层的防御,他们还是需要再通过层层防御才能抵达中心。在一个数据库中,这意味着如果一个攻击者通过了防火墙和服务器上的Windows安全后抵达了数据库,她还是需要作些工作来试图解析你的数据。而且,在数据和隐私受到法律保护的今天,数据需要进行强有力的保护。

  SQL Server 2008使用对称和非对称密钥以及数字证书提供了对广泛的数据加密种类的大力支持。最重要的是,它为你管理密钥,因为到目前为止,密钥管理是最难加密的部分。保密秘密绝非易事。

  作为一个管理员,你可能至少要管理密钥层级的上层,如图10所示。数据库管理员需要了解服务器级别的服务主密钥和数据库级别的数据库主密钥。每一个密钥保护它的子密钥,而这些子密钥反过来保护它们自己的子密钥,这样在树型结构中传递下去。一个例外就是当一个密码是保护一个同义字密钥或证书的时候,这是SQL Server 让用户管理他们自己的密钥和保证密钥的隐密性的方式。

  图 10SQL Server 2008中的加密密钥层次

  注意 Microsoft建议不要直接使用证书或非对称密钥来加密数据。非对称密钥加密会将性能降低很多倍,而且你使用这个机制所能保护的数据量是受限的,它取决于密钥模块。你可以使用一个密码而不是数据库主密钥来保护证书和非对称密钥。

  服务主密钥是一个管理SQL Server 中所有密钥和证书的密钥。它是SQL Server在安装过程中自动创建的一个同义字密钥。它显然是一个重要的秘密,因为它被知道了的话,那么攻击者就可以解析SQL Server管理的服务器上的每一个密钥。Windows中的数据保护API(Data Protection API ,DPAPI)会保护服务主密钥。

  SQL Server为你管理服务主密钥,不过你可以在它上面执行维护任务将它输入到一个文件中,重新生成它,并从一个文件将它恢复回来。然而,大多数情况下你不需要或不想要对密钥做任何修改。对于管理员来说,最好备份他们的服务主密钥,以防密钥崩溃。

  在数据库范围内,数据库主密钥是所有密钥、证书和数据库中的数据的根加密对象。每一个数据库可以有一个单独的主密钥;你如果试图创建第二个密钥那你会得到一个错误信息。你必须使用CREATE MASTER KEY Transact-SQL以用户提供的密码来创建一个数据库主密钥: 

以下是引用片段:
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'EOhnDGS6!7JKv'

  SQL Server 使用从密码和服务主密钥获得的一个三重数据加密标准密钥来加密密钥。第一个拷贝存储在数据库中,第二个拷贝存储在主数据库中。让数据库主密钥由服务主密钥来保护,这使得当需要的时候SQL Server可以自动地解密数据库主密钥。终端应用程序或用户不必使用密码打开主密钥,而且这是将密钥保护于层次之中的一个主要的好处。

  分离数据库和一个现有的主密钥,并将它移到另一个服务器上,这是一个棘手的事。问题在于新的服务器的服务主密钥和其它的服务器的服务主密钥是不同的。因此,服务器不能自动地解析数据库主密钥。通过使用加密所采用的密码来打开数据库主密钥并使用ALTER MASTER KEY 语句和新的服务主密钥将它加密,这样可以解决这个问题。否则,你总是需要在使用前打开数据库主密钥。

  一旦有了数据库主密钥,开发人员就可以使用它来创建三种密钥类型中的任何一个,这取决于所要求的加密类型:

  · 非对称密钥,用于具有一个公共密钥和一个私人密钥对的公共密码匙

  · 对称密钥,用于使用相同的密钥进行加密和解密数据的共享秘密的情况下

  · 证书,实质上是一个公共密钥的封装

  有了这所有的加密选项以及它和服务器以及数据库的深入集成,现在加密已经是一个为你的数据添加最后一道防线的可行方法。但是,要明智地使用这个工具,因为加密会对你的服务器增加许多处理消耗。

  透明的数据加密

  在SQL Server 2005中,你可以通过编写使用数据库引擎的加密功能的定制Transact-SQL来加密数据库中的数据。SQL Server 2008在这基础上推出了透明数据加密。

  透明数据加密执行所有的数据库级别的加密操作,这消除了应用程序开发人员创建定制的代码来加密和解密数据的要求。数据在写到磁盘时进行加密,从磁盘读的时候解密。通过使用SQL Server来透明地管理加密和解密,你可以保护数据库中的业务数据而不必对现有的应用程序做任何修改,如图11所示。

  图 11:透明数据加密

  数据库加密密钥(DEK)是用来执行加密和解密的,这个DEK存储在数据库启动记录中,在恢复场景中可用。你可以使用服务主密钥或硬件安全模块(HSM)来保护这个DEK。HSM通常是USB设备或智能卡,因此不容易被偷或丢失。

  5.2 可扩展的密钥管理

  随着调整遵从性和对数据保密性的整个关注的不断发展,越来越多的公司使用加密作为一种提供深度防范的解决方案。随着公司使用越来越多的加密和密钥来保护他们的数据,密钥管理变得越来越复杂。一些高安全性的数据库使用上千个密钥,而你必须使用一个系统来存储、释放或重建这些密钥。更进一步的,你应该将这些密钥与数据分开存储,以提高安全性。

  SQL Server 2008推出了供第三方供应商使用的加密功能。这些解决方案与SQL Server 2005 和SQL Server 2008数据库无缝地合作使用,提供了企业级的专一的密钥管理。这将密钥管理工作从SQL Server移到了专一的密钥管理系统。

  SQL Server 2008中的可扩展的密钥管理还支持HSM的使用,从而提供了密钥和数据物理上的分离。

  5.3 代码模块签名

  在SQL Server 中进行加密的一个好处是它提供了使用证书数字化签名代码模块的功能(存储过程、函数、触发器和事件通知)。这提供了对数据库表和其它对象的访问的更细粒度的控制。像加密数据一样,你使用证书中所包含的私钥来签名代码。结果在签名的代码模块中使用的表只能通过代码来访问,而不允许从代码模块的外部访问到。换句话说,只有使用用来签名这个模块的证书才能访问到这些表。

  对于存储过程情况是一样的。例如,如果它有一个没有被破坏的所有权链,你谨慎地控制哪些用户具有对这个存储过程的EXECUTE 权限,而且你直接拒绝对后台的表的访问。但是这在一些情况下不起作用,例如当这个存储过程的所有权链被破坏了或者执行动态的SQL,要求这个用户执行存储过程具有对后台的表的权限。要实现同样目的的另一个方法是使用EXECUTE AS ,但是这会改变存储过程执行环境的安全上下文。这可能是不希望的,例如,如果你需要在表中记录哪个用户使得这个存储过程运行(需要记录作为这个存储过程参数的用户名称)。

  签名代码模块还具有保护证书免于对代码模块的未授权的改动的好处。像其它数字签名的文档一样,当代码改变时证书就无效了。代码不在证书的上下文下执行,所以任何具有对该证书的访问权限的对象将不能被访问到。

  为了做到这一点,你可以创建一个证书,将它和一个新的用户关联起来,并使用这个证书来签名这个存储过程。为这个用户授权所有执行这个存储过程所必要的权限。实际上,你将这个用户添加到了这个存储过程的安全上下文中作为第二标识。然后将执行权限授予所有需要执行这个存储过程的用户和角色。下面的代码显示了这些步骤。假设你想签名mySchema.GetSecretStuff 存储过程,而所有引用的对象都已经存在于数据库中了:

以下是引用片段:

CREATE CERTIFICATE certCodeSigning
 ENCRYPTION BY PASSWORD = 'cJI%V4!axnJXfLC'
 WITH SUBJECT = 'Code signing certificate'
GO

-- Sign the stored procedure
ADD SIGNATURE TO mySchema.GetSecretStuff BY CERTIFICATE certCodeSigning
 WITH PASSWORD = 'cJI%V4!axnJXfLC'
GO

-- Map a user to the certificate
CREATE USER certUser FOR CERTIFICATE certCodeSigning
GO

--Assign SELECT permissions to new certUser
GRANT SELECT ON SocialSecurity TO certUser
GO

-- Grant execute permission to the user who will run the code
GRANT EXECUTE ON mySchema.GetSecretStuff TO ProcedureUser
GO

 

  现在只有明确地被授予在存储过程上的EXECUTE权限的用户可以访问这个表的数据。

  6. SQL Server 2008中的审查

  任何安全解决方案的一个重要部分是具有审查责任和调整遵从性原因的活动的能力。SQL Server 2008具有一些使它可以审查活动的特性。

  6.1 所有活动审查

  SQL Server 2008具有通过审查对象对审查的支持,这使得管理员可以捕捉数据库服务器中的活动并将它存储在日志中。有了SQL Server 2008,你可以将审查信息存储在以下目的地中:

  · 文件

  · Windows应用程序日志

  · Windows安全日志

  为了写到Windows安全日志中去,SQL Server 安全必须被配置为作为本地系统、本地服务、网络服务或一个具有SeAuditPrivilege权限但不是交互的用户的域帐户来运行。

  为了创建一个审查对象,你必须使用CREATE SERVER AUDIT语句。这个语句定义了一个审查对象,并将它与一个目的地相关联。这个特定的选项习惯于配置一个依赖于审查目的地的审查对象。例如,下面的Transact-SQL代码创建了两个审查对象;一个记录活动到一个文件中,另一个记录活动到Windows应用程序日志中:

以下是引用片段:
  CREATE SERVER AUDIT HIPAA_File_Audit
  TO FILE ( FILEPATH=’\\SQLPROD_1\Audit\’ );
  CREATE SERVER AUDIT HIPAA_AppLog_Audit
  TO APPLICATION_LOG
  WITH ( QUEUE_DELAY = 500, ON_FAILURE = SHUTDOWN);

  注意在记录到一个文件目的地中时,文件名称没有在CREATE SERVER AUDIT语句中指定。审查文件名称采用AuditName_AuditGUID_nn_TS.sqlaudit 的形式,其中AuditName 是审查对象的名称,AuditGUID是与审查对象关联的唯一标识符,nn是用于分割文件组的分区编码,而TS是一个timestamp类型的值。例如,通过之前的代码示例创建了HIPAA_FILE_Audit审查对象,它可以产生一个日志文件,其名称与下面的类似:

  HIPAA_File_Audit_{95A481F8-DEF3-40ad-B3C6-126B68257223}_00_29384.sqlaudit

  你可以使用QUEUE_DELAY 审查选项为性能原因执行异步的审查,而ON_FAILURE选项决定当审查信息不能写到目的地时所要采取的行动。在之前的HIPAA_AppLog_Audit示例中所显示的,ON_FAILURE选项配置为当日志不能写的时候关闭SQL Server示例;在这种情况下,执行CREATE SERVER AUDIT语句的用户必须具有SHUTDOWN权限。

  在你创建了一个审查对象时,你可以使用CREATE SERVER AUDIT SPECIFICATION和CREATE DATABASE AUDIT SPECIFICATION语句为它添加事件。CREATE SERVER AUDIT SPECIFICATION 添加服务器级别的行动组(在服务器级别会发生的相关行动的预定义集合)到一个审查中去。例如,下面的代码添加了FAILED_LOGIN_GROUP 行动组(它记录了失败的登陆尝试)到HIPAA_File_Audit审查中去。

以下是引用片段:
  CREATE SERVER AUDIT SPECIFICATION Failed_Login_Spec
  FOR SERVER AUDIT HIPAA_File_Audit
  ADD (FAILED_LOGIN_GROUP);

  CREATE DATABASE AUDIT SPECIFICATION语句添加数据库级别的行动组和将单个的数据库事件添加到一个审查中去。添加单独的行动使得你可以过滤基于这个活动涉及的对象和用户来记录的行动。例如,下面的代码示例添加了DATABASE_OBJECT_CHANGE_GROUP行动组(它记录数据库中的任何CREATE、ALTER或DROP操作)和将用户SalesUser或 SalesAdmin在Sales schema中对对象执行的任何INSERT, UPDATE, or DELETE语句添加到HIPAA_AppLog_Audit审查中去。

以下是引用片段:
  CREATE DATABASE AUDIT SPECIFICATION Sales_Audit_Spec
  FOR SERVER AUDIT HIPAA_AppLog_Audit
  ADD (DATABASE_OBJECT_CHANGE_GROUP),
  ADD (INSERT, UPDATE, DELETE
  ON Schema::Sales
  BY SalesUser, SalesAdmin);

  审查对象提供了一个可管理的审查框架,它使得定义应该被记录的事件和日志应该存储的位置变得很容易。这个对SQL Server 的补充帮助你执行一个完全的审查解决方案来保护你的数据库和满足调整遵从性要求。

  6.2 DDL触发器

  DDL触发器是在SQL Server 2005中推出的,不像表中的数据改变时所执行的Transact-SQL代码的DML触发器,一个DDL触发器是在表的结构改变时才触发。这是一个很好的跟踪和审查对数据库schema的结构化改变的方法。

  这些触发器的句法类似于DML触发器的语法。DDL触发器是AFTER 触发器,它对DDL语言事件作出响应;它们不对执行DDL等的类似操作的系统存储过程作出响应。它们完全是事务型的,所以你可以回滚一个DDL操作。你可以在一个DDL触发器中运行Transact-SQL或CLR 代码。DDL触发器还类似于其它的模块一样支持EXECUTE AS 条件语句。

  SQL Server 提供了关于触发器事件作为非强类型的XML的信息。它可以通过一个叫做EVENTDATA()的新的输出XML的内置功能来实现。你可以使用XQuery表达式来解析EVENTDATA() XML ,以便能够发现像schema名称、目标对象名称、用户名称还有触发触发器的整个Transact-SQL DDL语句等的事件属性。

  数据库级别的DDL触发器触发于数据库级别和之下的DDL语言事件。例如CREATE_TABLE、ALTER_USER 等等。服务器级别的DDL触发器触发于服务器级别的DDL语言事件,例如CREATE_DATABASE、ALTER_LOGIN等等。为了管理方便,你可以使用事件组,像DDL_TABLE_EVENTS作为所有CREATE_TABLE、ALTER_TABLE和DROP_TABLE事件的总的简称。这些广泛的DDL事件组和事件类型,以及它们所关联的XML EVENTDATA(),在SQL Server 在线书籍中有描述。

  和DML触发器的名称不一样,DML触发器的名称是schema 范围的,而DDL触发器名称是数据库范围的或服务器范围的。

  使用这个新的目录视图来找出用于DML触发器和数据库级别的DDL触发器的触发器元数据:

以下是引用片段:
  SELECT * FROM sys.triggers ;
  GO

  如果parent_class_desc 字段具有一个‘DATABASE’值,那么它是一个DDL触发器,并且名称是数据库本身范围内的。Transact-SQL 触发器的代码体在sys.sql_modules 目录视图中可以看到,你可以将它连接到sys.triggers 的object_id 字段上。关于一个CLR触发器的元数据可以在sys.assembly_modules 目录视图中看到,你可以将它连接到sys.triggers的object_id字段上。

  使用目录视图来找出服务器范围的DDL触发器的元数据:

以下是引用片段:
  SELECT * FROM sys.server_triggers ;
  GO

  Transact-SQL 服务器级别的触发器的代码体可以在sys.server_sql_modules 目录视图中看到,你可以将它连接到sys.server_triggers的object_id字段上。关于一个CLR服务器级别的触发器的元数据可以在sys.server_assembly_modules目录视图中找到,你可以将它连接到sys.server_triggers的object_id字段上。

  你可以使用DDL触发器来捕捉和审查数据库中的DDL活动。创建一个具有非强类型的XML字段的审查表。为DDL事件或你感兴趣的事件组创建一个EXECUTE AS SELF DDL 触发器。这个DDL触发器的代码体可以简单地将EVENTDATA() XML插入到审查表中。

  DDL触发器的另一个有趣的使用是触发于CREATE_USER 事件然后添加代码到自动权限管理中去。例如,假设你想让所有的数据库用户获得一个对存储过程P1、P2和P3的GRANT EXECUTE 权限。DDL触发器可以从EVENTDATA() XML中提取用户名称,动态地生成一个语句,像‘GRANT EXECUTE ON P1 TO someuser’,然后对它EXEC()。

  7. 总结

  SQL Server 2008提供了丰富的安全特性来保护数据和网络资源。它能够更容易地安全安装,因为除了最根本的特性之外,其它的都不是默认安装的或者是它们安装了但是是没有打开的。SQL Server提供了丰富的工具来配置服务器,特别是SQL Server Surface Area Configuration Tool,它的验证特性更强了,因为SQL Server与Windows验证更紧密地集成在一起,并保护脆弱的或是久远的密码。授予和控制一个用户通过验证之后可以做什么具有了更细粒度的权限、SQL Server Agent代理和执行上下文,从而变得更加灵活了。甚至是元数据都更加安全了,因为系统元数据视图只返回了关于该用户在某种形式下具有对其的权限的对象的信息。在数据库级别,当用户和schemas的分离使得管理用户变得更加容易的同时,加密提供了最后的一道安全防线。

  • 0
    点赞
  • 0
    评论
  • 1
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值