您的位置:首页 > 数据库

SQL Server 数据库帐号密码生成

2012-03-24 22:45 495 查看
一、背景

在某天晚上凌晨1点,我收到领导的通知:需要把我们所有的数据库的密码都需要进行一次修改,原因是我们放到Web服务器的配置文件config中明文了我们的数据库帐号和密码,而且这份配置文件可能泄露了,更糟糕的是我们的数据库是可以通过外网进行访问的。虽然有端口进行映射,但是我们的数据依然处在危险的状态,所以这个时候DBA需要争分夺秒修改数据库的帐号密码。

我们的数据库服务器大概有30台,而且每台机器上跑了很多个数据库。有创建数据库帐号经验的同学你会发现:使用SSMS进行创建帐号密码是件多么痛苦的事情,需要点击很多checkbox,特别是在创建一个可以访问整个数据库实例里的所有数据库的时候(虽然我们提倡每个数据库的帐号和密码都不一样,更严格的要求可能需要设置同一个数据库下需要有不同权限的帐号进行管理)

如果我们对数据库的帐号进行有效管理的话,我们可以很轻松的完成这个任务,只需要一条SQL就能管理了。在这里我提倡一种安全、易维护的方案给大家:SQL Server数据库帐号密码安全设计

二、设计概要

我们首先要明白我们出现的问题是什么:

1. 我们厌烦了一个个去点击checkbox;

2. 点击那么多次checkbox,我们不能确保所有的点击都是正确的;

所以我们第一步要想的就是有没什么办法可以解决上面这些问题?上面的这些操作SSMS是能让用户把操作保存为脚本的,我们可以自己编写SQL脚本来完成类似的工作。为了模拟SSMS上的操作,我们需要获取到数据库实例中所包含的所有数据库,再对每个数据库创建帐号和密码。我们可以通过游标的形式循环数据库,并创建帐号和密码。最后我们需要禁用掉sa这个帐号。

修改下面【通用SQL模板】的@user和@password的值,拷贝到下面的代码到SSMS中执行,这样就可以生成出适合本数据库实例的SQL脚本【生成的脚本代码】了,我们再拷贝生成的SQL代码到SSMS中执行就可以了。

执行下面的两个脚本不过秒级,所以20台服务器对你来说,简单啦。

三、通用SQL模板

--创建数据库帐号

DECLARE @dbname varchar(100)

DECLARE @user varchar(100)

DECLARE @password varchar(100)

DECLARE @sql varchar(max)

SET @user = 'UfranimdA_gz'

SET @password = 'o23#25R@8a8A!@23#@%'

SET @sql = '

USE [master]

GO

CREATE LOGIN ['+ @user + '] WITH PASSWORD=N'''+ @password +''', DEFAULT_DATABASE=[master], CHECK_EXPIRATION=OFF, CHECK_POLICY=ON

GO

EXEC master..sp_addsrvrolemember @loginame = N'''+@user+''', @rolename = N''sysadmin''

GO'

PRINT(@sql)

DECLARE @itemCur CURSOR

SET @itemCur = CURSOR FOR

SELECT name from sys.databases where state =0

OPEN @itemCur

FETCH NEXT FROM @itemCur INTO @dbname

WHILE @@FETCH_STATUS=0

BEGIN

SET @sql = '

USE ['+ @dbname + ']

GO

CREATE USER ['+@user+'] FOR LOGIN ['+@user+']

GO

USE ['+ @dbname + ']

GO

ALTER USER ['+@user+'] WITH DEFAULT_SCHEMA=[dbo]

GO

USE ['+ @dbname + ']

GO

EXEC sp_addrolemember N''db_owner'', N'''+@user+'''

GO'

PRINT(@sql)

FETCH NEXT FROM @itemCur INTO @dbname

END

CLOSE @itemCur

DEALLOCATE @itemCur

--禁用sa帐号

SET @sql = '

USE [master]

GO

ALTER LOGIN [sa] DISABLE

GO'

PRINT(@sql)

四、生成的脚本代码

--创建数据库帐号密码

USE [master]

GO

CREATE LOGIN [UfranimdA_gz] WITH PASSWORD=N'o23#25R@8a8A!@23#@%', DEFAULT_DATABASE=[master], CHECK_EXPIRATION=OFF, CHECK_POLICY=ON

GO

EXEC master..sp_addsrvrolemember @loginame = N'UfranimdA_gz', @rolename = N'sysadmin'

GO

USE [master]

GO

CREATE USER [UfranimdA_gz] FOR LOGIN [UfranimdA_gz]

GO

USE [master]

GO

