Partager via


Sécurité du gouverneur de ressources

Le gouverneur de ressources utilise des mécanismes de sécurité SQL Server existants tels que l'authentification, les niveaux d'autorisation et les chaînes de propriétés. Cette rubrique identifie les aspects de la configuration et de l'utilisation du gouverneur de ressources que vous devez prendre en considération afin de parer aux problèmes de sécurité potentiels.

Éléments à prendre en considération

Les éléments ci-dessous de conception et d'implémentation du gouverneur de ressources doivent être pris en considération pour assurer une utilisation aussi sûre que possible de cette fonctionnalité.

  • Autorisations

  • Noms du pool de ressources et du groupe de charge de travail

  • Fonction classifieur définie par l'utilisateur

Autorisations

Les autorisations suivantes sont requises pour la modification ou la consultation des paramètres du gouverneur de ressources :

  • Pour modifier la configuration du gouverneur de ressources, un utilisateur doit disposer de l'autorisation CONTROL SERVER. Les autorisations sont vérifiées lors de l'exécution de n'importe quelle instruction DDL du gouverneur de ressources.

  • Pour consulter la configuration active fournie par les vues de gestion dynamique, un utilisateur doit disposer de l'autorisation VIEW SERVER STATE.

Nous vous recommandons de confier la possibilité de créer ou de modifier la configuration du gouverneur de ressources à des administrateurs de base de données expérimentés.

Noms du pool de ressources et du groupe de charge de travail

Tous les noms de pools de ressources et de groupes de charge de travail sont exposés au public. Par conséquent, lors de la création des pools et des groupes, veillez à choisir des noms qui ne divulguent pas d'informations sur la nature des applications que vous exécutez sur le serveur. Par exemple, un groupe de charge de travail nommé SalairesEntreprise fournit une indication évidente de la nature et du caractère essentiel des applications qui utilisent le groupe de charge de travail.

Fonction classifieur définie par l'utilisateur

La fonction classifieur définie par l'utilisateur est stockée dans la base de données MASTER.

Cette fonction est semblable aux déclencheurs LOGON dans sa conception et son implémentation et s'exécute après les déclencheurs LOGON dans le cadre du processus de connexion. La fonction s'exécute dans le contexte de connexion de la session qui fait une demande et la classification doit être terminée pour qu'une session puisse réellement être établie. Par conséquent, tous les messages provenant de la fonction classifieur et normalement destinés à l'utilisateur (les messages et les messages d'erreur de l'instruction PRINT, par exemple), sont dirigés vers le journal des erreurs SQL Server.

AttentionAttention

Bien que cette version du gouverneur de ressources implémente la liaison au schéma pour limiter les appels pouvant être émis depuis la fonction classifieur définie par l'utilisateur, toutes les données retournées par cette fonction ne sont pas nécessairement sécurisées. Pour plus d'informations, consultez Considérations sur l'écriture d'une fonction classifieur.

Notez les aspects suivants du comportement de la fonction classifieur définie par l'utilisateur :

  • Le gouverneur de ressources exécute cette fonction dans le cadre de la classification dans le contexte de l'utilisateur par défaut de la connexion ou en tant qu'utilisateur désigné si EXECUTE AS est spécifié dans la fonction.

  • Lorsque le gouverneur de ressources exécute cette fonction dans le cadre de la classification, il ne vérifie pas l'autorisation EXECUTE sur la fonction classifieur définie par l'utilisateur. Toutefois, tous les objets référencés par la fonction sont soumis à des vérifications standard des autorisations, ce qui, selon les chaînes de propriétés, peut autoriser l'accès.

  • L'enregistrement d'une fonction en tant que classifieur du gouverneur de ressources n'affecte pas ses niveaux d'autorisation dans le cadre d'une utilisation hors de portée de la classification du gouverneur de ressources.

Chaînes de propriétés dans le gouverneur de ressources

Pour accorder à un utilisateur l'accès à un schéma alors que la classification du gouverneur de ressources est en cours, vous pouvez vous appuyer sur le chaînage des propriétés basé sur le schéma ou utiliser EXECUTE AS. L'exemple de code et les commentaires ci-dessous illustrent le fonctionnement du chaînage des propriétés dans le gouverneur de ressources.

[!REMARQUE]

L'exemple ci-dessous suppose que les connexions SQL sont activées.

Le code ci-dessous crée des utilisateurs du schéma (SchemaUser1 et SchemaUser2) qui ont accès à master.

use master
go

CREATE LOGIN SchemaUser1 WITH PASSWORD='your password here';
CREATE USER SchemaUser1 FOR LOGIN [SchemaUser1];
CREATE LOGIN SchemaUser2 WITH PASSWORD='your password here';
CREATE USER SchemaUser2 FOR LOGIN [SchemaUser2];
go

Le code ci-dessous crée un utilisateur (NormalUser1) qui dispose des autorisations de connexion par défaut.

CREATE LOGIN NormalUser1 WITH PASSWORD='your password here';
CREATE USER NormalUser1 FOR LOGIN [NormalUser1];
go

