毕业论文开发语言企业开发JAVA技术.NET技术WEB开发Linux/Unix数据库技术Windows平台移动平台嵌入式论文范文英语论文
您现在的位置: 毕业论文 >> 数据库 >> 正文

如何限制IP访问sqlerver2008数据库

更新时间:2014-2-21:  来源:毕业论文

SQL2008 中有三个数据库(DB1、DB2、DB3)

要求:ip地址 192.168.1.1  只能访问 DB1 和 DB3,也就是说不能访问 DB2
      ip地址 192.168.1.2  只能访问 DB2 和 DB3,也就是说不能访问 DB1

网上找到是限制访问整个SQL Server ,不是对里面的数据库作限制。
登陆触发器能为我们解决什么问题呢?本文将为你讲述5种运用登陆触发器的场景:

1) 限制某登录名(比如sa)只能在本机或者指定的IP中登陆;

2) 限制服务器角色(比如sysadmin)只能在本机或者指定的IP中登陆;

3) 限制某登录名(比如sa)只能某时间段内登陆;

4) 限制登录名与IP的对应关系,支持多对多关系;

5) 限制某登录名可以在某IP段登录(比如192.168.1.*),如下图;

二、实现过程

(一) 我机器的IP是:192.168.1.48,首先我在数据库创建一个test帐号,设置密码为123,接着创建登陆触发器:tr_connection_limit,它会在用户登陆的时候触发,通过EVENTDATA()函数返回的客户端的IP,使用ORIGINAL_LOGIN()函数返回的登陆名,对IP和登录名进行判断。
当登录名是test的时候,如果登陆的IP地址本地<local machine>或者是192.168.1.50,192.168.1.120就允许登陆,在这之外其它情况的登陆将回滚。登陆失败的如Figure1所示。


--Script1:创建test登录账号
CREATE LOGIN test WITH PASSWORD = '123'
GO

-- =============================================
-- Author:        <听风吹雨>
-- Create date:    <2013.05.21>
-- Description:    <限制test用户只能在本机和指定的IP中登陆>
-- =============================================
CREATE TRIGGER [tr_connection_limit]
ON ALL SERVER WITH EXECUTE AS 'sa'
FOR LOGON
AS
BEGIN

--限制test这个帐号的连接
IF ORIGINAL_LOGIN()= 'test'
--允许test在本机和下面的IP登录
AND
(SELECT EVENTDATA().value('(/EVENT_INSTANCE/ClientHost)[1]', 'NVARCHAR(15)'))
NOT IN('<local machine>','192.168.1.50','192.168.1.120')
     ROLLBACK;
END;

(Figure1:test用户登陆错误信息)

我在一台IP为192.168.1.115的机器上使用test登陆名登陆我的SQL Server数据库,因为这个IP不在允许的IP列表中,所以出现了Figure1的错误信息。我再使用一台IP为192.168.1.120的机器登陆我的SQL Server数据库,成功登陆了,使用Script2返回登陆的信息;如Figure2,请看session_id为58的记录:登陆名为test,登陆的IP为192.168.1.120。


--Script2:返回登录信息
SELECT
a.[session_id],a.[login_time],a.[host_name],
a.[original_login_name],b.[client_net_address]
FROM MASTER.sys.dm_exec_sessions a
INNER JOIN MASTER.sys.dm_exec_connections b
ON a.session_id=b.session_id

(Figure2:用户登陆信息)

关于Script1脚本中EXECUTE AS的用法可以参考:EXECUTE AS (Transact-SQL),ORIGINAL_LOGIN()函数可以参考:ORIGINAL_LOGIN (Transact-SQL),EVENTDATA()函数用法可以参考:EVENTDATA (Transact-SQL)

(二) 有些时候,你数据库可能有许多个登陆帐号,而你更希望的是限制IP,而登陆名跟IP并没有直接的关联,那这应该怎么实现呢?
首先创建一个Logon_DB数据库,再创建一个ValidIP表,在表中插入<local machine>和192.168.1.195,表示允许本地和IP为192.168.1.195进行登陆,登陆的帐号属于服务器角色:sysadmin。


--Script3:
--创建测试数据库
USE MASTER
GO
CREATE DATABASE Logon_DB

