我希望限制连接到我的 SQL Server 实例的 IP 地址,只允许来自特定 IP 列表的连接,防止其他任何 IP 地址的连接。这是否可以在 SQL Server 实例或数据库中进行配置?
我希望限制连接到我的 SQL Server 实例的 IP 地址,只允许来自特定 IP 列表的连接,防止其他任何 IP 地址的连接。这是否可以在 SQL Server 实例或数据库中进行配置?
听起来像是可以使用 Windows 防火墙 (您可以阻止 SQL Server 端口,并允许某些 IP 地址的例外)完成此操作。
您可以使用诸如 登录触发器 对 IP 地址进行检查,但我认为与其直接阻止流量相比,这是一个不太理想的选择。
在数据库层面上实现会更加困难。
Create the table to store banned IP addresses
/* 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]
Create the process to auto add IP addresses to the firewall. Personally I placed this code in an Agent Job running every 10 minutes. Also note that this process utilizes xp_cmdshell. I certainly don't want to debate the merits of enabling or disabling this functionality. To each their own, but my script won't work without this functionality. If you don't have it enabled here is a good link to help you.
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:
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
我期待能够收到改进这个功能的评论。
我想你可以编写一个登录触发器,就像这里所描述的那样,检查他们从哪里登录,但我建议最好使用防火墙。