如何在 SQL Server 中创建触发器来阻止特定 IP 地址的登录用户?

2024-01-09

我注意到大量定期从特定 IP 地址使用 SA 帐户进行登录尝试。我想使用 SQL 触发器或其他一些方法来根据用户的 IP 地址阻止这些用户访问数据库。

我能够创建一个数据库表来通过一个存储过程收集失败的尝试,我计划安排该存储过程每 10 分钟左右运行一次......

这是我的数据库表:

'''

USE [MASTER]
GO

CREATE TABLE [master].[dbo].[BLockedIPAddresses](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [ip] [varchar](50) NOT NULL,
    [attacked_on] [datetime2](2) NOT NULL,
    [banned_on] [datetime2](7) NOT NULL,
    [number_login_attempts] [int] NULL,
 CONSTRAINT [PK_BLockedIPAddresses] PRIMARY KEY CLUSTERED
([id] ASC)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON, FILLFACTOR = 80) ON [PRIMARY]) ON [PRIMARY]

ALTER TABLE [dbo].[BLockedIPAddresses] ADD  CONSTRAINT   [DF_BLockedIPAddresses_banned_on]  DEFAULT (getdate()) FOR [banned_on]


'''

然后,我创建了一个存储过程来更新并用尝试使用 SA 帐户登录的新 IP 填充数据库表。

'''

CREATE PROCEDURE [dbo].[sp_BLockedIPAddresses] 

AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    -- Insert statements for procedure here
-- [dbo].[BLockedIPAddresses]
DECLARE @T TABLE(LogDate datetime,ProcessInfo varchar(200),Text varchar(max))
    DECLARE @T2 TABLE(LogDate datetime,ProcessInfo varchar(200),IPAddress varchar(max))
    DECLARE @T3 TABLE(LogDate datetime,IPAddress varchar(max))
    DECLARE @IPAddress varchar(50),@LogDate datetime,@NumLoginAttempts int,@CmdExc varchar(300),@FailedLoginAttempts int=10

    BEGIN /* Get error log records with failed login attempt data */
        INSERT INTO @T
        EXEC sp_readerrorlog 0,1,'Password did not match that for the login provided'
        INSERT INTO @T
        EXEC sp_readerrorlog 1,1,'Password did not match that for the login provided'
        INSERT INTO @T
        EXEC sp_readerrorlog 2,1,'Password did not match that for the login provided'
        INSERT INTO @T
        EXEC sp_readerrorlog 3,1,'Password did not match that for the login provided'
        INSERT INTO @T
        EXEC sp_readerrorlog 4,1,'Password did not match that for the login provided'
        Select * from @T
        EXEC sp_readerrorlog 5,1,'Password did not match that for the login provided'
        Select * from @T
        EXEC sp_readerrorlog 6,1,'Password did not match that for the login provided'
        --Select * from @T
    END

    BEGIN /* Get the IP address from T*/
        INSERT INTO @T2
        SELECT LogDate,ProcessInfo,REPLACE(REPLACE( SUBSTRING(Text, PATINDEX ('%[0-9].%[0-9].%[0-9].[0-9]%',Text)-2,50),']',''),':','') FROM @T
    END

    BEGIN /* Get the NEW ip addresses from T2*/
        INSERT INTO @T3
        SELECT CONVERT(varchar(10),LogDate,101) LogDate,IPAddress from @T2 T
        WHERE NOT EXISTS(SELECT * FROM [master].[dbo].[BLockedIPAddresses] ai WHERE ai.ip=T.IPAddress)
        GROUP BY CONVERT(varchar(10),LogDate,101),IPAddress
        HAVING  COUNT(LogDate)>@FailedLoginAttempts
        ORDER BY IPAddress
    END

    BEGIN /* Validate that T3 has records, if not skip the firewall add */
        IF (SELECT COUNT(*) FROM @T3)=0
        BEGIN
            GOTO ExitWithoutCycle
        END
    END

    BEGIN /* Loop through T3 and add each entry to the windows firewall */
        WHILE EXISTS(SELECT * FROM @T3)
        BEGIN
            SELECT TOP(1) @LogDate=LogDate, @IPAddress=IPAddress FROM @T3
            SELECT @NumLoginAttempts=COUNT(*) FROM @T2 WHERE IPAddress=@IPAddress
                INSERT INTO [master].[dbo].[BLockedIPAddresses] (attacked_on,ip,number_login_attempts) VALUES(@LogDate,@IPAddress,@NumLoginAttempts)
                --SET @CmdExc = 'netsh advfirewall firewall add rule name="Autobanned IP - SQL Attacked '+@IPAddress+'" dir=in action=block enable="yes" remoteip='+@IPAddress+' protocol=any interfacetype=any'
                --EXEC master..xp_cmdshell @CmdExc
            DELETE @T3 WHERE IPAddress=@IPAddress
        END
    END
    /* sp_cycle_errorlog archives the current error log. */
    EXEC sp_cycle_errorlog
    ExitWithoutCycle:

END

'''

但是,这种方法对我不起作用。我仍然在数据库日志文件上看到登录尝试。

我可以获得可行的方法建议来减轻对服务器的这种安全攻击吗?


我喜欢这个想法,但除此之外,我建议首先执行以下操作:

  1. 始终禁用sa生产服务器上的帐户,创建单独的帐户sysadmin禁用之前对服务器的权限sa
  2. 避免将所有登录添加到sysadmin角色,可能需要登录db_owner特定数据库的权限,但不是整个服务器的权限。
  3. 在服务器上创建 WMI 警报,每当登录/角色/用户发生更改时,都会通过电子邮件通知。详细步骤在 SQL Server 上创建 WMI 警报 https://www.mssqltips.com/sqlservertip/5493/automated-wmi-alerts-for-sql-server-login-property-changes/
  4. 对 SQL Server 及其实例使用非标准端口(1433、1434 除外)
  5. 确保不需要的用户帐户没有添加到builtin\administrators运行 SQL 服务的服务器组
  6. 不确定它是否适用于您的环境,但最好避免暴露整个网络可访问的数据库服务器 IP,只要应用程序服务器能够访问数据库服务器就足够了。对于管理活动,用户必须通过应用程序服务器的网络/VLAN 访问数据库服务器
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 SQL Server 中创建触发器来阻止特定 IP 地址的登录用户? 的相关文章

随机推荐