--创建IP过滤表
USE Logon_DB
GO
CREATE TABLE dbo.ValidIP (
    IP NVARCHAR(15),
    CONSTRAINT PK_ValidIP PRIMARY KEY CLUSTERED(IP)
);
GO

--插入过滤IP
USE Logon_DB
GO
INSERT INTO dbo.ValidIP(IP) VALUES('<local machine>');
INSERT INTO dbo.ValidIP(IP) VALUES('192.168.1.195');

--创建登录触发器
-- =============================================
-- Author:        <听风吹雨>
-- Create date:    <2013.05.21>
-- Description:    <限制本机和指定的IP登陆>
-- =============================================
CREATE TRIGGER [tr_logon_CheckIP]
ON ALL SERVER
FOR LOGON
AS
BEGIN
    IF IS_SRVROLEMEMBER('sysadmin') = 1
    BEGIN
        DECLARE @IP NVARCHAR(15);
        SET @IP = (SELECT EVENTDATA().value('(/EVENT_INSTANCE/ClientHost)[1]', 'NVARCHAR(15)'));
        IF NOT EXISTS(SELECT IP FROM [Logon_DB].[dbo].[ValidIP] WHERE IP = @IP)
        ROLLBACK;
    END;
END;这次我们在IP为:192.168.1.120的机器上进行测试,这个IP之前是允许使用test帐号登陆的(tr_connection_limit),这次使用sa这个帐号登陆,返回了Figure3的错误信息,这是因为它违反了登陆触发器tr_logon_CheckIP的规则。

 

(Figure3:sa用户登陆错误信息)

在IP为192.168.1.195的机器上使用sa这个帐号成功登陆,再次执行Script2脚本,返回的列表如Figure4所示。

 

(Figure4:用户登陆信息)

(三) 还有一种场景,我们需要限制某些用户只能在指定的时间内登陆数据库,比如业务上某些运用只能在晚上跑的,通过这个登陆触发器,可以防止运用修改执行时间在白天中运行。
首先我们创建一个名为nightworker的登陆名,再创建一个LogonBlockedLog的登陆拦截日志表,接着创建登陆触发器:tr_logon_CheckTime,在早上7:00之后至晚上18:00之前(BETWEEN 7 AND 17)是不允许nightworker帐号登陆数据库的。


--Script4:
--创建nightworker登录账号
CREATE LOGIN nightworker WITH PASSWORD = '123'
GO

--创建登录拦截日志表
USE Logon_DB
GO
CREATE TABLE dbo.LogonBlockedLog (
    [Id] INT IDENTITY(1,1),
    [session_id] SMALLINT,
    [login_time] DATETIME,
    [host_name] NVARCHAR(128),
    [original_login_name] NVARCHAR(128),
    [client_net_address] VARCHAR(48),
    CONSTRAINT PK_LogonLog PRIMARY KEY CLUSTERED(Id)
);

--创建登录触发器
-- =============================================
-- Author:        <听风吹雨>
-- Create date:    <2013.05.21>
-- Description:    <限制登陆时间>
-- =============================================
CREATE TRIGGER [tr_logon_CheckTime]
ON ALL SERVER WITH EXECUTE AS 'sa'
FOR LOGON
AS
BEGIN
    IF ORIGINAL_LOGIN()='nightworker' AND
    DATEPART(hh,GETDATE()) BETWEEN 7 AND 17
    BEGIN
        ROLLBACK;
        INSERT INTO [Logon_DB].[dbo].[LogonBlockedLog]
            ([session_id]
            ,[login_time]
            ,[host_name]
            ,[original_login_name]
            ,[client_net_address])
        SELECT
            a.[session_id],a.[login_time],a.[host_name],
            a.[original_login_name],b.[client_net_address]
            FROM MASTER.sys.dm_exec_sessions a
            INNER JOIN MASTER.sys.dm_exec_connections b
            ON a.session_id=b.session_id
            WHERE a.session_id = @@SPID
    END;
END;现在时间是17:20左右,我使用nightworker登陆数据库,这违反了登陆触发器:tr_logon_CheckTime,所以提示Figure5的错误信息,并且在LogonBlockedLog拦截日志表中出现了一条记录,这个表可以帮助我们更好的了解登陆账号的登陆信息。

 

(Figure5:nightworker用户登陆错误信息)

 

(Figure6:拦截日志表)

