关键词:数据库触发器/服务器触发器  ,数据库级别DDL操作监控审计,禁止修改登录名密码,登录触发器,login触发器

【1】数据库级别DDL操作监控审计

SQL Server 2005开始支持DDL触发器,它不只限于对CREATE/ALTER/DROP操作有效,支持的DDL事件还有比如:权限的GRANT/DENY/REVOEK, 对象的RENAME, 更新统计信息等等,可通过DMV查看更多支持的事件类型如下:

select * from sys.trigger_event_types
where type_name not like '%CREATE%'
and type_name not like '%ALTER%'
and type_name not like '%DROP%'

注意:

1. TRUNCATE不在DDL触发器的事件类型中,SQL Server中将Truncate 归为DML操作语句,虽然它也并不触发DML触发器,就像开启开关的大批量导入操作 (Bulk Import Operations) 一样;

2. DDL触发器中捕获的信息都由EVENTDATA()函数返回,返回类型为XML格式,需要用XQuery来读取;

案例:转自2012示例库,只能数据库级别,不能实例级别

use database
go SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

create table databaseLog( [PostTime] datetime,
[DatabaseUser] varchar(500),
[Event] varchar(500),
[Schema] varchar(50),
[Object] varchar(4000),
[TSQL] varchar(4000),
[XmlEvent] xml)

CREATE TRIGGER [ddlDatabaseTriggerLog] ON DATABASE --all server 实例级别
FOR DDL_DATABASE_LEVEL_EVENTS AS  --DDL_SERVER_LEVEL_EVENTS 实例级别
BEGIN
SET NOCOUNT ON; DECLARE @data XML;
DECLARE @schema sysname;
DECLARE @object sysname;
DECLARE @eventType sysname; SET @data = EVENTDATA();
SET @eventType = @data.value('(/EVENT_INSTANCE/EventType)[1]', 'sysname');
SET @schema = @data.value('(/EVENT_INSTANCE/SchemaName)[1]', 'sysname');
SET @object = @data.value('(/EVENT_INSTANCE/ObjectName)[1]', 'sysname') IF @object IS NOT NULL
PRINT ' ' + @eventType + ' - ' + @schema + '.' + @object;
ELSE
PRINT ' ' + @eventType + ' - ' + @schema; IF @eventType IS NULL
PRINT CONVERT(nvarchar(max), @data); INSERT [dbo].[DatabaseLog]
(
[PostTime],
[DatabaseUser],
[Event],
[Schema],
[Object],
[TSQL],
[XmlEvent]
)
VALUES
(
GETDATE(),
CONVERT(sysname, CURRENT_USER),
@eventType,
CONVERT(sysname, @schema),
CONVERT(sysname, @object),
@data.value('(/EVENT_INSTANCE/TSQLCommand)[1]', 'nvarchar(max)'),
@data
);
END; GO SET ANSI_NULLS OFF
GO SET QUOTED_IDENTIFIER OFF
GO

--开启/关闭
ENABLE TRIGGER [ddlDatabaseTriggerLog] ON DATABASE
DISABLE TRIGGER [ddlDatabaseTriggerLog] ON DATABASE
GO

--删除
DROP TRIGGER tri_LogServerEvent ON DATABASE; --添加扩展属性到数据库对象中(即添加数据字典注解)
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Database trigger to audit all of the DDL changes made to the AdventureWorks2008R2 database.' , 
@level0type=N'TRIGGER',@level0name=N'ddlDatabaseTriggerLog' GO

禁止特定角色的用户对特定的表做DROP操作

IF exists(select * from sys.triggers where name = 'NO_DROP_TABLE' and parent_class_desc = 'DATABASE')
DROP TRIGGER [NO_DROP_TABLE] ON DATABASE;
GO CREATE TRIGGER NO_DROP_TABLE
ON DATABASE
FOR DROP_TABLE
AS
BEGIN
DECLARE @x XML,
@user_name varchar(100),
@db_name varchar(100),
@schema_name varchar(100),
@object_name varchar(200) --select eventdata()
SET @x = EVENTDATA();
SET @user_name = @x.value('(/EVENT_INSTANCE/UserName)[1]','varchar(100)');
SET @db_name = @x.value('(/EVENT_INSTANCE/DatabaseName)[1]','varchar(100)');
SET @schema_name = @x.value('(/EVENT_INSTANCE/SchemaName)[1]','varchar(100)');
SET @object_name = @x.value('(/EVENT_INSTANCE/ObjectName)[1]','varchar(100)'); --PRINT 'Current User: ' + @user_name
--PRINT 'Current Database: ' + @db_name
--PRINT 'Schema Name: ' + @schema_name
--PRINT 'Table Name: ' + @object_name IF is_rolemember('disallow_modify_tables',@user_name) = 1
AND @db_name = 'YOUR_DB_NAME'
AND @schema_name = 'YOUR_SCHEMA_NAME'
AND @object_name like 'YOUR_TABLE_NAME%'
BEGIN
PRINT 'Dropping tables is not allowed'
ROLLBACK
END
END
GO

【2】数据库触发器/服务器触发器

禁止修改登录名密码

create table db_del..check_login(xml_str xml);
GO
CREATE TRIGGER tr_alterpwd
ON all server
FOR ALTER_LOGIN
AS
BEGIN
insert into db_del..check_login values( EVENTDATA())
RAISERROR('搞事情,敢改我密码',16,1)
ROLLBACK
END

【3】登录触发器( LOGON 触发器)

SQL Server 2005在SP2中悄悄引入了LOGON触发器,作为一个实例级的对象,它的系统视图,定义语句和DDL/DML触发器都是分开的。

select * from sys.server_triggers where name = 'login_history_trigger'
select * from sys.server_trigger_events
select OBJECT_ID('login_history_trigger') --无法获取

在SQL Server中,顾名思义,LOGON触发器,只支持LOGON事件;

在ORACLE中,实例级触发器可支持更多事件 (SERVERERROR, LOGON, LOGOFF, STARTUP, or SHUTDOWN)。

代码示例1: 记录所有login登录历史

(其实也可以通过修改login auditing选项,来记录成功和失败的登录在errorlog里)

IF OBJECT_ID('login_history','U') is not null
DROP TABLE login_history
GO CREATE TABLE login_history
(
FACT_ID bigint IDENTITY(1,1) primary key,
LOGIN_NAME nvarchar(1024),
LOGIN_TIME datetime
)
GO IF EXISTS(select 1 from sys.server_triggers where name = 'login_history_trigger')
DROP TRIGGER login_history_trigger ON ALL SERVER
GO CREATE TRIGGER login_history_trigger
ON ALL SERVER
FOR LOGON
AS
BEGIN
--IF SUSER_NAME() NOT LIKE 'NT AUTHORITY\%' AND
-- SUSER_NAME() NOT LIKE 'NT SERVICE\%'
IF ORIGINAL_LOGIN() NOT LIKE 'NT AUTHORITY\%' AND
ORIGINAL_LOGIN() NOT LIKE 'NT SERVICE\%'
BEGIN
INSERT INTO DBA..login_history
VALUES(ORIGINAL_LOGIN(),GETDATE());
END;
END;
GO --view login history after logon
SELECT * FROM login_history

代码示例2: 限制特定用户在特定时间范围登录、限制连接数

--限制下班时间不能登录
DROP TRIGGER IF EXISTS limit_user_login_time ON ALL SERVER
GO
CREATE TRIGGER limit_user_login_time
ON ALL SERVER FOR LOGON
AS
BEGIN
IF ORIGINAL_LOGIN() = 'TestUser'
AND (DATEPART(HOUR, GETDATE()) < 9 OR DATEPART (HOUR, GETDATE()) > 18)
BEGIN
PRINT 'TestUser can only login during working hours!'
ROLLBACK
END
END
GO --限制连接数
DROP TRIGGER IF EXISTS limit_user_connections ON ALL SERVER
GO
CREATE TRIGGER limit_user_connections
ON ALL SERVER
WITH EXECUTE AS 'sa'
FOR LOGON
AS
BEGIN
IF ORIGINAL_LOGIN() = 'TestUser'
AND (SELECT COUNT(*) FROM sys.dm_exec_sessions
WHERE Is_User_Process = 1
AND Original_Login_Name = 'TestUser') > 2
BEGIN
PRINT 'TestUser can only have 1 active session!'
ROLLBACK
END
END

注意:如果LOGON触发器把所有人都锁在外面了怎么办?

Logon failed for login 'TestUser' due to trigger execution.

这时,只能通过DAC登录SQL Server去禁用LOGON触发器/修改逻辑以允许登录,DAC登录方式有远程和本地两种,远程登录需要通过sp_configure 开启remote admin connections ,如果没有事先开启,那就只能选择本地登录方式:

服务器本地,在SSMS中通过DAC登录

服务器本地,在cmd中通过DAC登录

--禁用/启用LOGON触发器
DISABLE TRIGGER limit_user_connections ON ALL SERVER
ENABLE TRIGGER limit_user_connections ON ALL SERVER