Le code ci-dessous crée des schémas (Schema1 et Schema2) et les mappe aux utilisateurs de schémas créés. Il crée également une table (groupTable) pour les schémas.

CREATE SCHEMA Schema1 AUTHORIZATION SchemaUser1
CREATE TABLE groupTable (uname sysname, gname sysname);
CREATE SCHEMA Schema2 AUTHORIZATION SchemaUser2
CREATE TABLE groupTable (uname sysname, gname sysname);
go

Le code ci-dessous ajoute des valeurs à groupTable.

INSERT Schema1.groupTable VALUES(N'NormalUser1',N'Group1');
INSERT Schema2.groupTable VALUES(N'NormalUser1',N'Group2');
go

À ce stade, Schema1 et Schema2 appartiennent respectivement à SchemaUser1 et SchemaUser2. L'exemple de code ci-dessous crée une fonction qui sera utilisée pour accéder à Schema1 et Schema2.

CREATE FUNCTION Schema1.classifier() RETURNS sysname WITH SCHEMABINDING AS
BEGIN
      DECLARE @n sysname
      SELECT @n = gname FROM Schema1.groupTable WHERE uname = SUSER_NAME()
      SELECT @n = gname FROM Schema2.groupTable WHERE uname = SUSER_NAME()
      RETURN @n
END
go

Le code ci-dessous enregistre la fonction précédente en tant que fonction classifieur définie par l'utilisateur. Notez que SchemaUser1 n'a pas d'autorisation d'accès à Schema2.

ALTER RESOURCE GOVERNOR WITH (CLASSIFIER_FUNCTION=Schema1.classifier);
ALTER RESOURCE GOVERNOR RECONFIGURE
go

À titre de test, essayez de vous connecter en tant que NormalUser1 à partir d'une autre connexion cliente. Ouvrez l'Observateur d'événements Windows. Le journal d'applications doit contenir une entrée relative à l'échec du classifieur. NormalUser1 hérite des droits d'accès pour Schema1.groupTable par chaînage des propriétés de Schema1.classifier. Toutefois, Schema1 n'a pas d'autorisation d'accès à Schema2.groupTable.

Effectuez un nouveau test en accordant l'autorisation SELECT à SchemaUser1 pour Schema2.groupTable. 

GRANT SELECT ON Schema2.groupTable TO SchemaUser1
go

Connectez-vous en tant que NormalUser1. Cette fois encore, vous constaterez dans le journal des événements la présence d'une entrée relative à l'échec du classifieur. La cause de cet échec est la vérification effectuée par le serveur pour déterminer si NormalUser1 dispose de l'autorisation SELECT, qui n'est pas héritée de SchemaUser1.

L'exemple de code ci-dessous crée une autre fonction classifieur. Cette fois, les connexions disposent de l'autorisation EXECUTE AS SchemaUser1.

CREATE FUNCTION Schema1.classifier2() RETURNS sysname WITH SCHEMABINDING, EXECUTE AS 'SchemaUser1' AS
BEGIN
      DECLARE @n sysname
      SELECT @n = gname FROM Schema1.groupTable WHERE uname = SUSER_NAME()
      SELECT @n = gname FROM Schema2.groupTable WHERE uname = SUSER_NAME()
      RETURN @n
END
go

ALTER RESOURCE GOVERNOR WITH (CLASSIFIER_FUNCTION=Schema1.classifier2);
ALTER RESOURCE GOVERNOR RECONFIGURE;
go

Dans la mesure où la nouvelle fonction s'exécute dans le contexte de SchemaUser1 et où SchemaUser1 a l'autorisation SELECT sur Schema2.groupTable, la fonction Schema1.classifier2() s'exécute correctement pour la connexion NormalUser1.

Connectez-vous à nouveau en tant que NormalUser1 et recherchez dans le journal des événements la présence d'un échec du classifieur.

[!REMARQUE]

Parce que l'autorisation EXECUTE sur la fonction Schema1.classifier2 n'est pas accordée à NormalUser1, ce dernier ne peut pas exécuter la fonction comme une requête ad hoc.

Pour plus d'informations, consultez Chaînes de propriétés.

Test de la fonction classifieur

Vous devez tester et optimiser votre fonction classifieur avant de l'utiliser pour classifier des requêtes entrantes. Une fonction mal écrite peut rendre le système inutilisable par expiration et exposition des informations de configuration. Vous pouvez utiliser une connexion administrateur dédiée (DAC) pour corriger une fonction classifieur alors que le gouverneur de ressources est activé, car cette connexion n'est pas sujette à la classification. Nous vous recommandons d'activer la connexion administrateur dédiée sur le serveur. Pour plus d'informations, consultez Utilisation d'une connexion d'administrateur dédiée.

[!REMARQUE]

L'autre solution, lorsqu'une connexion administrateur dédiée n'est pas disponible pour la résolution des problèmes, consiste à redémarrer le système en mode mono-utilisateur. Le mode mono-utilisateur n'est pas sujet à la classification ; toutefois, il ne vous permet pas d'effectuer un diagnostic du classifieur du gouverneur de ressources s'il est en cours d'exécution.