El rincón de JMACOE

Seguridad de los inicios de sesión en el Sql Server

En un anterior post hable acerca como bloquear el inicio de sesión desde IP especificos. En este post voy a detallar más lo que podemos hacer con esta poderosa tecnica. Resulta muy util pues aunque se sepan las credencias (usuario/password) el intento de inicio de sesión se rechazara de no cumplir la condición.

Bloquear un host mediante su nombre

En las redes windows se estila usar nombre de host, el cual es independiente de los números IPs. Para rechazar intentos de conexion desde nombres de hosts especificos podemos usar el siguientes script:

USE master;
GO
CREATE TRIGGER connection_lock_trigger
ON ALL SERVER
FOR LOGON AS
BEGIN
   DECLARE @HostName Varchar(MAX)
   SET @HostName = HOST_NAME()
   IF @HostName IN ('NombreDeHost1' , 'NombreDeHost2')
   BEGIN
       ROLLBACK TRANSACTION;
       PRINT 'Esta credencial no se puede usar desde el host ' + @HostName
   END
END;

Limitar la cantidad de veces que se puede iniciar sesión

Profundizamos un poco más en el nivel de seguridad, ahora vamos a realizar un conteo de cuantas sesiones abiertas existen para rechazar las conexiones entrantes. En este ejemplo el inicio de sesión es ‘login_text’ y solo permite 3 conexiones como máximo.

USE master;
GO
CREATE TRIGGER connection_limit_trigger
ON ALL SERVER 
FOR LOGON
AS
BEGIN
    IF ORIGINAL_LOGIN()= 'login_test' AND
        (SELECT COUNT(*) FROM sys.dm_exec_sessions
         WHERE is_user_process = 1 AND
         original_login_name = 'login_test') > 3
    BEGIN
        ROLLBACK TRANSACTION;
        PRINT 'Lo siento solo se permiten 3 conexiones para ''login_text'''
    END
END;

Fijar el inicio de sesion desde un solo origen

Para lograr esto con toda la seguridad posible, tenemos que usar la combinación de 3 elementos: nombre de host, ip e inicio de sesión.
Esta técnica es útil por ejemplo cuando queremos que el inicio de sesión se use solamente para conexiones entre servidores. Y es util por que aun cuando se haya filtrado la credencial esta no podrá ser utilizada por nadie mas.

USE master;
GO
CREATE TRIGGER connection_server_trigger
ON ALL SERVER 
FOR LOGON
AS
BEGIN
    DECLARE @HostName Varchar(MAX)
    DECLARE @IP Varchar(500)
    
    SET @IP = EVENTDATA().value('(/EVENT_INSTANCE/ClientHost)[1]', 'varchar(500)')
    SET @HostName = HOST_NAME()

    IF ORIGINAL_LOGIN()= 'login_test' 
    BEGIN
        IF NOT (@HostName IN ('NombreDeHost1','NombreDeHost2') AND
                    @IP IN ('172.16.255.11', '172.20.254.1', '172.26.254.12')
                   )
        BEGIN
            ROLLBACK TRANSACTION;
            PRINT 'Lo siento pero ''login_text'' es de uso exclusivo para conexión entre servidores'
        END
    END
END;

Recomendaciones

Comparte y diviertete: