接上文http://blog.csdn.net/dba_huangzj/article/details/79030680实例级别安全性包含创建和管理登录名、凭证(credentials)和服务器角色。相对的安全主体在实例级别包含数据库、端点和AlwaysON Availability Groups。本文将讨论登录名、服务器角色和凭证。
Windows 身份验证:只勾选这个时,用户只能使用Windows本地账号或者域账号去连接SQL Server。SQL Server的账号与这个Windows账号关联,Windows主体的SID(security identifier)会存储在master库中。
混合身份验证:也称SQL Server和Windows 身份验证模式,见下图,在这种模式下,Windows身份验证依旧生效。同时可以创建SQL 登录名,这种登录名具有名字、密码和SID,并存储在master库中。我们最常用的莫过于sa。使用这种方式,用户可以不具有任何Windows权限,即可登录到SQL Server。
混合身份验证比Windows身份验证略微不安全,因为可以直接绕过Windows域的保护,只要直到账号密码即可直接登录,同时在数据库审计层面也不方便(假设所有人都用sa登录,出了问题很难查找谁做的)。所以最好使用Windows身份验证。在一些情况下,可以考虑使用混合身份验证:
USE master
GO
CREATE LOGIN [cartersecuresafe\Pete]
FROM WINDOWS
WITH DEFAULT_DATABASE=master, DEFAULT_LANGUAGE=British ;
GO
USE master
GO
CREATE LOGIN Danni
WITH PASSWORD='C0mplexPa$$w0rd',
DEFAULT_DATABASE=master, CHECK_EXPIRATION=OFF, CHECK_POLICY=ON ;
GO
USE AdventureWorks2016CTP3
GO
ALTER USER Danni WITH LOGIN = Danni ;
:CONNECT CARTERSECURESAFE\ProdInstance1
DECLARE @SQL NVARCHAR(MAX) ;
SET @SQL = (SELECT 'CREATE LOGIN '
+ name
+ ' WITH PASSWORD = ''C0mplexPassw0rd'', SID = 0x'
+ CONVERT(NVARCHAR(64), SID, 2)
FROM sys.sql_logins
WHERE Name = 'Danni') ;
:CONNECT CARTERSECURESAFE\DRInstance1
EXEC(@SQL) ;
不过这个方式会使得密码以明文形式存储,略微不安全,而且如果DBA不知道某个账号的密码,也无法进行。为此,可以使用sys.sql_logins视图中的password_hash列来脚本化登录名的密码。不过这里使用HASHBYTES()()函数来产生登陆名的hash值。如下脚本,这个脚本产生DDL命令用于把所有启用的SQL 登录名脚本化并对密码哈希化:
DECLARE @password NVARCHAR(MAX) = 'C0mplexPa$$w0rd' ;
DECLARE @salt VARBINARY(4) = CRYPT_GEN_RANDOM(4) ;
DECLARE @hash VARBINARY(1000) ;
DECLARE @SQL NVARCHAR(MAX) ;
SET @hash = (SELECT 0x0200 + @salt + HASHBYTES('SHA2_512', CAST(@password
AS VARBINARY(MAX)) + @salt)) ;
SET @SQL = (SELECT 'CREATE LOGIN '
+ Name
+ ' WITH PASSWORD = '
+ CONVERT(NVARCHAR(1000), @hash, 1)
+ ' HASHED, SID = 0x'
+ CONVERT(NVARCHAR(64), SID, 2)
FROM sys.sql_logins
WHERE is_disabled = 0
FOR XML PATH('')) ;
SELECT @SQL ;
这里使用最高级别算法SHA2_512来加密,代码中的CRYPT_GEN_RANDOM()函数,使用Windows CAPI来产生一个加密随机数,本机直接执行的结果如下:
角色 | 描述 |
sysadmin | 实例层面最高权限。 |
bulkadmin | 允许成员执行BULK INSERT命令,常用于执行ETL过程的服务账号。 |
dbcreator | 可以在实例中创建数据库,一旦创建辛苦,登录名自动成为数据库的拥有者(Onwer),并且可以对这个库进行任何操作。但不代表可以对其他现有非该登录创建的库有权限。 |
diskadmin | 允许成员可以在SQL Server中管理备份设备。 |
processadmin | 通过T-SQL或者SSMS来停止实例。也可以kill掉运行中的进程。 |
public | 所有登录都默认添加到public角色。不可去除。 |
securityadmin | 成员可以管理实例级别的登录名,比如可以把登录名添加到除sysadmin外的服务器角色,或者对实例级别资源如端点授权。但是不能对数据库层面的用户进行授权。 |
serveradmin | 包含了diskadmin和processadmin角色,外加启动和停止实例,但是成员如果使用SHUTDOWN T-SQL命令,也能关闭服务(注意关闭跟停止,如果使用NOWAIT选项,则关闭时不需要运行CHECKPOINT),同时成员还可以修改端点和查看所有实例元数据。 |
setupadmin | 其成员可以创建和管理linked server(链接服务器) |
CREATE SERVER ROLE AVAILABILITYROLE AUTHORIZATION [CarterSecureSafe\
SQLAdmin] ;
GO
GRANT ALTER ANY AVAILABILITYROLE GROUP TO AVAILABILITYROLE ;
GRANT ALTER ANY ENDPOINT TO AVAILABILITYROLE ;
GRANT CREATE AVAILABILITYROLE GROUP TO AVAILABILITYROLE ;
GRANT CREATE ENDPOINT TO AVAILABILITYROLE ;
GO
然后添加Danni这个登录名到AvailabilityRole角色中:
ALTER SERVER ROLE AvailabilityRole ADD MEMBER Danni ;
GO
CREATE CREDENTIAL URLBackupCredential
WITH IDENTITY = 'CarterSecureSafeStorageAcc'
,SECRET ='\Ydfg\SGdTgJNpVFl992sBv7Bp1gyL61I33wNrTMHGBDdtVcx97F5f6SC5uDi59FeY2/IjxyqsuLU2xrkrNAGT==' ;
创建一个凭证用于备份到Azure中,使用的存储账号叫“CarterSecureSafeStorageAcc”。