Я хочу, чтобы SQL Server создал запись в файле журнала всех (успешных) входов / подключений к базе данных.Журнал должен содержать как минимум:
- IP-адрес и порт подключающегося клиента
- имя приложения клиента
- имя пользователя
- имя базы данных
- время соединения или применимой транзакции
Похоже, трассировка сервера, вероятно, может собрать всю эту информацию , но Microsoft говорит, что трассировки сервера устарели в пользуРасширенные события.
Итак, я пытаюсь собрать эту информацию с помощью расширенных событий.Для своих тестов я использую SQL Server 2017 Developer Edition (работает в контейнере Docker в Windows 10) и 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, поэтому его нельзя сопоставить с
Login
или Logout
событиями. - My
EVENT SESSION
указывает набор username
, client_app_name
и client_hostname
, но ни одно из этих полей / действий не присутствует в собранных данных.: (
connection_accept
: - Собирает клиентский порт, но не собирает IP-адрес клиента !!!
- Имеетsesstion_id, так что, по крайней мере, его можно соотнести с
Login
и Logout
- Примечание: Я еще не поймал это конкретное событие в дикой природе, поэтому у меня нет дальнейших комментариевоб этом.
Ни одно из этих событий не предоставляет IP-адрес клиента, но я приму имя хоста клиента в качестве разумной замены. Однако получение номера порта являетсяреальная проблема. Номер порта находится только в событии connection_accept
, и нет очевидного способа соотнести его с событием login
, которое имеет имя хоста. Короче говоря, кажется, что Extended Events просто не может доставить этобазовое сопряжение IP-адресов и портов клиента. Я хочу верить, что я не прав, потому что это такие элементарные данные. Любая помощь или предложения о том, что я пропускаю, будут высоко оценены.
Расширенное событие DDL
Вот 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
Альтернативы
Помимо расширенных событий, "аудит безопасности" - это еще один механизм , который не считается устаревшим.Поэтому я подумал, что я бы также попробовал:
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», «идентификатор сеанса» и имя пользователя (то есть «имя принципа сервера»).«).Тем не менее, нет никакого способа сопоставить это обратно с connection_accept
XEvent.Таким образом, нет способа извлечь две части информации, которые я хочу: IP-адрес клиента и номер порта.:(
Бонус
Помимо сбора IP-адреса и порта клиента, меня также интересует сбор трафика сетевого трафика SQL Server . Однако я еще не виделлюбой способ сделать это либо. Советы приветствуются! Я вижу только смутно связанные сообщения .
Обновление
Я заметил глобальное действие (поле) под названием task_address
, которое, по-видимому, связывает события login
, logout
и connection_accept
.Таким образом, теперь возможно найти IP и порт, комбинируя login:client_hostname
и connection_accept:port
.Меня беспокоит только то, что я не могу найти документацию для task_address
, чтобы подтвердить свои наблюдения.