ALTER USER [UfranimdA_gz] WITH DEFAULT_SCHEMA=[dbo]

GO

USE [master]

GO

EXEC sp_addrolemember N'db_owner', N'UfranimdA_gz'

GO

USE [tempdb]

GO

CREATE USER [UfranimdA_gz] FOR LOGIN [UfranimdA_gz]

GO

USE [tempdb]

GO

ALTER USER [UfranimdA_gz] WITH DEFAULT_SCHEMA=[dbo]

GO

USE [tempdb]

GO

EXEC sp_addrolemember N'db_owner', N'UfranimdA_gz'

GO

USE [model]

GO

CREATE USER [UfranimdA_gz] FOR LOGIN [UfranimdA_gz]

GO

USE [model]

GO

ALTER USER [UfranimdA_gz] WITH DEFAULT_SCHEMA=[dbo]

GO

USE [model]

GO

EXEC sp_addrolemember N'db_owner', N'UfranimdA_gz'

GO

USE [msdb]

GO

CREATE USER [UfranimdA_gz] FOR LOGIN [UfranimdA_gz]

GO

USE [msdb]

GO

ALTER USER [UfranimdA_gz] WITH DEFAULT_SCHEMA=[dbo]

GO

USE [msdb]

GO

EXEC sp_addrolemember N'db_owner', N'UfranimdA_gz'

GO

USE [DBA_DB]

GO

CREATE USER [UfranimdA_gz] FOR LOGIN [UfranimdA_gz]

GO

USE [DBA_DB]

GO

ALTER USER [UfranimdA_gz] WITH DEFAULT_SCHEMA=[dbo]

GO

USE [DBA_DB]

GO

EXEC sp_addrolemember N'db_owner', N'UfranimdA_gz'

GO

USE [TestDB]

GO

CREATE USER [UfranimdA_gz] FOR LOGIN [UfranimdA_gz]

GO

USE [TestDB]

GO

ALTER USER [UfranimdA_gz] WITH DEFAULT_SCHEMA=[dbo]

GO

USE [TestDB]

GO

EXEC sp_addrolemember N'db_owner', N'UfranimdA_gz'

GO

USE [master]

GO

ALTER LOGIN [sa] DISABLE

GO

五、特别说明

1. 这里生成的SQL脚本中包含了系统数据库:master、model、msdb、tempdb,为了方便我就没对这些数据库进行限制的,希望以后可以修正下这个脚本。

2. 这里再次推荐大家使用同一的数据库帐号密码的管理,无论是安全还是方便维护都是大有好处的。SQL Server数据库帐号密码安全设计,大家可以提些其它的想法。

SQL Server数据库帐号密码安全设计

一、背景

作为一个DBA,或许你有很多的系统需要管理,而且不同的系统使用了不同的数据库,通常的情况下,我们都是通过sa进行设置密码的,而且在config文件里面明文的写上我们的帐号和密码,这样的设计我们是否太大方了呢?

或许你会说,我们的数据库是安全的,因为我们的数据库是只有内网可以访问的,但是那台机器的安全性呢?因为能进入操作系统就能看到我们的帐号密码了。再加上有些时候我们不希望客户能看到数据库密码的。那么应该如何保证我们的数据库账号密码的安全性呢?

二、架构设计

针对上面的安全性问题,我设计了下面的方案,主要是运用加密算法进行加密,再通过分离一些职责,设置几道关卡,加强数据的安全性。

下面是这个方案的总体架构图:



(架构图)

三、架构解析说明

1. 程序1,程序2表示我们的应用程序,在程序的config中再也没有明文的数据库帐号和密码的了,它调用一个公用的webservice,只需要传入一个唯一的key值(有DBA发布这个key值),获取数据库IP、帐号、密码;

2. 网页接口调用程序是我们提供的一个webservice,它使用只读帐号视图,查询key值所对应加密后的数据库IP、帐号、密码;如下图所示:

[LinkName] 表示key值;

[En_LinkIP]表示程序需要链接的数据库IP地址;

[En_LinkSa]表示数据库使用的帐号;

[En_LinkPassword]表示数据库帐号所对应的密码;



(只读账号视图)

3. 把上图获取到的数据返回给网页接口调用程序,把这些值以|符号进行串联成一个字符串,再进行二次加密(使用不同的加密算法);再把加密后的字符串返回给程序1、程序2;

4. 当程序拿到这些加密后的字符串后,使用我们发布的DLL进行解密,这里的解密包括两个解密算法,把解密后的值返回给程序;

