引言
配置对SQL Server的功能和数据的访问是每个数据库管理员工作的重要部分,必须谨慎对待。过多地访问资源的后果可能意味着信息丢失或受损。必须加强管理那些可以合法地访问服务器的人员的许可权限。采取的恰当的措施,即可有效地防护那些负责数据登记或表格修改的人员,使保障SQL Server资源安全的工作更加轻松。在配置SQL Server的安全性时,需要牢记两个重要的目标,一是需要保护数据的完整性,二是需要防止对这些数据的非授权访问。这一切都必须在不降低工作效率的前提下实现。
为完成此目标,我们将会把SQL Server分成四个不同的级别,由此我们可以控制许可和功能。这四个级别是服务器、数据库、模式、对象。每个级别都拥有其自己的特性和选择,笔者将在此文中讨论之。在探讨之前,我们先要保证理解SQL Server的一些基本安全概念。
访问SQL Server的传统方法是通过登录账户。这些账户可以是Windows登录或SQL登录。在SQL Server中的默认认证模式仅准许Windows登录,但是如果你切换到混合认证模式,这两种方法都是可用的。仅在必要时才能这样做,因为仅使用Windows认证会使系统更加安全。对于用户来说,这样也更方便,因为这样使用现有的域账户,并不要求提供额外的凭证。在使用非Kerberos认证的系统环境中,或者在用户访问数据库时并没有处于你的网络中时,可能会要求混合认证模式。
登录账户仅能使用户到达SQL Server的“前门”。为访问任何数据库,用户需要一个可以链接到登录账户的用户账户。可以将单个登录账户链接到每个数据库中的某个用户账户,从而使单个登录账户访问多个数据库。虽然没有必要,许多数据库管理员还是会使服务器的登录名与数据库的用户名使用相同的名称,以便于管理。数据库中的许可可以直接给一个用户账户或一组账户。SQL Server中的组意即角色。用户账户可隶属于许多角色,并具备所有这些角色的许可,正如Windows操作系统环境那样。

对资源的访问是由授权、拒绝或撤消许可实现的。授权许可非常简单,它准许用户对对象执行某种操作。下面的代码将把PERSON 模式中CONTACT表格的SELECT许可授予SQLLOGIN1账户。这个语句中的“WITH GRANT OPTION”参数准许SQLLOGIN2将这种许可给予数据库中的其它用户。可以通过撤消或拒绝许可而移除之。撤消一个用户对某个角色的许可将会影响到他们所隶属的另外一个角色的许可。因而,在撤消了某用户对某个角色的许可后,他仍可能拥有执行某种操作的许可。拒绝许可会覆盖与之相冲突的任何已经分配的许可。拒绝许可通常用于大型环境中,以确保一个用户不能执行某种操作,即使其隶属于给与它们这些许可的另外一个角色。
/** CREATE TWO SQL LOGIN ACCOUNTS & TWO USER ACCOUNTS IN THE ADVENTUREWORKS
DATABASE **/
USE Master
Go
Create Login SQLLogin1 WITH PASSWORD=’Pa$$w0rd’, DEFAULT_
DATABASE=AdventureWorks
Go
Create Login SQLLogin2 WITH PASSWORD=’Pa$$w0rd’, DEFAULT_
DATABASE=AdventureWorks
Go
USE AdventureWorks
Go
CREATE USER SQLLogin1 FOR LOGIN SQLLogin1
Go
CREATE USER SQLLogin2 FOR LOGIN SQLLogin2
Go
/** Grant the SELECT permission on the CONTACT table to SQLLogin1
& SQLLogin2.
Allow SQLLogin2 to delegate the SELECT permission on CONTACT to
other users. **/
GRANT SELECT ON PERSON.CONTACT TO SQLLOGIN1
Go
GRANT SELECT ON PERSON.CONTACT TO SQLLOGIN2
WITH GRANT OPTION
GO
了解分配和控制许可的方式将更容易地理解此文所提供的建议。下面重点看一看每一个级别的安全,从服务器级别开始,直到数据库对象。
服务器安全
Windows登录账户可被映射为单独一个用户账户或一个用户组。在为大量用户分配了同样的特权时,便更容易通过组来管理用户的访问,因为仅需要分配或改变一次许可。你仍可以使用Activity Monitor或SQL Profiler等工具来记录某个用户做了什么。有可能出现某个组并不完全满足你的需要的情况。例如,一个拥有50个秘书的组,其中只有47个秘书需要访问SQL Server,这便会带来一个小问题。可以通过创建四个登录账户来轻松地解决:一个账户用于秘书组,三个账户用于不应当访问的用户。秘书组被授予许可,但用于用户的三个登录账户将被拒绝。即使他们是这个组的成员,明确拒绝许可也优先处理。这样做也许有些麻烦,但是如果改变组的成员资格不可行时,这将是最佳选择。
如果你决定使用SQL登录账户,需要记住的一个重要不同点是是其认证是由SQL Server处理的。口令及口令策略是由数据库管理员控制的。问题是并没有什么内在机制可以完成工作。SQL Server 2000及更早的版本都不能强迫用户使用强口令或改变这些口令。然而,从SQL Server 2005开始,在操作系统上建立的口令策略能够在SQL登录账户上得以强化。口令的长度、改变的频率及复杂性规则如今都可以轻松地强化。没有必要对所有账户进行强化,但是,却可对特定登录进行强化。许多环境习惯于SQL Server登录的不严格的口令规则观念,但是这确实并不是一个很好的安全方法。
被称为“sa”的内置SQL登录账户默认情况下是被禁用的,有时被人们忽略,特别是在服务器仅使用Windows认证时。即使没有数据库管理员的知识和经验,注册表的修改也可以改变服务器的认证模式,因而应当给这个账户分配一个强口令。

