Ein Kunde kam mit einer Anforderung auf uns zu, den Zugriff zu einen Microsoft SQL Server zu limitieren. Die Einschränkung sollte aber nicht auf einem Anmeldenamen basieren, sondern auf dem Namen bestimmter Applikationen. Die Einschränkung sieht vor, dass ausgewählte Mitarbeiter des Entwicklungsteams mit Hilfe von Microsoft SQL Server Management Studio auf den Server zugreifen dürfen, während das Business nur mit Hilfe einer selbst entwickelten Applikation auf die Daten des Microsoft SQL Servers zugreifen dürfen. Auf dem ersten Blick scheint es hierfür keine Lösung zu geben; aber seit der Version von Microsoft SQL Server 2005 (SP2) gibt es die Möglichkeit, LOGON Trigger zu verwenden.

Was sind LOGON Trigger?

Logon-Trigger lösen eine Reaktion als Antwort auf ein LOGON-Ereignis aus, wenn eine Benutzersitzung mit einer Instanz von SQL Server erstellt wird und nachdem die Authentifizierungsphase der Anmeldung abgeschlossen ist. Aus diesem Grund werden alle Meldungen, die aus dem Trigger stammen und normalerweise den Benutzer erreichen (z. B. Fehlermeldungen und Meldungen aus der PRINT-Anweisung) zum SQL Server Fehlerprotokoll umgeleitet.

Business Case

Die Anforderungen im vorliegenden Fall sind trivial: Alle Mitarbeiter dürfen mittels einer Applikation auf die Datenbanken in Microsoft SQL Server zugreifen. Für gelegentliche Tests / Fehlersuche ist es einem kleinen Kreis von Entwicklern gestattet, mit Hilfe von Microsoft SQL Server Management Studio unmittelbar auf den Datenbankserver zuzugreifen. Da die berechtigten Anwender von jedem ihnen zur Verfügung stehenden Computer auf die Datenbanken zugreifen müssen, ist eine Zugriffsbeschränkung über IP-Adressen nicht möglich. Ebenfalls wurde von Seiten des Kunden der Zugang über einen Jumphost aus internen Gründen wieder verworfen worden.

Lösung

Als Lösung kommt ein LOGON-Trigger zum Tragen, der nach der Anmeldung überprüft, mit welcher Applikation der Anwender auf den Datenbankserver zugreifen möchte. Da ein LOGON-Trigger immer erst NACH der Anmeldung ausgeführt wird, sind Sitzungsdetails bereits in der Systemview [sys].[dm_exec_sessions] gespeichert worden. Mit Hilfe dieser Informationen lässt sich auslesen, mit welchem Programm der Benutzer auf den Datenbankserver zugreift.

SELECT session_id,
       host_name,
       program_name
FROM   sys.dm_exec_sessions
WHERE  is_user_process = 1
       AND session_id = @@SPID;

Die Abfrage liefert für die aktuelle Sitzung neben der Session ID und den Hostnamen noch das Attribut [program_name]. In diesem Attribut wird in der Regel der Programmname gespeichert. Leider ist damit jedoch ein kleiner Nachteil verbunden, der weiter unten beschrieben wird.
Program Name of active session

Wenn ein Zugang mit Hilfe von Microsoft SQL Server Management Studio initiiert wird, so wird der Name des Programms in der Verbindung mit übermittelt. Somit kann identifiziert werden, wenn jemand versucht, sich mit Hilfe von SSMS auf den Server zu verbinden. Da nur einem begrenzter Kreis von Mitarbeitern diese Option zur Verfügung steht, wird zunächst eine Sicherheitsrolle [SSMSAccess] als Serverrolle eingerichtet. Alle Mitarbeiter (Domänenkonten, Domänengruppen, SQL Konten), die Mitglied dieser Gruppe oder sysadmin sind, erhalten mittels SSMS einen Zugang zum Microsoft SQL Server. Der Versuch anderer Mitarbeiter wird abgelehnt.

CREATE SERVER ROLE [SSMSAccess] AUTHORIZATION [sa];

Jeder Anwender, der einen Zugang mittels SSMS erhalten soll, muss Mitglied dieser Serverrolle sein!

Im Anschluss wird ein Servertrigger implementiert, der den Wert in program_name für die aktive session_id überprüft.

CREATE TRIGGER connection_application
ON ALL SERVER
FOR LOGON
AS
BEGIN
    IF EXISTS
    (
        SELECT * FROM sys.dm_exec_sessions
        WHERE  session_id = @@SPID
        AND PROGRAM_NAME() LIKE '%SQL Server Management Studio%'
        AND
        (
            IS_SRVROLEMEMBER(N'SSMSAccess') = 0
            AND IS_SRVROLEMEMBER(N'sysadmin') = 0
        )
    )
    BEGIN
        RAISERROR (N'You are not allowed to connect to this server with SSMS!', 11, 1) WITH NOWAIT;
        ROLLBACK;
    END
END;
GO

Will ein Benutzer mit SQL Server Management Studio auf den Server zugreifen, muss er entweder Mitglied der benutzerdefinierten Serverrolle oder aber sysadmin sein. Ansonsten wird mittels RAISERROR ein Eintrag im Fehlerprotokoll von SQL Server hinterlassen.

login_test_no_access

Der Benutzer mit dem Anmeldenamen [login_test] ist weder Mitglied der Gruppe [SSMSAccess] noch sysadmin. Aus diesem Grund schlägt die Anmeldung fehl.

Failed_Login

Hintertür?

Diese Möglichkeit der Kontrolle mag auf den ersten Blick gut sein. Dennoch gibt es eine Hintertür, mit der man dennoch in das System gelangt. Das Problem ist der “Connection String”, der von einer Applikation generiert wird, wenn eine Verbindung zum Microsoft SQL Server aufgebaut wird. Die nachfolgende Abbildung zeigt den Connection String, der von Microsoft Access generiert wird, wenn ein Zugriff auf die Datenbank erfolgt:

Access-ConnectionString

Die Option “APP” wird von Microsoft SQL Server als [program_name] in sys.dm_exec_sessions hinterlegt.

Program Name of Access Session

Dieser Teil des Connection String kann manipuliert werden! In Microsoft SQL Server Management Studio können die Elemente der Verbindungszeichenfolge explizit angegeben werden. Dadurch lässt sich der [program_name] manipulieren und ein Zugang wäre möglich.

Manipulation Verbindungszeichenfolge

Herzlichen Dank fürs Lesen!