5. 那这些记录是怎么录入的呢?你猜对了,那就是DBA,DBA收集这些帐号和密码进行管理,只要开发人员告知数据库的相关信息(或许根本就不需要,因为部署是DBA的事情,或许开发人员根本就不需要知道这个数据库在哪里),我就使用单机机密程序,加密我们的数据库IP、帐号、密码,并生成唯一的key值,把这个key告诉开发人员。

把加密后的数据插入到数据库;超级管理员视图如下图所示:



(超级管理员视图)

四、特别说明

1. 就安全性考虑,LinkIP的值尽量能使用端口进行设置,修改默认的1433端口;

2. 虽然在程序中可以获取到明文的帐号密码,但是这比明文写在config上要安全很多倍了;

3. 对字符串进行二次加密是为了防止数据的拦截的;

4. 如果网页接口调用程序给爆掉了,拿到的数据还是加密后的数据;而且这个帐号是只读数据的,是没有insert、update、delete的权限的;

5. 有这个超级管理员帐号,这个帐号可以只有为数几个人知道,与网页接口调用程序的数据库帐号是完全分离的;

6. 程序中可能需要在使用帐号密码的时候需要捕获一下异常,就是当我们DBA修改了帐号密码后引起的链接异常;

7. 这个帐号表中,我们可以通过State字段进行控制这个帐号是否可用(甚至你可以直接删掉这条记录),这样当我们的业务系统泄漏了数据帐号的时候,我们可以很快速的修改帐号密码,不需要通知开发人员去修改config文件;

8. 只读账号视图现在只是简单的MD5加密,你完全可以设计自己算法;

9. LinkName是需要唯一的,所以在表设计的时候是使用了这个作为主键的;

10. 其实上面的设计我是为了体现出只读帐号视图和超级管理员视图的区别的;可以参考:SQL Server 2005控制用户权限访问表,其实你完全可以让网页接口调用程序调用数据库的config的帐号密码也进行一次加密,让程序去解密,这样只需要做一次就够了。

五、SQL代码

--创建表

CREATE TABLE [dbo].[LinkConfigTest](

[Id] [int] IDENTITY(1,1) NOT NULL,

[LinkName] [nvarchar](50) NOT NULL,

[LinkIP] [varchar](50) NULL,

[LinkSa] [varchar](50) NULL,

[LinkPassword] [varchar](50) NULL,

[Description] [nvarchar](100) NULL,

[State] [int] NULL CONSTRAINT [DF_LinkConfigT_State] DEFAULT ((0)),

[StateDescription] [nvarchar](50) NULL,

[HostName] [nvarchar](50) NULL,

[CreateTime] [datetime] NULL,

[En_LinkIP] [varchar](50) NULL,

[En_LinkSa] [varchar](50) NULL,

[En_LinkPassword] [varchar](50) NULL,

CONSTRAINT [PK_LinkConfigT] PRIMARY KEY NONCLUSTERED

(

[LinkName] ASC

)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

) ON [PRIMARY]

--插入测试数据

INSERT [LinkConfigTest]([LinkName],[LinkIP],[LinkSa],[LinkPassword],[Description],[State],[HostName],[CreateTime],[En_LinkIP],[En_LinkSa],[En_LinkPassword]) VALUES ('sd9_DB1','192.168.1.147,14339','sd158admin','sd158admin+-987','内网_DB1',1,'SERVR9','2012-3-7 14:08:52','0xddf4a1c5a5dadc7374a9ca3ed3aa9f6b','0xe319cb7bedd3b0d400c3da3484c6a6e3','0xdc24223e94b4c4d754cfc40230680156')

INSERT [LinkConfigTest]([LinkName],[LinkIP],[LinkSa],[LinkPassword],[Description],[State],[HostName],[CreateTime],[En_LinkIP],[En_LinkSa],[En_LinkPassword]) VALUES ('sc13','192.168.1.25,13433','sc13admin','sc13adminasdfg','内网_DB1',1,'BAREOT-4','2012-3-7 14:08:52','0x0f3e6234263b544bbb7861fc3be9d4a9','0xe969c53b6c44990ac38a92f1c6ad2d97','0xac7663644f8de76a3da122257a6593ea')

INSERT [LinkConfigTest]([LinkName],[LinkIP],[LinkSa],[LinkPassword],[Description],[State],[StateDescription],[HostName],[CreateTime],[En_LinkIP],[En_LinkSa],[En_LinkPassword]) VALUES ( 'sd9_DB2','192.168.1.147,14339','gd14admin','sc13admin#$','内网_DB2',0,'停用','SERVR9','2012-3-7 14:08:52','0xddf4a1c5a5dadc7374a9ca3ed3aa9f6b','0x8cfaec93141b6fb3fc5de4cef40c8648','0x99f2fb6b0f14d47fa725a79c62ae60c3')

