Bre*_*ias 6 sql-server monitoring network-monitoring extended-events
我希望 SQL Server 创建一个日志文件,记录所有(成功的)数据库登录/连接。日志应至少包含:
看起来服务器跟踪可能可以捕获所有这些信息,但微软表示服务器跟踪已被弃用,取而代之的是扩展事件。
因此,我尝试通过扩展事件收集这些信息。对于我的测试,我使用 SQL Server 2017 Developer Edition(在 Windows 10 上的 Docker 容器中运行)和 SSMS v17.7。创建或查看扩展事件时,我以“sa”身份登录。
到目前为止,我已经能够通过扩展事件收集大部分信息。问题是收集客户端 IP 和端口。我可以单独获得任何一个部分,但不能同时获得两个部分。下面列出了我正在使用的 XEvent。列出两次的事实connection_accept并不是错误。SQL Server 实际上有两个名称完全相同的不同事件(!!!)。
Login:没有收集客户端 IP 或端口的选项(字段或操作)。至少它确实提供了client_hostname!Logout:没有收集客户端 IP 或端口的选项(字段或操作)。这也捕捉到了client_hostname。connection_accept:
Login事件关联Logout。EVENT SESSION的集合,但这些字段/操作都不存在于收集的数据中。:(usernameclient_app_nameclient_hostnameconnection_accept:
Login和Logout这些事件都没有提供客户端的 IP 地址,但我会接受客户端主机名作为合理的替代。然而,获取端口号是一个真正的问题。端口号仅在connection_accept事件中找到,并且没有明显的方法将其与login具有主机名的事件关联起来。简而言之,扩展事件似乎根本无法提供这种基本的客户端 IP 和端口配对。我想相信我错了,因为这是如此基本的数据。对于我所忽略的内容的任何帮助或建议将不胜感激。
这是我一直在测试的 DDL EVENT SESSION:
CREATE EVENT SESSION [Connections] ON SERVER
ADD EVENT SQLSatellite.connection_accept(
ACTION(sqlserver.client_app_name,sqlserver.client_connection_id,sqlserver.client_hostname,sqlserver.context_info,sqlserver.database_name,sqlserver.nt_username,sqlserver.request_id,sqlserver.server_instance_name,sqlserver.server_principal_name,sqlserver.session_id,sqlserver.transaction_id,sqlserver.username)
WHERE ([sqlserver].[not_equal_i_sql_unicode_string]([sqlserver].[client_app_name],N'SQLServerCEIP'))),
ADD EVENT sqlserver.connection_accept(
ACTION(sqlserver.client_app_name,sqlserver.client_connection_id,sqlserver.client_hostname,sqlserver.context_info,sqlserver.database_name,sqlserver.nt_username,sqlserver.request_id,sqlserver.server_instance_name,sqlserver.server_principal_name,sqlserver.session_id,sqlserver.transaction_id,sqlserver.username)
WHERE ([sqlserver].[not_equal_i_sql_unicode_string]([sqlserver].[client_app_name],N'SQLServerCEIP'))),
ADD EVENT sqlserver.connectivity_ring_buffer_recorded(
ACTION(sqlserver.client_app_name,sqlserver.client_connection_id,sqlserver.client_hostname,sqlserver.database_name,sqlserver.nt_username,sqlserver.server_instance_name,sqlserver.server_principal_name,sqlserver.session_id,sqlserver.session_nt_username,sqlserver.transaction_id,sqlserver.username)
WHERE ([sqlserver].[client_app_name]<>N'SQLServerCEIP')),
ADD EVENT sqlserver.login(SET collect_options_text=(1)
ACTION(sqlserver.client_app_name,sqlserver.client_connection_id,sqlserver.client_hostname,sqlserver.database_name,sqlserver.nt_username,sqlserver.server_instance_name,sqlserver.server_principal_name,sqlserver.session_id,sqlserver.session_nt_username,sqlserver.transaction_id,sqlserver.username)
WHERE ([sqlserver].[client_app_name]<>N'SQLServerCEIP')),
ADD EVENT sqlserver.logout(
ACTION(sqlserver.client_app_name,sqlserver.client_connection_id,sqlserver.client_hostname,sqlserver.database_name,sqlserver.nt_username,sqlserver.server_instance_name,sqlserver.server_principal_name,sqlserver.session_id,sqlserver.session_nt_username,sqlserver.transaction_id,sqlserver.username)
WHERE ([sqlserver].[client_app_name]<>N'SQLServerCEIP'))
ADD TARGET package0.event_file(SET filename=N'c:\xevents\connections')
WITH (MAX_MEMORY=4096 KB,EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,MAX_DISPATCH_LATENCY=30 SECONDS,MAX_EVENT_SIZE=0 KB,MEMORY_PARTITION_MODE=NONE,TRACK_CAUSALITY=ON,STARTUP_STATE=OFF)
GO
Run Code Online (Sandbox Code Playgroud)
除了扩展事件之外,“安全审核”是另一种未被弃用的机制。所以我想我也应该尝试一下:
USE [master]
GO
CREATE SERVER AUDIT [AuditTest]
TO FILE
( FILEPATH = N'C:\xevents\'
,MAXSIZE = 2 MB
,MAX_FILES = 5
,RESERVE_DISK_SPACE = OFF
)
WITH
( QUEUE_DELAY = 1000
,ON_FAILURE = CONTINUE
)
CREATE SERVER AUDIT SPECIFICATION [Connections]
FOR SERVER AUDIT [AuditTest]
ADD (SUCCESSFUL_LOGIN_GROUP),
ADD (LOGOUT_GROUP)
GO
Run Code Online (Sandbox Code Playgroud)
提供的字段包括“客户端应用程序”、“客户端 IP”、“会话 ID”和用户名(即“服务器主体名称”)。但是,无法将其与connection_acceptXEvent 关联起来。所以没办法提取出我想要的两条信息:客户端IP和端口号。:(
除了收集客户端IP和端口之外,我还对收集SQL Server网络流量感兴趣。然而,我还没有看到任何方法可以做到这一点。提示赞赏!我只看到模糊相关的帖子。
我注意到一个名为 的全局操作(字段)task_address似乎与login,logout和connection_accept事件相关。因此,现在可以通过组合login:client_hostname和来找到 IP 和端口connection_accept:port。我唯一担心的是我找不到文件来task_address验证我的观察结果。
如果您可以在您的环境中使用触发器,这里是一个解决方案。每次“登录”时,都会向[master].[dbo].[TRACETABLE]插入一行。
CREATE TABLE [master].[dbo].[TRACETABLE] (
[EVENTDATE] DATETIME NOT NULL,
[DBNAME] NVARCHAR(128) NULL,
[CURRENTUSER] NVARCHAR(128) NULL,
[HOSTNAME] NVARCHAR(128) NULL,
[APPLICATIONNAME] NVARCHAR(128) NULL,
[PROCEDURENAME] NVARCHAR(128) NULL,
[USERID] SMALLINT NULL,
[USERNAME] NVARCHAR(128) NULL,
[SUSERID] INT NULL,
[SUSERNAME] NVARCHAR(128) NULL,
[IS_SERVERADMIN_SYSADMIN] INT NULL,
[IS_DB_OWNER] INT NULL,
[IS_DDL_ADMIN] INT NULL,
[IS_DB_DATAREADER] INT NULL,
[ORIGINAL_LOGIN] NVARCHAR(4000) NULL,
[NET_TRANSPORT] SQL_VARIANT NULL,
[PROTOCOL_TYPE] SQL_VARIANT NULL,
[AUTH_SCHEME] SQL_VARIANT NULL,
[LOCAL_NET_ADDRESS] SQL_VARIANT NULL,
[LOCAL_TCP_PORT] SQL_VARIANT NULL,
[CLIENT_NET_ADDRESS] SQL_VARIANT NULL,
[PHYSICAL_NET_TRANSPORT] SQL_VARIANT NULL)
GO
GRANT INSERT ON [master].[dbo].[TRACETABLE] TO PUBLIC
GRANT SELECT on [master].[sys].[dm_exec_connections] TO PUBLIC
GO
CREATE TRIGGER Logon_Trigger_Track_IP
ON ALL SERVER FOR LOGON
AS
BEGIN
INSERT INTO [master].[dbo].[TRACETABLE]
--the auditing snippet below works fine in a
--login trigger,
--database trigger
--or any stored procedure.
SELECT
getdate() AS EventDate,
DB_NAME() AS DBName,
CURRENT_USER AS CurrentUser,
HOST_NAME() AS HostName,
APP_NAME() AS ApplicationName,
OBJECT_NAME(@@PROCID) AS ProcedureName,
USER_ID() AS Userid,
USER_NAME() AS UserName,
SUSER_ID() AS sUserid,
SUSER_SNAME() AS sUserName,
IS_SRVROLEMEMBER ('sysadmin') AS [Is_ServerAdmin_Sysadmin],
IS_MEMBER('db_owner') AS [Is_DB_owner],
IS_MEMBER('db_ddladmin') AS [Is_DDL_Admin],
IS_MEMBER('db_datareader') AS [Is_DB_Datareader],
ORIGINAL_LOGIN() AS [ORIGINAL_LOGIN],
ConnectionProperty('net_transport') AS 'net_transport',
ConnectionProperty('protocol_type') AS 'protocol_type',
ConnectionProperty('auth_scheme') AS 'auth_scheme',
ConnectionProperty('local_net_address') AS 'local_net_address',
ConnectionProperty('local_tcp_port') AS 'local_tcp_port',
ConnectionProperty('client_net_address') AS 'client_net_address',
ConnectionProperty('physical_net_transport') AS 'physical_net_transport'
END
GO
ENABLE TRIGGER [Logon_Trigger_Track_IP] ON ALL SERVER
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4805 次 |
| 最近记录: |