【转载】原文地址:https://www.baidu.com/link?url=N-SM28ge21TTYky79dYk8otsjKgYCIpy-0RBSvMV25f8KSOsYczhxTOCzeNZhaNV-U6gy-xVhAVcyRwiCTLYG_&wd=&eqid=d5aab7f6000533a4000000035afa3701

1.问题背景:

之前有客户朋友在做数据安全加固项目的时候和我聊到,SQLServer能不能像mysql一样设置类似的IP访问白名单、黑名单,以此来加强数据访问安全。我们知道mysql里有张mysql.user表记录了用户的权限信息,其中host、user字段就是用来限制用户IP访问权限的。

当然SQL Server和Oracle是没有这样的权限表的,换个思路,SQLServer我们可以通过登录触发器来间接实现同样的功能,而oracle可通过sqlnet.ora文件中添加CP.VALIDNODE_CHECKING参数来实现

2.登录触发器

SQLServer 包括三种常规类型的触发器:DML TRIGGER、DDL TRIGGER和LOGONTRIGGER。DML触发器是比较常使用的,它主要针对表或视图中的数据修改(INSERT、UPDATE和DELETE等)在激发任何有效的事件时,将会激发这些触发器,而无论是否会影响任何表行;DDL触发器用于响应各种数据定义语言 (DDL) 事件。 这些事件主要对应于Transact-SQL CREATE、ALTER 和 DROP 语句,以及执行类似 DDL操作的某些系统存储过程。 而登录触发器在遇到 LOGON 事件时触发,LOGON 事件是在建立用户会话时引发的,也是我们此文将要提及的触发器。

3.限制登录条件

比如说

1)限制某个login(比如test)只能在本机或指定IP登录

2)限制服务器角色(比如sysadmin)只能在本机或指定IP登录

3)限制某个login(比如testtime)只能在某个时间段登录同时记录非法登录日志

4.实现过程

1)限制某个login(比如test)只能在本机或指定IP登录

当检测到登录账号为test时,则会限制该账号只能在本机,或IP地址为192.168.0.108或192.168.0.109上登录。此例涉及到EVENTDATA()函数,有兴趣可以到msdn上查看其使用方法。

代码:

 --创建test登录账号

 CREATE LOGIN test WITH PASSWORD = 'test'

 GO

 --创建登录触发器

 ALTER TRIGGER [restrict_login]
--控制 数据库引擎使用sa用户帐户来验证对模块引用的对象的权限,是借用,仅在此存储过程中有用
ON ALL SERVER WITH EXECUTE AS 'sa' FOR LOGON AS BEGIN
--返回连接到 SQL Server 实例的登录名,并校验
IF ORIGINAL_LOGIN()= 'test' AND
--返回有关服务器或数据库事件的信息。校验登陆事件的IP是否为指定IP
(SELECT EVENTDATA().value('(/EVENT_INSTANCE/ClientHost)[1]', 'NVARCHAR(15)')) NOT IN('','192.168.0.108','192.168.0.109')
--在隐式或显式调用 EVENTDATA 的事务提交或回滚之后,EVENTDATA 所返回的数据将无效。
ROLLBACK; END;

若test账号在除'','192.168.0.108','192.168.0.109'之外的服务器上登录时,则会抛出如下错误

但是在本机上使用test账号则能正常登录,使用以下代码查看登录情况:

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

2)限制服务器角色(比如sysadmin)只能在本机或指定IP登录

这里我们效仿mysql里的user表,设置了一个IP表来限制访问IP。

当检测到登录login为sysadmin服务器角色(这个角色可以设为diskadmin,dbcreator等9种服务器角色中的任一种),且登录ip地址不在dbo.connectip定义的有效ip地址内,则拒绝登录访问

代码:

 --创建IP过滤表

 USE db22

 GO

 CREATE TABLE dbo.connectip ( 

     IP NVARCHAR(20), 

     CONSTRAINT PK_IP PRIMARY KEY CLUSTERED(IP) 

 ); 

 GO

 --插入白名单IP

 USE db22

 GO

 INSERT INTO dbo.connectip(IP) VALUES('');

 INSERT INTO dbo.connectip(IP) VALUES('192.168.0.108');

 --创建登录触发器

 CREATE TRIGGER [restrict_login_check] 

 ON ALL SERVER 

 FOR LOGON 

 AS 

 BEGIN