INSERT [LinkConfigTest]([LinkName],[LinkIP],[LinkSa],[LinkPassword],[Description],[State],[HostName],[CreateTime],[En_LinkIP],[En_LinkSa],[En_LinkPassword]) VALUES ('jh16','192.168.1.30,16433','jh16admin','sc13admin$%as','内网_DB1',1,'SERVR16','2012-3-7 14:08:52','0x012f0e163b9f1d9624e56154e0159452','0x13c540aff4fe6d61f48de0e097fd1c66','0xb59032aaffddc07b72d9958359a5da97')

INSERT [LinkConfigTest]([LinkName],[LinkIP],[LinkSa],[LinkPassword],[Description],[State],[HostName],[CreateTime],[En_LinkIP],[En_LinkSa],[En_LinkPassword]) VALUES ('hb17','192.168.1.35,17433','hb17admin','sc13admin$%asdf','内网_DB5',1,'BAEF-1','2012-3-7 14:08:52','0x8723f377c50a33f3cb6794978be09895','0x4bce38f66dfba3f8779f070636a6a70d','0x8cab2ef5b6a6c5c48d499c5ef84c3436')

0.SQL Server

主要是数据库和程序的性能优化

SQL Server 数据库帐号密码生成
posted @ 2012-03-23 16:35 听风吹雨 阅读(1259) | 评论 (16) 编辑

SQL Server数据库帐号密码安全设计
posted @ 2012-03-07 17:20 听风吹雨 阅读(1180) | 评论 (3) 编辑

SQL Server 当表分区遇上唯一约束
posted @ 2012-02-23 18:58 听风吹雨 阅读(1124) | 评论 (3) 编辑

SQL Server 2005 性能优化实战系列(文章索引)
posted @ 2012-01-20 14:54 听风吹雨 阅读(1765) | 评论 (3) 编辑

SQL Server 批量创建、删除链接服务器
posted @ 2012-01-20 10:47 听风吹雨 阅读(1296) | 评论 (10) 编辑

SQL Server 置疑、可疑、正在恢复
posted @ 2011-12-19 20:59 听风吹雨 阅读(1251) | 评论 (4) 编辑

SQL Server 维护计划实现数据库备份
posted @ 2011-11-18 17:51 听风吹雨 阅读(1278) | 评论 (8) 编辑

SQL Server 维护计划备份主分区
posted @ 2011-10-09 11:52 听风吹雨 阅读(9612) | 评论 (2) 编辑

SQL Server 重复执行作业中某个步骤
posted @ 2011-09-14 14:58 听风吹雨 阅读(964) | 评论 (0) 编辑

SQL Server 设计开发系列(文章索引)
posted @ 2011-08-29 15:47 听风吹雨 阅读(2058) | 评论 (5) 编辑

SQL Server 自动化管理分区设计方案(图解)
posted @ 2011-07-21 14:49 听风吹雨 阅读(1384) | 评论 (8) 编辑

SQL Server 维护系列(文章索引)
posted @ 2011-07-15 14:52 听风吹雨 阅读(1503) | 评论 (2) 编辑

SQL Server 2005 控制用户权限访问表
posted @ 2011-07-14 18:11 听风吹雨 阅读(2766) | 评论 (8) 编辑

SQL Server 表分区实战系列(文章索引)
posted @ 2011-07-01 15:45 听风吹雨 阅读(2569) | 评论 (21) 编辑

SQL Server 备份和还原全攻略
posted @ 2011-06-29 17:03 听风吹雨 阅读(2211) | 评论 (17) 编辑

SQL Server 表分区注意事项
posted @ 2011-05-31 17:51 听风吹雨 阅读(2207) | 评论 (10) 编辑

SQL Server 数据库迁移偏方
posted @ 2011-04-28 17:51 听风吹雨 阅读(1940) | 评论 (5) 编辑

SQL Server 数据库最小宕机迁移方案
posted @ 2011-03-30 17:44 听风吹雨 阅读(2315) | 评论 (6) 编辑

SQL Server 2005 自动化删除表分区设计方案
posted @ 2011-02-25 17:31 听风吹雨 阅读(2002) | 评论 (4) 编辑

SQL Server 动态生成分区脚本
posted @ 2011-01-14 14:48 听风吹雨 阅读(2407) | 评论 (2) 编辑

SQL Server 2005 分区模板与实例
posted @ 2010-12-31 16:23 听风吹雨 阅读(2441) | 评论 (14) 编辑

