管理安全性之账号安全
大家从事数据库行业,或者是经常与数据库打交道都知道数据库的重要性,特点是企业级的数据库来说,数据库的安全是非常重要的。
今天咱们就SQL Server 2008的安全性进行一个交流,咱们的主要课题有:
SQL Server 2008的账号与架构
SQL Server 2008的数据加密
SQL Server 2008的服务器配置安全
咱们先看第一个账号与架构:
这是SQL Server中跟安全相关的比较重要的两个概念:
咱们先回顾一下SQL Server中的用户管理:
身份验证方式分为Windows验证和SQL Server验证:
如果我们希望某个用户能够访问数据库中的对象,就必须经过这么几个步骤:
1 新建登录 (windows/SQL Server)
2 新建用户
3 分配权限
SQL Server 2005/2008在账号安全性方面又有所提高:
最明显的地方就是多了一个账号密码策略:
账号密码策略:
账号锁定策略:
SQL Server 可以对在 SQL Server 内部使用的密码应用在 Windows Server 2003 中使用的相同复杂性策略和过期策略。此功能需要通过 NetValidatePasswordPolicy API 实现,该 API 只在 Windows Server 2003 和更高版本中提供。
演示:
实例1: 创建WINDOWS账号,这个账号的安全性是受OS控制的,不受SQL Server2005的控制。所以,如果OS对账号要求严格的话,那么WINDOWS验证就一定安全。我们在此主要看一下SQL Server验证,我们来看一个实例:
实例2:我们创建一个SQL Server用户 我们也看到了下面有强制实施密码策略,强制密码过期,用户在下次登录时必须更改密码:
1 强制实施密码策略 这个到底起什么作用?我们建一个用户试一下,我们输入一个简单密码,可以,我们知道密码策略中有一个最明显的就是复杂性密码,但好像不起作用呀,这是因为,如果要求用户必须使用复杂性密码,不仅这里要启用,关键是OS中还需要启用密码策略,也就是说这里的强制实施密码策略,是指强制实施OS的密码策略:
我们来 GPEDIT.MSC 开启OS的密码策略再来试一下:
我们使用复杂性密码,则OK,并且会受42天的一个限制,并且要求用户第一次登录时必须更改密码,并且要求这个密码一定是一个复杂性密码:就是从写100位光是一种字符也不行,必须是三种或以上的组合
用户在下次登录时必须更改密码什么场合使用:一般是你为客户设置服务器时,客户的密码不可能让你知道,所以你设置完以后要让用户在下次登录时重新设置密码:
而这些功能在2000的时候是没有的,
演示代码:
---创建WINDOWS登录
create login [dufei\dufei] from windows with default_database=master
--计算机名\用户名 必须使用 [ ] 不能是''
-- 创建 SQL Server 登录用户 满足要求
create login df
with password='DUfei2008',default_database=master
drop login df
-- 创建 SQL Server 登录用户 不满足要求
create login df with password='abcdefghijklmn',default_database=master
-- 创建 SQL Server 登录用户 加上相关选项
create login df with password='DUfei2008' must_change,
default_database=master,check_expiration=on,check_policy=on
must_change 下次登录是必须更改密码 check_expiration 过期设置 policy 密码复杂度是否够复杂
开发人员,需要留出一个用户留出一个接口,以防止密码过期后,不能使用,需要用户修改密码,否则就只能是管理员到数据库中手动修改。
开发人员只要去调用类即可:system.data.sqlclient.sqlconnection类 接口。
我不是做开发。大家可以自己去查一下。
大家看到现在为止,感觉到似乎很安全了,但是仍然需要预防有人恶意猜解密码,如有些黑客软件,会不停的枚举密码,还是有一些危险性。所以还要结合一个功能:
设置账号锁定:防止有人穷举我们的密码:
方法: 使用 WINDOWS的帐号锁定策略 ,但是如果合法用户被锁定了,如果解锁,则使用下面的语法
语法: alter login username with password='password' unlock
在这里你要使用合法的用户名和密码,以表明你是知道正确密码的。
可以防止恶意锁定,就是有些人说,你是够强,我猜不出来,那么我就给你锁定,我进不去,你也进不去。(同归于尽)那么我们管理员就可以通过这个语法来给合法用户解锁
我们来看一个实例:
实例: 设置账号锁定策略,如果3次无效登录,则锁定用户30分钟
方法:gpedit.msc
然后使用某个用户,非法登录三次后,出现:
此次使用管理员进行SQL :
alter login dufei with password='Ccjsj1200' unlock
你是需要知道这个SQL用户的密码的。
这个操作我们使用图形化也可以操作:在用户的属性中有一个状态:
在此,只能解锁,不能锁定,如果不希望别人登录,只能禁用!
在此我们介绍了在 SQL Server 2008中两个和用户相关的安全特性一个是密码策略,一个是锁定策略。
下面咱们看另一个和安全相关的概念:架构,这也是2005以后版本中所增强的地方,比密码策略更重要的地方,
架构:SCHEMA 这个概念是出于什么想法呢?在SQL早期版本中,我们对于一个对象的描述方法是使用“4点表示法”我们描述一个对象,如表,视图,触发器,存储过程等。一般是:
服务器 . 数据库 . 用户 . 对象 这样表示也很方便,
如 dufei.itet.dbo.yg 表明在dufei这个数据库中有一个itet数据库中有一个对象(表),所有者是dbo, 当然这个所有者可以不是DBO,可以是你指定的一个用户,如
Dufei.itet.lili.yg 那么就表明这个对象的所有者是lili,但是会有一个问题,就是如果用户被删除了,或者是用户离职了,一个新的员工来接替他,再重新创建一个新的用户名,这个权限交接很麻烦。所以在2000的时候很多应用程序都会使用DBO这个对象,但会将权限扩大化,因此在2005的时候引入了SCHEMA这个概念Schema 的概念与机制在 Oracle 里很早就有了,SQL 2005 算是顺应潮流吧:
注意:
1 架构定义与用户管理是分开的 ( 并没有从属的关系 )
2 在创建数据库用户时,可以指定该用户账号所属的默认架构。 ( 建议大家指定)
3 若不指定默认架构,则为DBO,为了向前兼容,早期版本中的对象迁移到新版本中,早期版本中没有架构的概念的。所以就该对象的架构名就是dbo.在SQL Server 2008中,DBO就是一个架构
4 当查找对象时,先找与用户默认架构相同的架构下的对象,找不到再找DBO的对象
第4点有点难理解,我们来看一张图,通过这张图,大家应该能很显示的理解这一点:
Bill 去查找orders时,是找不到的,因为没有指定orders的架构,用户本身也没有指定架构,所以就直接去到dbo中去查找,里面肯定没有,但同理,找products就可以找到
Ted去查找orders时,是能找到的,虽然没有指定orders的架构,但用户本身是sales架构,所以就到orders架构中去找orders,找到了,找procers时,虽然没有指定架构,会先去与用户本身架构相同的架构sales,没有找到,就再去找dbo架构,就OK了
也就是说 TED这个用户查询PRODUCTS时找了两回,第一回没找到,再找DBO,找到了!
下面咱们来看一下通过代码来实现对架构的操作:
Create schemas
Alter schemas
Drop schemas
USE MASTER
drop DATABASE dufei
create database dufei
命令对架构进行操作
use master
setuser
go
create login dufei with password='Ccjsj1200',default_database=dufei
create login xuhuili with password='Ccjsj1200',default_database=dufei
use dufei
go
create user dufei for login dufei
create user xuhuili for login xuhuili
-- 创建两个用户时没有指定属于哪个架构
create table yg1 (姓名 varchar(8),性别 char(2))
-- 这个表没指定属于哪个架构 属于默认 DBO 架构
go
create schema sch
create table sch.yg2(姓名 varchar(8),性别 char(2))
go
--这个表就属于sch架构
grant select on schema::sch to dufei
-- 赋予 dufei这个用户查询 sche架构中的对象的权限.
setuser 'dufei' --切换用户
select * from yg2
-- 此时报告 "对象名无效" 是因为没有指定yg2的架构,系统默认为dbo,而我们的yg2属于sch架构.
select * from sch.yg2
--可以了
setuser -- 切换到 sa
setuser 'xuhuili'
select * from sch.yg2
--不能查询,是因为没有权限
setuser --切换sa
alter user dufei with default_schema=sch
setuser 'dufei'
select * from yg2
-- 此时不需要指定 sch 也可以了,如果架构中还有其他对象,也可以查询
setuser
create table sch.yg3 (id int,uname varchar(8))
setuser 'dufei'
select * from yg3
insert into yg3 values (1,'aa') --拒绝了 insert权限
setuser
grant insert on schema::sch to dufei
setuser 'dufei'
insert into yg3 values (1,'aa') --OK!
Grant alter any schema to dufei 使dufei 这个用户对所有的架构都有可更改的能力。
Use master go
Grant control server to dufei 使dufei这个用户能够控制服务器。
-- 修改对象的架构 yg2表的架构由 sch 转移到sch1
setuser
create schema sch1
alter schema sch1 transfer sch.yg2
--创建用户时指定默认schema,默认属于DBO
create login yhy with password='Ccjsj1200',default_database=master
use dufei
create user yhy for login yhy with default_schema=sch --属于sch
setuser 'yhy'
select * from yg2
setuser
grant select on schema::sch1 to yhy
setuser 'yhy'
select * from yg2 ---还是无效,因为不在同一个schema
setuser
alter user yhy with default_schema=sch1 --更改yhy的架构
select * from yg2
--显示当前用户
select user
--win用户也可以使用 setuser 测试
setuser
drop user df
实例要求:windows用户可以创建表,并查看表中的数据
1 创建windows用户 df
2 创建登录 create login [dufei\df] from windows with default_database=master
3 向指定数据库添加用户 create user df for login [dufei\df] with default_schema=sch
4 分配权限 grant select on schema::sch to df
5 切换用户 setuser 'df'
6 查看当前用户 select user
6 测试权限:
select * from yg1 --不行,但不是‘对象名无效’,因为 yg1是DBO架构,但需要单独赋予用户访问此表的权限!
setuser
grant select on yg1 to df
setuser 'df'
select * from yg1
create table yg3 (id int) --拒绝
setuser
grant alter on schema::sch to df
grant create table to df
setuser 'df'
create table yg3 (id int)
insert into yg3 values (1) --拒绝了,继续分配权限即可!
显示对象所属架构
sp_helpuser df
sp_tables
显示已有架构
select * from sys.schemas
如何自定义标准角色:
角色这个概念和WINDOWS中的组是一样的,是权限相同的用户集合。
如果我希望有多个用户具有相同的权限,那么我可以创建一个角色,然后把用户加入到这个角色中,给这个角色分配一个权限即可,而不用一一分配。
系统中已经有一部分内置服务器角色和数据库角色,我们可以直接使用,但这些角色一般不适合于应用到普通用户身上,也就是说应该结合当前的实际需要,创建和使用自己的角色
在当前数据库中创建标准角色
sp_addrole sales
从当前数据库中删除角色
sp_droprole sales
往角色中增加成员
sp_addrolemember 角色名,成员名
返回有关当前数据库中某个角色的成员的信息
sp_helprolemember 角色名
从角色中删除用户
EXEC SP_DROPROLEMEMBER 角色名,用户名
EXEC SP_DROPROLEMEMBER ABC,DF
给角色分配权限
GRANT 权限 ON 表名 TO 角色名
收回权限
REVOKE 权限 ON 表名 FROM 角色名
删除角色
SP_DROPROLE ABC
-----------角色介绍---------------
setuser
1 在当前数据库中创建角色
sp_addrole sales
2 删除角色
sp_droprole sales
3 向角色中增加用户
sp_addrole sales
sp_addrolemember sales,df
sp_addrolemember sales,dufei
4 显示角色中的用户
sp_helprolemember sales
5 从角色中删除用户
sp_droprolemember sales,df
6 分配权限,与架构结合
grant select on schema::sch to sales
如:
create login rose with password='rose',default_database=master
create user rose for login rose
sp_helpuser 'rose'
setuser 'rose'
select * from sch.yg2 --拒绝了select
setuser
sp_addrolemember sales,rose
setuser 'rose'
select * from sch.yg2 --可以了
自定义应用程序角色:一旦拥有应用程序角色,就替代了原来的权限,必须重新登录
一旦启动了应用程序角色,用户现有的权限被关闭,应用程序角色的安全权限被相应打开。你的应用程序现在就可以使用应用程序角色来执行修改数据库的操作了
如创建一个应用程序角色“role2”密码“123456”,功能是仅仅显示员工表的内容!用户只要知道密码就可以成为此角色。
insert into 员工表 (编号,姓名,性别) values (9,'ss',22)
select * from 员工表
exec sp_setapprole 'nole2','123456'
insert into 员工表 (编号,姓名,性别) values (10,'ss',22)
在执行 SP_SETAPPROLE 之前是可以插入记录的。执行以后用户现在的权限被关闭,以应用程序角色的权限来操作数据库,只能查询没有插入权限了。
因为用户是登录是获得的应用程序权限,所以只要重新登录即可还原!