数据库级别DDL操作监控审计、数据库触发器/服务器触发器的更多相关文章

  1. 数据库级别DML操作监控审计、表触发器/对象触发器

    使用触发器记录DML,使用触发器记录表的DML 数据库级别DML操作监控审计.表触发器/对象触发器 --创建记录表 CREATE TABLE T_SHALL_LOG ( ID , ) , EVTIME ...

  2. SQL监控:mysql及mssql数据库SQL执行过程监控审计

    转载 Seay_法师 最近生活有很大的一个变动,所以博客也搁置了很长一段时间没写,好像写博客已经成了习惯,搁置一段时间就有那么点危机感,心里总觉得不自在.所以从今天起还是要继续拾起墨笔(键盘),继续好 ...

  3. Linux bash运维操作日志审计(单服务器)

    目前公司有几台机器比较重要,需要把所有用户的操作记录下来,于是就是参照资料来完成 1. vim /etc/profile.d/oplogrc.sh logdir=/opt/oplog userdir= ...

  4. Python --链接MYSQL数据库与简单操作 含SSH链接

    项目是软硬件结合,在缺少设备的情况,需要通过接口来模拟实现与设备的交互,其中就需要通过从数据库读取商品的ID信息 出于安全考虑  现在很多数据库都不允许通过直接访问,大多数是通过SSH SSH : 数 ...

  5. Qt数据库 QSqlTableModel实例操作(转)

    本文介绍的是Qt数据库 QSqlTableModel实例操作,详细操作请先来看内容.与上篇内容衔接着,不顾本文也有关于上篇内容的链接. Qt数据库 QSqlTableModel实例操作是本文所介绍的内 ...

  6. 监控数据库DDL操作日志

    背景 为了监控好生产环境下各个数据库服务器上DDL操作日志,便于运维工程师管控好风险,我们有必要关注当前实例下的所有的DDL操作以及对应的IP和hostname. 测试环境 Microsoft SQL ...

  7. SQLServer 创建服务器和数据库级别审计

    概述 在上一篇文章中已经介绍了审计的概念:本篇文章主要介绍如何创建审计,以及该收集哪些审核规范. 一.常用的审核对象 1.1.服务器审核对象 1.FAILED_LOGIN_GROUP( Audit L ...

  8. SQL Server 创建服务器和数据库级别审计

    一.概述 在上一篇文章中已经介绍了审计的概念:本篇文章主要介绍如何创建审计,以及该收集哪些审核规范. 二.常用的审核对象 2.1.服务器审核对象 1.FAILED_LOGIN_GROUP( Audit ...

  9. 数据库DDL操作

    DDL1. 数据库* 查看所有数据库:SHOW DATABASES* 切换(选择要操作的)数据库:USE 数据库名* 创建数据库:CREATE DATABASE [IF NOT EXISTS] myd ...

随机推荐

  1. [PyCharm] 设置自动启动时自动打开项目

    设置启动PyCharm时自动打开(或不打开)上次进行的项目: 选择 “Settings - General - Reopen last project on startup”,勾选该选项则启动时自动打 ...

  2. numpy常用举例

    转自https://morvanzhou.github.io/tutorials/data-manipulation/np-pd/2-1-np-attributes/ numpy 的属性: ndim: ...

  3. IOS设计模式第七篇之观察者设计模式

    版权声明:原创作品,谢绝转载!否则将追究法律责任. 观察者设计模式 在观察者设计模式里面,一个对象通知其他的对象一些状态的改变.涉及这些对象不需要知道另一个对象---因此鼓励解耦设计模式.这个设计模式 ...

  4. Python六大开源框架对比:Web2py略胜一筹(转)

    Python是一门动态.面向对象语言.其最初就是作为一门面向对象语言设计的,并且在后期又加入了一些更高级的特性.除了语言本身的设计目的之外,Python标准库也是值得大家称赞的,Python甚至还自带 ...

  5. Android中Handler引起的内存泄露

    在Android常用编程中,Handler在进行异步操作并处理返回结果时经常被使用.通常我们的代码会这样实现. 1 2 3 4 5 6 7 8 9 public class SampleActivit ...

  6. 原生js--元素尺寸、位置和溢出

    判断元素尺寸和位置的方法: elem.getBoundingClientRect()  // 已验证IE7+.firefox.chrome均支持此方法 该方法返回一个对象(坐标值为视口坐标,不是文档坐 ...

  7. 有关xml中的xmlns

    1. xmlns "xmlns"是XHTML namespace的缩写,叫做"名字空间"声明.名字空间是什么作用呢?我的理解是:由于xml允许你自己定义自己的标 ...

  8. DragonBones龙骨骨骼中的自定义事件(另有声音、动画事件)

    参考: DragonBones骨骼动画事件系统详解 一.在DragonBones中添加自定义事件帧 动画制作时 时间轴拉到最下面有一个事件层,添加一个事件帧 左边属性面板定义自定义事件 二.Egret ...

  9. windows下的C++与cuda编译器位置

    在windows下最常见的C++编译器为visual studio自带的编译器cl.exe 通常其所在目录为: C:\Program Files (x86)\Microsoft Visual Stud ...

  10. Docker容器挂载宿主目录的情形分析

    Docker容器启动的时候,如果要挂载宿主机的一个目录,可以用-v参数指定. 譬如我要启动一个centos容器,宿主机的/test目录挂载到容器的/soft目录,可通过以下方式指定: # docker ...