web-dev-qa-db-ja.com

SQL Server接続を特定のIPアドレスに制限する

SQL Serverインスタンスへの接続を特定のIPアドレスに制限したい。特定のリスト以外のIPアドレスからの接続を禁止したい。これは、SQL Serverインスタンスまたはデータベースで構成できるものですか?

17
mohammedn

Windowsファイアウォール を使用した場合のように聞こえます(SQL Serverポートをブロックし、特定のIPアドレスの例外を許可できます)。

これは、sys.dm_exec_connectionsを使用してIPアドレスをチェックする ログオントリガー のようなもので実行できますが、トラフィックを完全にブロックするよりもはるかに望ましいオプションではないと思います。

確かに、データベースレベルで行うのははるかに困難です。

22
Aaron Bertrand

この機能を記述して、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:
    

これは完全なソリューションではないことを理解しています。これはIPv4 IPアドレスでのみ機能し、構成に応じておそらくポート1433を介して行われたログイン試行のみを確認するためです。ただし、1週間程度で100を超えるIPアドレスを識別してブロックすることができました(主に中国と香港ですが、国土安全保障省)をブロックしました。

[〜#〜] tangent [〜#〜]-これを1週間ほど実行すると、かなりのパターンがIPアドレスのネット範囲。私は このツール が、誰がどこでこれらのヒットが発生しているかを特定するのに最も役立つことがわかりました。このWebサイトの優れている点は、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

この機能を改善するコメントをお待ちしています。

20
Matt Smith
  1. Windowsサーバーの負荷を軽減するために、BaracudaやF5などの外部ファイアウォールを使用する-最適なオプション。
  2. Windowsファイアウォール設定-上記を実行できない場合は、受信ファイアウォール設定を設定し、ポート1433を開いて、[リモートコンピューター]タブでソースIPアドレスを入力します。
  3. SQL Serverネットワークレベル-SQL Serverネットワーク構成*→詳細受け入れられたNTLM SPN。ここにドメイン名を追加します。
  4. 従う マット・スミスの手順 トリガー付き
1
Ashburn RK

説明されているように、ログオントリガーを記述できると思います here ログイン元を確認しますが、ファイアウォールを使用することをお勧めします。

1
Hans Olsson