(四) 我们进一步模仿MySQL的mysql.User表的用法,用表保存用户与IP的对应关系,这样就可以对所有登陆用户进行控制了。

--Script5:
--登陆名与有效IP对应表
USE Logon_DB
GO
CREATE TABLE [dbo].[ValidLogOn](
    [Id] INT IDENTITY(1,1) NOT NULL,
    [LoginName] [sysname] NOT NULL,
    [ValidIP] [nvarchar](15) NOT NULL,
    CONSTRAINT [PK_ValidLogOn] PRIMARY KEY CLUSTERED ([Id])
 )
--创建唯一约束索引
CREATE UNIQUE NONCLUSTERED INDEX [IX_ValidLogOn_LV] ON [dbo].[ValidLogOn]
(
    [LoginName] ASC,
    [ValidIP] ASC
)
 --插入测试数据
INSERT [dbo].[ValidLogOn] ([LoginName], [ValidIP]) VALUES (N'BARXXX\Administrator', N'<local machine>')
INSERT [dbo].[ValidLogOn] ([LoginName], [ValidIP]) VALUES (N'nightworker', N'<local machine>')
INSERT [dbo].[ValidLogOn] ([LoginName], [ValidIP]) VALUES (N'nightworker', N'192.168.1.48')
INSERT [dbo].[ValidLogOn] ([LoginName], [ValidIP]) VALUES (N'sa', N'<local machine>')
INSERT [dbo].[ValidLogOn] ([LoginName], [ValidIP]) VALUES (N'sa', N'127.0.0.1')
INSERT [dbo].[ValidLogOn] ([LoginName], [ValidIP]) VALUES (N'sa', N'192.168.1.48')
INSERT [dbo].[ValidLogOn] ([LoginName], [ValidIP]) VALUES (N'test', N'<local machine>')
INSERT [dbo].[ValidLogOn] ([LoginName], [ValidIP]) VALUES (N'test', N'192.168.1.120')
INSERT [dbo].[ValidLogOn] ([LoginName], [ValidIP]) VALUES (N'test', N'192.168.1.48')
INSERT [dbo].[ValidLogOn] ([LoginName], [ValidIP]) VALUES (N'test', N'192.168.1.50')
--创建登录触发器
-- =============================================
-- Author:        <听风吹雨>
-- Create date:    <2013.05.21>
-- Description:    <限制登陆名和IP>
-- =============================================
CREATE TRIGGER [tr_logon_CheckLogOn]
ON ALL SERVER WITH EXECUTE AS 'sa'
FOR LOGON
AS
BEGIN
    DECLARE @LoginName sysname
    DECLARE @IP NVARCHAR(15)
    SET @LoginName = ORIGINAL_LOGIN();
    SET @IP = (SELECT EVENTDATA().value('(/EVENT_INSTANCE/ClientHost)[1]', 'NVARCHAR(15)'));
    --判断登录名和IP
    IF NOT EXISTS(SELECT [ValidIP] FROM [Logon_DB].[dbo].[ValidLogOn] WHERE [LoginName] = @LoginName AND [ValidIP] = @IP)
        ROLLBACK;
END;

(Figure7:登陆名与有效IP对应表)

用户登陆名与IP对应关系表[ValidLogOn],有几点需要注意的,BARXXX\Administrator这个是Windows 身份验证中操作系统的帐号,你需要根据你的实际情况进行修改;IP当中你则需要注意<local machine>和127.0.0.1这些特殊的地址,我个人还是建议在这个表中加入这些信息的。

(五) 对上面的再延伸一点,如果想类似Host like 192.168.1.* 这样进行范围的过滤,那这又应该怎么实现呢?
可以使用CLR扩展函数对IP进行判断,后面会讲到这种方式。这里使用SQL就能解决的方法,仅供参考。开放登录名nightworker在内网所有IP:192.168.1.* 访问本机的权限。


--Script6:
--插入测试数据
INSERT [dbo].[ValidLogOn] ([LoginName], [ValidIP]) VALUES (N'nightworker', N'192.168.1.*')

--创建登录触发器
-- =============================================
-- A

[1] [2] 下一页

设为首页 | 联系站长 | 友情链接 | 网站地图 |

copyright©youerw.com 优尔论文网 严禁转载
如果本毕业论文网损害了您的利益或者侵犯了您的权利,请及时联系,我们一定会及时改正。