连接记录

问题描述 投票:3回答:1

我希望SQL Server创建一个记录所有(成功)登录/数据库连接的日志文件。日志应该包含最低限度:

  • 连接客户端的IP地址和端口
  • 客户端的应用程序名称
  • 用户名
  • 数据库名称
  • 连接时间或适用的交易

它看起来像a server trace likely can capture all this information,但微软表示不推荐使用服务器跟踪来支持扩展事件。

所以我试图通过扩展事件收集这些信息。对于我的测试,我使用的是SQL Server 2017 Developer Edition(在Windows 10上的Docker容器中运行)和SSMS v17.7。我在创建或查看扩展事件时以“sa”身份登录。

到目前为止,我已经能够通过扩展事件收集大部分此类信息。问题是收集客户端IP和端口。我可以孤立地获得任何一部分,但不能同时获得两部分。我正在使用的XEvents如下所示。 connection_accept被列入两次这一事实并非错误。 SQL Server实际上有两个具有完全相同名称的不同事件(!!!)。

  • Login:没有收集客户端IP或端口的选项(字段或操作)。至少它确实提供client_hostname
  • Logout:没有收集客户端IP或端口的选项(字段或操作)。这也捕获了client_hostname
  • connection_accept: 收集客户端IP,但它掩盖了最低的八位字节(例如192.168.1.XX)! 收集客户端端口!好! 不收集session_id,因此无法与LoginLogout事件相关联。 我的EVENT SESSION指定了usernameclient_app_nameclient_hostname的集合,但这些字段/操作中没有一个存在于收集的数据中。 :(
  • connection_accept: 收集客户端端口,但不收集客户端IP! 有sesstion_id,所以至少它可以与LoginLogout相关联 注意:我还没有在野外发现这个特殊事件,所以我没有进一步的评论。

这些事件都不提供客户端的IP地址,但我会接受客户端主机名作为合理的替代品。但是,获得端口号是一个真正的问题。端口号仅在connection_accept事件中找到,并且没有明显的方法将其与具有主机名的login事件相关联。简而言之,似乎扩展事件根本无法提供此基本客户端IP端口配对。我想相信我错了,因为它是如此基本的数据。任何有关我所忽视的帮助或建议将不胜感激。

扩展事件DDL

这是我测试过的EVENT SESSION的DDL:

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

备择方案

除了扩展事件,"security audits" is another mechanism没有被弃用。所以我想我也试一试:

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

提供的字段包括“客户端应用程序”,“客户端IP”,“会话ID”和用户名(即“服务器原则名称”)。但是,没有办法将其与connection_accept XEvent相关联。所以没有办法提取我想要的两条信息:客户端IP和端口号。 :(

奖金

除了收集客户端IP和端口,我也对collecting SQL Server network traffic volume感兴趣。但是,我还没有看到任何方法。提示赞赏!我只看到vaguely related posts

Update

我注意到一个名为task_address的全球行动(场)似乎与loginlogoutconnection_accept事件有关。因此,现在可以通过组合login:client_hostnameconnection_accept:port找到IP和端口。我唯一担心的是我找不到task_address的文档来验证我的观察结果。

sql-server monitoring network-monitoring extended-events
1个回答
0
投票

如果您可以在您的环境中使用触发器,这是一个解决方案。每次有“登录”时,都会在[master]中插入一行。[dbo]。[TR​​ACETABLE]。

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
© www.soinside.com 2019 - 2024. All rights reserved.