服务器角色准许你将预分配的许可指定给用户或组。例如,dbcreator的成员,能够创建新数据库,而securityadmin角色准许其成员管理登录账户。如果读者需要关于特定服务角色的信息,可以使用联机图书或sp_srvrolepermission过程(例如,EXEC SP_SRVROLEPERMISSION BULKADMIN)。知道这一点很重要,因为你无法改变这些角色,也无法添加新的角色。因而,这些角色被称固定服务器角色。拥有某个服务器角色的成员资格的任何账户都会自动地拥有许可,以将其它账户添加到同样的组中。所有账户都会自动地成为一个被称为“public”特别服务器角色的成员,这些登录账户不能从这个服务器角色中移除。这个角色仅能用于将许可分配给每个登录账户所拥有的资源。其使用方式与Windows的“Authenticated Users(经过身份验证的用户)”组相同。
在某些自动工作(如备份)中执行某些操作的人员可能并不需要将特权用于其日常的职责。充分利用代理账户可以解决这种问题。这些账户可以得到完成某种工作的许可,然后用户们被准许进行其工作而不是使用其自己的账户。在所有情况下,务必使用“最少特权”原则,这些账户仅能拥有适合于特定需要的许可。有些管理员图省事,使用了SQL Server代理账户进行工作,但是由于代理账户通常都有特权提升,所以这并非是一个很好的安全方法,除非做这项操作的人员是数据库管理员。
可能引起安全问题的另外两个设置是网络协议的配置和启用高级特性。多数网络连接将使用TCP/IP或Named/Pipes,而不是两者同时使用,所以应当在SQL Server配置管理器中禁用未用的协议。禁用SQL Server Browser服务并改变默认的1433端口将使窃贼发现服务器更为困难。Surface Area Configuration(外围应用配置器)工具将启用或禁用某些最常见的特性,这些特性通常会引起服务器的安全问题。在SQL Server 2005及更高的版本中,有些扩展过程,如xp_cmdshell、特别(ad hoc)连接及CLR integration默认都是禁用的。除非需要将这些选项用于服务器的功能,否则就不要重新启用这些选项。对于偶尔使用的工具,管理员可能会决定在使用完毕后立即禁用之,并使用恰当的日志工具来记录其使用。
数据库安全
如果不将用户账户分配给登录账户,它们就无法在数据库中发挥作用。如果有人试图这样做,SQL Serve将首先检查被称为“guest”的特定用户账户是否被禁用。如果是这样,登录账户将被映射到此账户。所有的数据库都有临时账户,但是默认情况下它是被禁用的,除非管理员启用这个账户。
正如存在着固定的服务器角色一样,还存在着固定的数据库角色,如db_backupoperator。但有一点与服务器不一样,你可以在数据库级别创建角色,从而可以分配固定角色没有涉及的特定许可级别。公共数据库角色的运行方式与服务器级别的公共角色的运行方式相同。
在需要对数据库的资源访问进行更强大的控制时,有些管理员不再使用登录账户和用户账户,而主要使用应用程序角色。应用程序角色是数据库中的特定用户账户,它可以提供对数据库的直接访问而不必登录账户。在用于访问数据库时,应用程序账户将忽略用户可能拥有的任何其它特权,并强迫用户只使用分配给应用程序的许可。任何人都无法将这些特权与来自另外一个账户的许可结合起来绕过安全限制。另外一个安全利益是当终端用户在SQL Server上工作时,可被强迫使用特定的应用程序。一旦有人拥有其自己的登录和用户账户,这些人就可以使用Excel、Access或免费下载的应用程序来连接到服务器上的数据库。如果一个应用程序用一个用户无法看到的应用程序角色和口令进行了预先配置,用户将只能使用这个程序连接到数据库。这种级别的控制使得强化数据如何被访问和修改的规则更为简单。SP_SETAPPROLE这个存储过程使用应用程序角色连接到数据库,它有一个加密选项,有些人误认为口令在网络上是受到保护的。如果有必要对通过网络传输的应用程序角色的口令进行加密,就应当使用SQL Server所支持的其它网络加密选择,如IPSec或SSL。