--指示 SQL Server 登录名是否为指定服务器角色的成员
IF IS_SRVROLEMEMBER('sysadmin') = 1 BEGIN DECLARE @IP NVARCHAR(20); SET @IP = (SELECT EVENTDATA().value('(/EVENT_INSTANCE/ClientHost)[1]', 'NVARCHAR(20)')); IF NOT EXISTS(SELECT IP FROM [db22].dbo.connectip WHERE IP = @IP) ROLLBACK; END; END;

当我们从ip地址为192.168.0.108(不在有效ip内)服务器上以sa(sysadmin角色)用户远程登录的话,会抛出如下错误

但是我们却可以以不受限的tete账户从192.168.0.106来登录

如果想把这个表内的ip都加密,结果发现不一致导致登录失败了,怎么都进不来,怎么办?按照以下步骤来:

1.打开Sql Server Manage Studio,不要登录(反正是会失败),去菜单:“文件”--“新建”--“使用当前连接的查询”,在打开的登录窗口中,服务器名称输入:ADMIN:127.0.0.1

,账号sa + 原密码,,点击登录,成功

2.在打开的查询界面执行:drop trigger tr_logon_CheckIP on all server   执行成功,就删除掉这个触发器了

3.重新登录sa,发现可以进去了

3)限制某个login(比如testtime)只能在某个时间段登录,同时记录非法登录信息

假设一个场景,我们规定某些用户只能晚上固定某个时间段登录服务器进行一些报表拉取操作,而白天不允许其登录,那么此例可以帮助我们实现而且能达到监控的目的。

代码:

 --创建登录账号

 CREATE LOGIN testnight WITH PASSWORD = 'testnight'

 GO

 --创建拦截日志表

 USE db22

 GO

 CREATE TABLE dbo.login_record ( 

     [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_id PRIMARY KEY CLUSTERED(Id) 

 ); 

 --创建登录触发器

 ALTER TRIGGER [restrict_login_record]

 ON ALL SERVER WITH EXECUTE AS 'sa'

 FOR LOGON

 AS

 BEGIN

     IF ORIGINAL_LOGIN()='testnight' AND

     DATEPART(hh,GETDATE()) BETWEEN 9 AND 18

     BEGIN

         ROLLBACK;

         INSERT INTO [db22].[dbo].[login_record]

             ([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;

此例中,如果testnight用户在白天9:00-18:00任意时间登录,则会抛出如下登录错误

同时会在拦截日志表dbo.login_record中有如下记录:

甚至我们可以模仿mysql里的mysql.user表建立一个含host,user字段的登录白名单表,用来保存用户与IP对应关系,这样就可以对所有用户进行管控了,其实它的实现也很简单,主要是一个取IP的方法:EVENTDATA().value('(/EVENT_INSTANCE/ClientHost)[1]','NVARCHAR(15)'),然后与白名单表里的IP和user做比对,若白名单表里没有对应项,则ROLLBACK并记录登录信息到log表即可,这里就不赘述了,有兴趣的朋友可以试试。

SQL——登陆触发器实现限制IP的更多相关文章

  1. SQL Server 限制IP登陆(登陆触发器运用)

    原文:SQL Server 限制IP登陆(登陆触发器运用) 一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 实现代码(SQL Codes) 补 ...

  2. SQL Server基础之登陆触发器

    虽然同表级(DML)触发器和库级(DDL)触发器共顶着一个帽子,但登陆触发器与二者有本质区别.无论表级还是库级,都是用来进行数据管理的,而登陆触发器是纯粹的安全工具. 登陆触发器只响应LOGON事件, ...

  3. SQL Server 触发器

    触发器是一种特殊类型的存储过程,它不同于之前的我们介绍的存储过程.触发器主要是通过事件进行触发被自动调用执行的.而存储过程可以通过存储过程的名称被调用. Ø 什么是触发器 触发器对表进行插入.更新.删 ...

  4. 【Oracle连接字符串】【Oracle Net Manager 服务命名配置】【PL/SQL 登陆数据库】

    连接数据库的几个重要参数: 1. 登陆用户名:user: 2. 登录密码:password: 3. 存放数据库的服务器地址(server_ip)和端口(server_port): 4. 数据库名(db ...

  5. Oracle Net Manager 服务命名配置以及用PL/SQL 登陆数据库

    我们知道,要连接一个数据库需要知道四个参数: 1. 登陆用户名:user: 2. 登录密码:password: 3. 存放数据库的服务器地址(server_ip)和端口(server_port): 4 ...

  6. sql sever 触发器的概念和使用

    触发器简介: 触发器是一种特殊的存储过程,它的执行不是由程序调用,也不是手动执行,而是由事件来触发.触发器是当对某一个表进行操作.例如:update.insert.delete这些操作的时候,系统会自 ...

  7. Oracle数据库编程:使用PL/SQL编写触发器

    8.使用PL/SQL编写触发器: 触发器存放在数据缓冲区中.        触发器加序列能够实现自动增长.        在触发器中不能使用connit和rollback.        DML触发器 ...

  8. sql server触发器的例子

    发布:thebaby   来源:脚本学堂     [大 中 小] 本文介绍下,在sql server数据库中使用触发器的简单例子,有需要的朋友可以参考下,希望对你有一定的帮助. 原文地址:http:/ ...

  9. 15、SQL Server 触发器

    SQL Server 触发器 触发器是一种特殊的存储过程,只有当试图用数据操作语言DML来修改数据时才会触发,DML包含对视图和表的增.删.改. 触发器分为DML触发器和DDL触发器,其中DML触发器 ...

随机推荐

  1. caffeModels--models-caffes-大全

    caffe的伯克利主页:http://caffe.berkeleyvision.org/caffe的github主页:https://github.com/BVLC/caffe caffe的model ...

  2. java 回文字符串

    package string.string1_5; public class Palindrome { /** * 从两头向中间移动 * @param str * @return */ public ...

  3. vue-router 介绍

    vue-router是官方的路由管理工具,用于组建单页面应用很方便快捷.还记得我们在上一篇文章中,使用vue-cli创建的hello-vue的那个项目吗?打开项目,我们先看下目录结构: 看了上面的目录 ...

  4. 转_Greenplum 数据库安装部署(生产环境)

    Greenplum 数据库安装部署(生产环境) 硬件配置: 16 台 IBM X3650, 节点配置:CPU 2 * 8core,内存 128GB,硬盘 16 * 900GB,万兆网卡. 万兆交换机. ...

  5. java 多线程2(转载)

    http://www.cnblogs.com/DreamSea/archive/2012/01/11/JavaThread.html Ø线程的概述(Introduction) 线程是一个程序的多个执行 ...

  6. cURL实现Get和Post

    1.Get请求: //初始化 $ch = curl_init(); //设置选项,包括URL curl_setopt($ch, CURLOPT_URL, "http://www.jb51.n ...

  7. 深入理解Java:注解(Annotation)自己定义注解入门

    深入理解Java:注解(Annotation)自己定义注解入门 要深入学习注解.我们就必须能定义自己的注解,并使用注解,在定义自己的注解之前.我们就必须要了解Java为我们提供的元注解和相关定义注解的 ...

  8. [不好分类]iphone手机激活错误的处理过程

    同事一台iphone 6s手机,重启后显示无法激活.(欢迎访问viphhs,欢迎转载.https://www.cnblogs.com/viphhs) 百度后尝试更换了手机卡,重新连接wifi,都不能恢 ...

  9. iOS不用上架就能下载安装ipa应用内测:使用FIR.im发布自己的移动端APP

    本文转自:http://www.cnblogs.com/imzzk/p/firim.html 一次很偶然的机会知道fir.im,这家公司主要的产品就是帮助开发者方便便捷地发布iOS或者Android应 ...

  10. c# 委托 Predicate的使用示例

    一.说明 委托Predicate 可以有参数(比如下面的示例),也可以不带参数,委托Predicate是返回固定值bool值的委托 二.示例代码(控制台程序) using System; using ...