Wednesday, July 18, 2012

SQL Server: Restrict Login from Valid Machine IPs Only (Using Logon Trigger)


Today, I have practically learned how to stop valid database users to login on SQL Server instance from invalid machines (IPs).
Process is very simple. Just create a Logon Trigger and check if login user is coming from valid IP or not. If not, then just kick him out.

Download Script
USE master
GO
-- Create table to hold valid IP values
CREATE TABLE ValidIPAddress (IP NVARCHAR(15)
CONSTRAINT PK_ValidAddress PRIMARY KEY)

-- Declare local machine as valid one
INSERT INTO ValidIPAddress
SELECT '<local machine>'
-- Create Logon Trigger to stop logins from invalid IPs
CREATE TRIGGER tr_LogOn_CheckIP ON ALL SERVER
    FOR LOGON
AS
    BEGIN
        DECLARE @IPAddress NVARCHAR(50) ;
        SET @IPAddress = EVENTDATA().value('(/EVENT_INSTANCE/ClientHost)[1]',
                                           'NVARCHAR(50)') ;
        IF NOT EXISTS ( SELECT  IP
                        FROM    master..ValidIPAddress
                        WHERE   IP = @IPAddress )
            BEGIN
            -- If login is not a valid one, then undo login process
                SELECT  @IPAddress
                ROLLBACK --Undo login process
            END

    END
Once trigger is created, you can find it under Server Objects -- > Triggers tab


From invalid IP, which you have not added in secure list will see following error on log-in attempt.

17 comments:

  1. This is excellent blog post - I indeed learning something new today. Thanks Aasim.

    ReplyDelete
  2. Thanks Guru... You are my inspiration

    ReplyDelete
  3. Great. But could we restrict both user and IP ? Like MySQL.
    How can we allow Bob login any where, Jack login only with IP 1.2.3.4

    ReplyDelete
  4. Thank you nice article , how can we restricte using userID and IP ?

    ReplyDelete
    Replies
    1. Script already handling IP case, and for User use "/EVENT_INSTANCE/LoginName)[1]"

      Delete
    2. What about for program name?

      Delete
  5. Hey, aasim

    i have a question ,actually i am working on oracle pl/sql, so i wanna ask you something regarding trigger, is that any possibility that we have made a trigger which works on time event or time restriction like at that particular time trigger have to give restriction that user can't perform any DML or DDL event.

    But accidentally or intentionally another user has used some modification by logging at that particular time ,now the thing is how should we find that which user has done this modification. can you write a trigger or give some idea?

    ReplyDelete
    Replies
    1. Sorry for late reply. As you described, if I would like same scenario for SQL Server, I would like to create two Job (using SQL Server Agent) which will execute my TSQL script to REVOKE or GRANT permissions to users according to requirements.

      Delete
  6. Can we redistrict particular user for specific ip addrss,
    e.g we have one db user abcd and i would like to restrict ip address for abcd user so abcd user only can have access from specified ip address,but other db user can access db from any ip address.

    ReplyDelete
  7. hi Assim,

    How can check the sa login details if the user connect the SQL instance name and login with sa, I want to view [EventType],[PostTime],[ServerName] ,[LoginName] ,[LoginType] ,[ClientHostName], [Ipaddress],[databasename],[tablename]

    ReplyDelete
  8. how can i can delete the trigger, now in my pc I am not able to login with sa, it give error on your attach screen

    ReplyDelete
  9. The good news is that VPN services don't differentiate, and no matter where you're from, you can get an IP address from just about any other place. VPN For British IPs

    ReplyDelete
  10. but i need to restrict only for 1 user like this.
    Ex: If my user is some abc then only i need check the IP ned if it is white listed we need to allow.

    ReplyDelete
  11. Great solution simple and superb. Great job

    ReplyDelete
  12. Hi.. this is interesting and very useful, one thing I'd like to ask is there any way I can print custom message for this Trigger? Thanks

    ReplyDelete

All suggestions are welcome