SQL Server datetime数据类型设计、优化误区
posted @ 2010-11-26 10:58 听风吹雨 阅读(3103) | 评论 (32) 编辑

SQL Server数据库服务器高性能设置
posted @ 2010-11-16 11:38 听风吹雨 阅读(3415) | 评论 (28) 编辑

SQL Server 合并(删除)分区解惑
posted @ 2010-11-05 16:33 听风吹雨 阅读(2203) | 评论 (3) 编辑

简单实用SQL脚本Part:sql多行转为一列的合并问题
posted @ 2010-10-20 09:41 听风吹雨 阅读(2850) | 评论 (14) 编辑

简单实用SQL脚本Part:生成站点导航树形结构
posted @ 2010-09-16 22:30 听风吹雨 阅读(2034) | 评论 (11) 编辑

简单实用SQL脚本Part:SQL Server 2005 链接服务器
posted @ 2010-09-09 14:43 听风吹雨 阅读(2186) | 评论 (7) 编辑

简单实用SQL脚本Part:游标模板
posted @ 2010-09-08 17:22 听风吹雨 阅读(458) | 评论 (0) 编辑

简单实用SQL脚本Part9:纵向回填信息
posted @ 2010-09-06 14:35 听风吹雨 阅读(1722) | 评论 (10) 编辑

简单实用SQL脚本Part:查找SQL Server 自增ID值不连续记录
posted @ 2010-08-30 20:11 听风吹雨 阅读(3347) | 评论 (14) 编辑

简单实用SQL脚本Part6:特殊需要的行转列
posted @ 2010-08-12 22:51 听风吹雨 阅读(1940) | 评论 (7) 编辑

SQL Server Url正则表达式 内存常驻 完美解决方案
posted @ 2010-07-31 04:12 听风吹雨 阅读(582) | 评论 (0) 编辑

批量生成bcp命令
posted @ 2010-06-02 15:41 听风吹雨 阅读(1669) | 评论 (0) 编辑

留念2010年6月1日——SQL
posted @ 2010-06-02 14:22 听风吹雨 阅读(331) | 评论 (5) 编辑

纯真QQIP库导入到SQL Server详解
posted @ 2010-05-27 22:49 听风吹雨 阅读(2903) | 评论 (18) 编辑

使用SQL Server2005扩展函数进行性能优化
posted @ 2010-05-26 21:55 听风吹雨 阅读(1803) | 评论 (11) 编辑

SQL Server扩展函数的基本概念
posted @ 2010-05-26 19:57 听风吹雨 阅读(1774) | 评论 (6) 编辑

SQL Server 全文索引的硬伤
posted @ 2010-05-13 21:10 听风吹雨 阅读(2012) | 评论 (8) 编辑

简单实用SQL脚本Part2:日期和时间函数
posted @ 2010-04-21 18:25 听风吹雨 阅读(1604) | 评论 (0) 编辑

使用bcp进行大数据量导出导入
posted @ 2010-04-17 20:03 听风吹雨 阅读(2041) | 评论 (3) 编辑

使用Excel批量生成SQL脚本(小技巧)
posted @ 2010-04-15 14:18 听风吹雨 阅读(3006) | 评论 (14) 编辑

简单实用SQL脚本
posted @ 2010-04-09 18:32 听风吹雨 阅读(8919) | 评论 (23) 编辑

空间换时间的数据库设计
posted @ 2010-03-30 11:45 听风吹雨 阅读(3096) | 评论 (11) 编辑

肤浅的 SQL Server 2000、2005对比
posted @ 2010-03-16 15:28 听风吹雨 阅读(1337) | 评论 (0) 编辑

SQL Server 索引中include的魅力(具有包含性列的索引)
posted @ 2010-01-11 20:44 听风吹雨 阅读(3625) | 评论 (10) 编辑

数据库调优积累系列(6):读书笔记
posted @ 2009-12-28 20:05 听风吹雨 阅读(1586) | 评论 (0) 编辑

数据库调优积累系列(5):专业术语
posted @ 2009-12-28 20:04 听风吹雨 阅读(226) | 评论 (0) 编辑

数据库调优积累系列(4):数据库设计
posted @ 2009-12-28 20:02 听风吹雨 阅读(265) | 评论 (0) 编辑

数据库调优积累系列(2):查询
posted @ 2009-12-28 19:49 听风吹雨 阅读(333) | 评论 (0) 编辑

数据库调优积累系列(3):游标
posted @ 2009-12-28 19:49 听风吹雨 阅读(161) | 评论 (0) 编辑

数据库调优积累系列(1):索引
posted @ 2009-12-28 19:47 听风吹雨 阅读(464) | 评论 (2) 编辑
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: