审计SQL Server安全性的几种方式

日期: 2012-11-05 作者:Basit Farooq翻译:冯昀晖 来源:TechTarget中国 英文

随着业界安全管理要求的加强,微软正针对SQL Server建立更加安全并支持审计的功能。这些功能不只可以帮助DBA生成模式变更和安全相关事件的审计跟踪,还可以支持公司满足各种法规遵守的需求,并增强了企业数据和数据库基础架构的安全性。     登录审计   SQL Server登录审计是一种传统的审计形式,可以记录对服务器失败和成功的登录尝试。登录审计写到错误日志中。

  记录连接尝试可以用来获知谁在尝试连接数据库,是否发送了恶意攻击或者尝试攻击是否成功。   登录审计可以按如下方式配置: 在对象资源管理器中右击SQL Server,选择属性。点击安全。设置登录审计……

我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。

我原创,你原创,我们的内容世界才会更加精彩!

【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】

微信公众号

TechTarget微信公众号二维码

TechTarget

官方微博

TechTarget中国官方微博二维码

TechTarget中国

电子邮件地址不会被公开。 必填项已用*标注

敬请读者发表评论,本站保留删除与本文无关和不雅评论的权力。

随着业界安全管理要求的加强,微软正针对SQL Server建立更加安全并支持审计的功能。这些功能不只可以帮助DBA生成模式变更和安全相关事件的审计跟踪,还可以支持公司满足各种法规遵守的需求,并增强了企业数据和数据库基础架构的安全性。

    登录审计

  SQL Server登录审计是一种传统的审计形式,可以记录对服务器失败和成功的登录尝试。登录审计写到错误日志中。

  记录连接尝试可以用来获知谁在尝试连接数据库,是否发送了恶意攻击或者尝试攻击是否成功。

  登录审计可以按如下方式配置:

  • 在对象资源管理器中右击SQL Server,选择属性。
  • 点击安全。
  • 设置登录审计属性。可以选择:无审计,只记录失败登录,只记录成功登录,以及失败和成功登录都记录。
  • 点击确定然后重启SQL Server。

  C2审计和通用遵从准则

  你可以启用C2审计模式来记录访问语句和对象失败和成功的日志。C2审计模式保存了大量数据,所以日志文件很容易变得非常巨大。当文件达到200 MB时,SQL Server会打开一个新文件。如果记录日志的数据目录空间不足了,SQL Server会自动关闭记录功能。您可以按照如下方式启用C2审计模式:

  • 在对象资源管理器中右击SQL Server,选择属性。
  • 点击安全,然后选中“启用C2审计跟踪”。
  • 点击确定。

  当然,您也可以使用“sp_configure”来启动C2审计跟踪。

  请注意,虽然C2安全标准在SQL Server 2012中是可用的,但它将被通用遵从准则替代,而且可能将在未来的SQL Server版本中删除掉。

  通用遵从准则是一套审计标准,它仍然使用SQL Server跟踪捕获数据。通用遵从准则选项启用之后,登录审计也会启用。您可以按如下方式启用“通用遵从准则”:

  • 在对象资源管理器中右击SQL Server,然后选择属性。
  • 点击安全,然后选中C2审计跟踪。
  • 点击确定。

  SQL事件探测器跟踪安全审计事件,可以被用来跟踪任何对象访问和登录配置,以及安全事件。跟踪结果保存在跟踪文件或者数据库表中。

  数据定义语言(DDL)触发器

  DDL触发器可以用于把DDL信息和SQL Server有关安全的事件日志记录到表中。DDL事件日志记录提供给你审计和特权提升攻击的潜在警告(用户被赋予太多权限或者用户误用了他们的权限)。

  在定义触发器时,你可以指定作用域为服务器或者数据库。服务器作用域的触发器对服务器对象事件(比如登录对象)触发执行。数据库作用域的触发器响应数据库对象事件(比如,数据库模式,表和视图)触发。“EventData”函数提供关于DDL或者安全相关事件(引起DDL触发器被触发的事件)的明细信息。“EventData”函数返回类型为xml的值。该模式的差异与事件类型有关。

  下面的代码在服务器上创建了一个DDL触发器,将审计并存储在SQL Server上发生的所有连接和安全有关事件,结果会记录到master数据库的“SecurityLog ”表中。

  USE [master]
  GO
  DROP TABLE [dbo].[SecurityLog]
  GO
  CREATE TABLE [dbo].[SecurityLog](
  [EventType] [nvarchar](128) NULL,
  [EventTime] [datetime] NULL,
  [EventLog] [xml] NULL
  ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
  GO

  现在,创建一个DDL触发器(ddl_trig_capture_security_events)来捕获并存储所有连接和安全有关事件:

  USE [master]
  GO
  IF EXISTS (SELECT * FROM sys.server_triggers
  WHERE name = 'ddl_trig_capture_security_events')
  DROP TRIGGER ddl_trig_capture_security_events
  ON ALL SERVER;
  GO
  CREATE TRIGGER ddl_trig_capture_security_events
  ON ALL SERVER;
  FOR LOGON, DDL_SERVER_SECURITY_EVENTS,
  DDL_DATABASE_SECURITY_EVENTS
  AS
  INSERT INTO [master]..[SecurityLog] (EventType, EventTime, EventLog)
  SELECT EVENTDATA().value('(/EVENT_INSTANCE/EventType)[1]','nvarchar(128)')
  ,EVENTDATA().value('(/EVENT_INSTANCE/PostTime)[1]','datetime')
  ,EVENTDATA()
  GO
  Once the trigger has been created, you can test to see if it is working:
  USE [master]
  GO
  CREATE LOGIN [TestDDL] WITH PASSWORD=N'TestDDL'
  GO
  USE [AdventureWorks2012]
  GO
  CREATE USER [TestDDL] FOR LOGIN [TestDDL]
  GO
  ALTER ROLE [db_datareader] ADD MEMBER [TestDDL]
  GO
  GRANT EXECUTE ON [dbo].[uspGetBillOfMaterials] TO [TestDDL]
  GO

  点击xml查看所有事件日志:

点击xml查看所有事件日志

  下图展示了选择查看日志表时展示的结果:

选择查看日志表时展示的结果

  事件通知

  事件通知是在SQL Server 2005引入的,提供的功能是通过服务代理和队列收集非常具体的SQL跟踪,DDL和安全相关事件的子集。事件通知支持通过服务代理自动异步处理事件(在交易范围之外)。事件通知可以提供DDL触发器和SQL跟踪的编程替代。

  在下面的例子中,我们将使用事件通知审计并存储在SQL Server上出现的所有连接和安全相关事件。

 USE [msdb]
  GO
  --Creating queue
  CREATE QUEUE [SecurityEventsQueue]
  GO
  --Creating service for the queue
  CREATE SERVICE [//AdventureWorks.com/SecurityEventsService]
  AUTHORIZATION [dbo]
  ON QUEUE [dbo].[SecurityEventsQueue]
  ([http://schemas.microsoft.com/SQL/Notifications/PostEventNotification])
  GO
  --Creating route for the service
  CREATE ROUTE SecurityEventsRoute
  WITH SERVICE_NAME = '//AdventureWorks.com/SecurityEventsService',
  ADDRESS = 'LOCAL';
  GO
  --Creating Event Notification to capture connection and secrity-related events
  USE [msdb]
  GO
  CREATE EVENT NOTIFICATION NotifySecurityEvents
  ON SERVER
  FOR AUDIT_LOGIN,
  AUDIT_LOGOUT,
  AUDIT_LOGIN_FAILED,
  DDL_SERVER_SECURITY_EVENTS,
  DDL_DATABASE_SECURITY_EVENTS
  TO SERVICE '//AdventureWorks.com/SecurityEventsService' ,
  '9D584F73-1796-4494-ADC2-04BDD729FBCE';
  GO
  --Creating the service program that will process the event messages that is
  --generated via Event Notification objects
  IF EXISTS (SELECT * FROM [sys].[objects] WHERE [name] = 'sProcessSecurityEvents')
  DROP PROCEDURE [dbo].[sProcessSecurityEvents]
  GO
  CREATE PROC [dbo].[sProcessSecurityEvents]
  AS BEGIN
  SET NOCOUNT ON
  SET CONCAT_NULL_YIELDS_NULL ON
  SET ANSI_PADDING ON
  SET ANSI_WARNINGS ON
  BEGIN TRY
  DECLARE @message_body [xml]
  ,@EventTime [datetime]
  ,@EventType [varchar](128)
  ,@message_type_name [nvarchar](256)
  ,@dialog [uniqueidentifier]
  -- Endless loop
  WHILE (1 = 1)
  BEGIN
  BEGIN TRANSACTION ;
  -- Receive the next available message
  WAITFOR (RECEIVE TOP(1)
  @message_type_name = [message_type_name],
  @message_body = [message_body],
  @dialog = [conversation_handle]
  FROM [dbo].[SecurityEventsQueue]), TIMEOUT 2000
  -- Rollback and exit if no messages were found
  IF (@@ROWCOUNT = 0)
  BEGIN
  ROLLBACK TRANSACTION;
  BREAK;
  END;
  -- End conversation of end dialog message
  IF (@message_type_name = 'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog')
  BEGIN
  PRINT 'End Dialog received for dialog # ' + CAST(@dialog as [nvarchar](40));
  END CONVERSATION @dialog;
  END;
  ELSE
  BEGIN
  SET @EventTime = CAST(CAST(@message_body.query('/EVENT_INSTANCE/PostTime/text()') AS [nvarchar](max)) AS [datetime])
  SET @EventType = CAST(@message_body.query('/EVENT_INSTANCE/EventType/text()') AS [nvarchar](128))
  INSERT INTO [master]..[SecurityLog] ([EventType], [EventTime], [EventLog])
  VALUES (@EventType, @EventTime, @message_body)
  END
  COMMIT TRANSACTION
  END --End of loop
  END TRY
  BEGIN CATCH
  SELECT ERROR_NUMBER()
  ,ERROR_SEVERITY()
  ,ERROR_STATE()
  ,ERROR_PROCEDURE()
  ,ERROR_LINE()
  ,ERROR_MESSAGE()
  END CATCH
  END
  GO
  --Once service program is created successfully, execute the following script to
  --activate our service broker queue and reference this Service Program stored procedure:
  ALTER QUEUE [dbo].[SecurityEventsQueue]
  WITH STATUS = ON
  ,ACTIVATION (PROCEDURE_NAME = [sProcessSecurityEvents]
  ,STATUS = ON
  ,MAX_QUEUE_READERS = 1
  ,EXECUTE AS OWNER)
  GO

  事件通知是在SQL Server 2005引入的,提供的功能是通过服务代理和队列收集非常具体的SQL跟踪,DDL和安全相关事件的子集。事件通知支持通过服务代理自动异步处理事件(在交易范围之外)。事件通知可以提供DDL触发器和SQL跟踪的编程替代。

  现在,测试一下事件通知设置,然后检查“SecurityLog”表的输出信息。

  SQL Server 审计

  我们还可以使用SQL Server审计跟踪安全相关事件。SQL Server审计是SQL Server企业版功能,自SQL Server 2008之后才有的。SQL Server审计使用扩展事件帮助执行审计。

  例如:我们将创建针对所有安全相关事件的审计。要实现这个目的,我们首先要创建基于文件的服务器审计规范,我们将把它用作我们的服务器审计规范。

  USE [master]
  GO
  CREATE SERVER AUDIT [Audit-SecurityEvents]
  TO FILE
  ( FILEPATH = N'D:Demo_SQLAudit'
  ,MAXSIZE = 200 MB
  ,MAX_ROLLOVER_FILES = 2147483647
  ,RESERVE_DISK_SPACE = OFF )
  WITH
  ( QUEUE_DELAY = 1000
  ,ON_FAILURE = CONTINUE )
  GO

  我们现在将创建审计规范来审计服务器和数据库安全相关事件,比如登录密码修改,数据库用户或者对象权限修改,失败的登录尝试和服务器策略改变:

  CREATE SERVER AUDIT SPECIFICATION [ServerAuditSpecification]
  FOR SERVER AUDIT [Audit-SecurityEvents]
  ADD (LOGIN_CHANGE_PASSWORD_GROUP),
  ADD (DATABASE_PRINCIPAL_CHANGE_GROUP),
  ADD (DATABASE_OBJECT_PERMISSION_CHANGE_GROUP),
  ADD (FAILED_LOGIN_GROUP),
  ADD (SERVER_PRINCIPAL_CHANGE_GROUP)
  GO

  要测试你的审计规范,你可以产生一些事件,然后查看审计文件,以确认这些事件已经被审计到了。请看下图:

审计SQL Server安全性的几种方式

作者

Basit Farooq
Basit Farooq

资深数据库管理员、培训师和技术撰稿人,具有十多年微软SQL Server平台的开发、技术培训和数据库管理的经验。

相关推荐