将SQL Server连接限制为特定的IP地址

时间:2011-08-19 21:25:08

标签: sql sql-server security sql-server-2005 sql-server-2008

我想将与SQL Server实例的连接限制为特定的IP地址。我想阻止除特定列表之外的任何IP地址的任何连接。这是可以在SQL Server实例或数据库中配置的吗?

4 个答案:

答案 0 :(得分:22)

听起来像是使用Windows firewall做的事情(你可以阻止SQL Server端口,并允许某些IP地址的例外)。

你可以使用logon trigger这样的东西来检查使用sys.dm_exec_connections的IP地址,但我认为这比直接阻止流量更不可取。

在数据库级别当然要做得更加艰难。

答案 1 :(得分:19)

我写了这个功能,以自动禁止从同一IP地址尝试登录多于X( @FailedLoginAttempts )的IP地址。它基于SQL Server错误日志。我正在运行Windows Server 2008和SQL Server 2008 R2。

请注意,如果您暂时没有重新启动SQL Server错误日志,则可能会获得大量IP地址,并且可能需要一些时间来处理所有内容。每运行10分钟,整个过程大约需要4-5秒。

步骤

  1. 确保您记录失败的尝试。在SQL Server Management Studio(SSMS)中右键单击您的实例(在数据库上方)属性安全性登录审核。确保单击[仅登录失败] ||的单选按钮[选中失败和成功登录]。
  2. 创建表以存储禁止的IP地址

    /* Create table to store banned IP addresses */
    USE [YourDB]
    GO
    
    CREATE TABLE [dbo].[autobanned_ipaddesses](
        [id] [int] IDENTITY(1,1) NOT NULL,
        [ipaddress] [varchar](50) NOT NULL,
        [attacked_on] [datetime2](2) NOT NULL,
        [banned_on] [datetime2](7) NOT NULL,
        [number_login_attempts] [int] NULL,
     CONSTRAINT [PK_autobanned_ipaddesses] 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].[autobanned_ipaddesses] ADD  CONSTRAINT   [DF_autobanned_ipaddesses_banned_on]  DEFAULT (getdate()) FOR [banned_on]
    
  3. 创建自动将IP地址添加到防火墙的过程。我个人将此代码放在每10分钟运行一次的代理作业中。另请注意,此过程使用 xp_cmdshell 。我当然不想辩论启用或禁用此功能的优点。对于他们自己,但我的脚本将无法使用此功能。如果你没有启用它here是一个很好的链接来帮助你。

    USE [YourDB]
        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,'Could not find a login matching the name provided'
            INSERT INTO @T
            EXEC sp_readerrorlog 0,1,'An error occurred while evaluating the password'
        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 autobanned_ipaddesses ai WHERE ai.ipaddress=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 autobanned_ipaddesses (attacked_on,ipaddress,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:
    
  4. 据我所知,这不是一个完美的解决方案,因为它只适用于IPv4 IP地址,只能查看通过端口1433进行的登录尝试,具体取决于您的配置。然而,它帮助我在一周左右的时间内识别并阻止了100多个IP地址(主要是中国和香港,但我确实阻止了国土安全部)。

    TANGENT - 一旦我运行了一个星期左右,我很快就意识到IP地址的净范围中有相当多的模式。我发现this tool最有助于确定这些命中的来源和位置。关于这个网站的好处是,一旦你获得IP地址的位置,在下面你可以再次输入IP地址并获得IP地址的净范围。例如(对不起中国),我发现59.53.67.13的净范围是59.0.0.0 - 59.255.255.255。话虽这么说,我创建了一个手动功能来阻止整个网络范围并删除任何已包含此范围内IP地址的Windows防火墙规则。

        USE [YourDB]
    
        DECLARE @CmdExc varchar(300)
        DECLARE @NetRange varchar(50)='59.0.0.0 - 59.255.255.255'
    
        DECLARE @NetRangeFrom varchar(20),@NetRangeTo varchar(20),@IPAddress varchar(20)
        DECLARE @IPPart2From int,@IPPart2To int
        DECLARE @IPPartSearch2From int,@IPPartSearch2To int
    
        DECLARE @T Table (ipaddress varchar(20))
    
        SET @NetRange=REPLACE(@NetRange,' ','')
        SELECT @NetRangeFrom=LTRIM(RTRIM(SUBSTRING(@NetRange,1,CHARINDEX('-',@NetRange)-1)))
        SELECT @NetRangeTO=LTRIM(RTRIM(SUBSTRING(@NetRange,CHARINDEX('-',@NetRange)+1,50)))
        SELECT @IPPartSearch2From=CAST(PARSENAME(@NetRangeFrom,3) as int)
        SELECT @IPPartSearch2To=CAST(PARSENAME(@NetRangeTo,3) as int)
    
        INSERT INTO @T
        select ai.ipaddress from autobanned_ipaddesses ai where LTRIM(ai.ipaddress) like SUBSTRING(@NetRangeFrom,1,CHARINDEX('.',@NetRangeFrom,1))+'%' AND PARSENAME(LTRIM(RTRIM(ai.ipaddress)),3) BETWEEN @IPPartSearch2From AND @IPPartSearch2To
    
        SET @CmdExc = 'netsh advfirewall firewall add rule name="AB SQL Attacked '+@NetRange+'" dir=in action=block enable="yes" remoteip='+@NetRange
        EXEC master..xp_cmdshell @CmdExc
        WHILE EXISTS(SELECT * from @T)
        BEGIN
            SELECT TOP(1) @IPAddress=ipaddress from @T
            SET @CmdExc = 'netsh advfirewall firewall delete rule name="Autobanned IP - SQL Attacked '+@IPAddress+'"'
            EXEC master..xp_cmdshell @CmdExc
            DELETE TOP(1) FROM @T
        END
    

    我期待能够改进此功能的评论。

答案 2 :(得分:1)

我想您可以编写一个登录触发器,如here所述,它会检查他们从哪里登录,但我建议使用防火墙会更好。

答案 3 :(得分:1)

  1. 使用像Baracuda或F5这样的外部防火墙 - 最佳选项,以减少Windows服务器上的负载。
  2. Windows防火墙设置 - 如果无法执行上述操作,请设置传入防火墙设置并打开端口1433,然后在“远程计算机”选项卡中输入源IP地址。
  3. 在SQL Server网络级别 - SQL Server网络配置*→高级接受的NTLM SPN 。在此处添加域名。
  4. 使用触发器
  5. 关注Matt Smith's procedure
相关问题