关键词:数据库触发器/服务器触发器  ,数据库级别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. 两台Linux主机互传文件可以使用SCP命令来实现

    当两台linux主机之间要互传文件时可使用SCP命令来实现 复制文件: (1)将本地文件拷贝到远程 scp 文件名 --用户名@计算机IP或者计算机名称:远程路径 (2)从远程将文件拷回本地 scp ...

  2. NUC972裸机调试步骤

    .将开发板设置成USB启动.开发板拨码开关与启动方式设置对应如下: 其中PA1 ,PA0对应S1和S0 上电或复位,使开发板从USB启动.开启NuWriter,选择正确的芯片型号,按下“Continu ...

  3. React Native(十一)——删除事件以及刷新列表

    需求:删除列表中的某一项,但不刷新整个页面,底下的数据顺势而上(第一张是原始数据,第二张是删除掉"你会介今年"这条动态后显示的数据). 中间的过程比较曲折,只因为刚开始的时候自己只 ...

  4. iOS应用内支付(IAP)的那些坑

    本文转载至 http://blog.devtang.com/2013/04/07/tricks-in-iap/ 前言 udacity 中的在线课程 <How to build a startup ...

  5. strcat的几种实现及性能比较

    一  原型说明 strcat()为C语言标准库函数,用于字符串拼接.函数原型声明在string.h头文件中: char *strcat(char *dest, const char *src); 该函 ...

  6. 【Linux】 centos 7 启用端口

    网上的大部分资料都是用iptables防火墙的,但是阿里云的centos 7默认防火墙是firewall.最为简单的方法其实就是关闭我们的防火墙: 1  查看下防火墙的状态: systemctl st ...

  7. 【软件分析与挖掘】ELBlocker: Predicting blocking bugs with ensemble imbalance learning

    摘要: 提出一种方法——ELBlocker,用于自动检测出Blocking Bugs(prevent other bugs from being fixed). 难度在于这些Blocking Bugs仅 ...

  8. java高级---->Thread之ExecutorService的使用

    今天我们通过实例来学习一下ExecutorService的用法.我徒然学会了抗拒热闹,却还来不及透悟真正的冷清. ExecutorService的简单实例 一.ExecutorService的简单使用 ...

  9. screen实战

    VPS侦探在刚接触Linux时最怕的就是SSH远程登录Linux VPS编译安装程序时(比如安装lnmp)网络突然断开,或者其他情况导致不得不与远程SSH服务器链接断开,远程执行的命令也被迫停止,只能 ...

  10. 【读书笔记】socket描述符选项[SOL_SOCKET]

    #include <sys/socket.h>    int setsockopt( int socket, int level, int option_name,             ...