/** CREATE AND TEST A DATABASE APPLICATION ROLE **/
USE AdventureWorks
GO
CREATE APPLICATION ROLE AccountingApp1 WITH PASSWORD = ‘Pa$$w0rd’
GO
DECLARE @cookie varbinary(8000);
EXEC SP_SETAPPROLE ‘AccountingApp1’,’Pa$$w0rd’,
@fCreateCookie = true, @cookie = @cookie OUTPUT;
SELECT USER_NAME()
EXEC SP_UNSETAPPROLE @cookie
SELECT USER_NAME()
GO
有些数据库选项利用DDL触发器来防止因意外删除对象而导致的问题。许多数据库管理员使用这些触发器自动记录对数据库某些类型的改变,例如,表的删除和修改。这些触发器还可轻易地用于防止这种改变。在删除数据库或其中的对象时,有些公司的策略要求遵循特定的过程。为了防止有人意外删除某个表格(即使他们拥有这种许可),也可以创建一个恢复这种改变的触发器。只有那些了解触发器并拥有禁用触发器许可的用户才能删除数据库中的表。然而,在以这种方式使用触发器管理数据库时,要记住,所有的触发器都自动地成为启动触发器transaction的一个扩展,触发器只对有日志记录的操作做出响应。
/** CREATE AND TEST A DATABASE TRIGGER THAT PREVENTS TABLE DELETION**/
CREATE TRIGGER [DELETETABLE]
ON DATABASE
FOR DROP_TABLE
AS
ROLLBACK;
GO
DISABLE TRIGGER [DELETETABLE] ON DATABASE
GO
ENABLE TRIGGER [DELETETABLE] ON DATABASE
GO
模式安全
模式是在SQL Server 2005中引入的,它代表着一种在数据库中组织对象的方法。它充当了包含数据表、视图和其它对象的文件夹。可以在不同的模式中创建拥有同样名字的对象。数据库中的contact表可存在于PROD 模式中,如PROD.CONTACT,而同样名称的表的测试版本也可存在于DEV 模式中,如DEV.CONTACT。因为许可和所有权可被直接分配给模式,把访问权分配给多个对象要比以前的版本更为简单。你甚至可以在需要时在模式之间移动数据表。数据表将继承分配给它的新模式的许可。
/** CREATE A TABLE IN ONE 模式 AND THEN MOVE IT INTO ANOTHER
模式 **/
USE ADVENTUREWORKS
GO
SELECT CONTACTID, FIRSTNAME, LASTNAME
INTO DBO.CONTACT
FROM PERSON.CONTACT
GO
SELECT * FROM DBO.CONTACT
GO
CREATE 模式 DEV
GO
ALTER 模式 DEV
TRANSFER DBO.CONTACT
GO
SELECT * FROM DEV.CONTACT
GO
对象安全
最后的安全级别准许管理员将许可分配给你在数据库中所创建的对象,如:表、视图、过程或函数。在这种级别,数据库管理员可用许多方法保障数据安全。限制和触发器通常是实施数据完整性要求并强化业务规则的常见方法。还有许多方法,可使用EncryptByKey()或 EncryptbyPassPhrase()函数来配置数据表中的加密。
多数情况下,对象级的安全将涉及将许可分配给表或表中的特定栏。在许多情况下,最好使用视图来处理。如果是数据表的话,视图可以是能够得到分配许可的存储查询。视图可以从一个表中显示特定的栏,或从多个表抽取数据。可以在不直接使用表的情况下将访问权分配给终端用户。这种机制准许管理员创建一种环境,在这里,用户和应用程序总是以同样的方式访问信息,而不管表结构如何被修改,没有必要直接暴露真实表的名称和位置。
触发器和存储过程可被用作更新表或视图的方法。可以用这些方法强化业务规则并控制更新。在与EXECUTE AS子句连用时,存储过程可以为一个用户执行此用户并不直接拥有许可的操作。
结论
在一台SQL Server实例上配置安全性时,有许多因素需要考虑。其中的有些因素容易被人们忽略。如果采用一种系统化的方法,并考虑了上文所探讨的所有四个级别,那么遗漏某个方面的可能性将大大降低。在任何实际的环境中都不可能真正存在完美无缺的安全性,但是只要考虑了上述的细节就可以接近最安全的目标。

文章如转载,请注明转载自:http://www.5iadmin.com/post/967.html