web-dev-qa-db-fra.com

Comment refuser l'accès à SQL Server à certaines connexions via SSMS, mais autoriser le fournisseur de données .Net SqlClient

Nous avons une situation où les développeurs n'ont pas d'autorisations UPDATE, MAIS ils travaillent avec des applications et voient les chaînes de connexion -> ils connaissent les mots de passe de certains comptes SQL (exemple SQLLogin1) disposant des autorisations UPDATE. Nos opérations ne sont actuellement pas parfaites, et parfois les données de production doivent être modifiées (pas encore d'interface graphique pour cela).

Au lieu de contacter DBA et de lui demander de modifier les données, le développeur utiliserait (à tort) le compte SQL SQLLogin1 (autorisé à modifier les données) et connectez-vous via SQL Server Management Studio pour modifier les données lui-même.

DBA ne peut pas changer le mot de passe pour SQLLogin1 sans que le développeur ne voit la nouvelle chaîne de connexion et le nouveau mot de passe, car la chaîne de connexion d'application qui utilise SQLLogin1 est maintenu par le développeur.

Question:

Existe-t-il un moyen de refuser l'accès à SQLLogin1 Connexion SQL, mais uniquement si elle se connecte via SSMS?

En même temps, si SQLLogin1 se connecte via .Net SqlClient Data Provider (program_name dans le sys.dm_exec_sessions), il doit être autorisé à se connecter.

De cette façon, nous ne voulons pas permettre au développeur de se connecter via SSMS en utilisant SQLLogin1, tandis que l'application qui utilise SQLLogin1, pourrait toujours se connecter.

10
Aleksey Vitsko

Vous pouvez utiliser un déclencheur de connexion au serveur pour effectuer des validations de connexion personnalisées et les rejeter à tout moment. Vous verrez ce déclencheur répertorié sous "Objets serveur" et dans "Déclencheurs" si vous utilisez SSMS.

Par exemple:

CREATE TRIGGER strRejectSSMSConnectionForSQLLogin1
ON ALL SERVER FOR LOGON
AS
BEGIN

    IF ORIGINAL_LOGIN() = N'SQLLogin1' AND PROGRAM_NAME() LIKE N'Microsoft SQL Server Management Studio%'
    BEGIN
        RAISERROR('Direct connection by SSMS refused.', 16, 1)
        ROLLBACK
    END

END

Le ROLLBACK à l'intérieur du déclencheur rejettera la connexion (il y a une transaction implicite enveloppant l'appel au déclencheur lors de l'événement de connexion).

Soyez prudent lorsque vous implémentez des déclencheurs de connexion, s'ils ne sont pas codés correctement, vous rejetterez les connexions qui devraient pouvoir se connecter (y compris les vôtres!) Assurez-vous de tester d'abord sur les environnements test/dev.

Gardez à l'esprit que ce code est exécuté avant la création de la session , de sorte que les vues système qui reposent sur l'ID de session (SPID) ne contiendront pas l'actuel connexion vérifiée jusqu'à la fin des déclencheurs sans restauration ou échec suffisamment élevé.

11
EzLo

Je pense qu'il n'y a pas de solution fiable à votre problème puisque Application Name est modifiable parameter cette came peut être modifiée par n'importe quel utilisateur.

Voici comment le changer dans SSMS:

Dans Connect to Database Object boîte de dialogue choisissez Options, ouvrez Additional Connection Parameters et choisissez un nom pour Application Name comme ça:

enter image description here

Maintenant sys.dm_exec_sessions DMV et Program_name () vous montreront ce que vous avez passé dans votre chaîne de connexion dans Application Name paramètre:

enter image description here

13
sepupic

Vous ne pouvez pas couper un client spécifique, comme déjà détaillé dans les autres réponses.

La solution consiste à supprimer les privilèges d'accès aux systèmes de production des comptes du développeur.

Toute modification doit être scriptée et un dba exécutera le script.

Le déploiement est effectué par un administrateur système; les développeurs produisent un package qu'ils donnent à quelqu'un avec les privilèges appropriés et les développeurs ne voient jamais les configurations utilisées sur les systèmes de production.

Le débogage est organisé au cas par cas avec une copie des données de production dans un environnement de transfert comme solution préférée ou un compte temporaire avec des privilèges limités si nécessaire.

4
Paolo
  1. Dans le sens idéal, il s'agit d'un problème de processus/politique/gestion. Même si quelqu'un connaît le mot de passe, s'il est contraire à la politique de l'entreprise que quiconque, sauf un administrateur de base de données, se connecte à la production (enfin, vous pourriez avoir une équipe d'ingénierie de libération et/ou des administrateurs système, etc.), et il y a des pénalités pour enfreindre les règles, alors cela devrait être suffisant (en supposant que de telles règles sont appliquées).

  2. Il est impossible d'empêcher une application particulière de se connecter. Comme sepupic l'a démontré , il est assez facile de changer le "nom du programme". Mais même si le développeur ne peut pas comprendre cela, il existe de nombreux autres programmes qui peuvent se connecter à SQL Server. La plupart des gens auront accès à SQLCMD.exe et même aux obsolètes OSQL.exe . Le développeur peut se connecter depuis Visual Studio, et il peut même créer sa propre application pour se connecter via ".Net SqlClient Data Provider". Oh, et maintenant nous avons même Azure Data Studio. C'est tout simplement trop.

  3. Pourtant, cela pourrait encore être possible si nous l'abordons dans l'autre sens: au lieu d'empêcher l'application X de se connecter, pourquoi ne pas autoriser l'application Y à se connecter? Bien sûr, nous entrons à nouveau dans le "nom du programme", et même le "nom d'hôte" peut être usurpé, MAIS, je suis à peu près sûr que l'adresse IP du client ne peut pas être usurpée (du moins pas via les mots clés de la chaîne de connexion). Vous connaissez l'adresse IP du ou des serveurs d'applications ou vous pouvez facilement la trouver dans le sys.dm_exec_connections DMV (dans le client_net_address champ).

    En commençant par Logon Trigger suggéré par EzLo , nous pouvons modifier la logique qui détermine si la connexion est valide ou non:

    IF (ORIGINAL_LOGIN() = N'SQLLogin1'
        AND (
                 CONVERT(VARCHAR(10), CONNECTIONPROPERTY('net_transport')) <> 'TCP'
              OR CONVERT(VARCHAR(10), CONNECTIONPROPERTY('client_net_address')) <> '10.10.10.10'
     -- uncomment below (and comment-out line above) if app uses multiple IP addresses
     --       OR CONVERT(VARCHAR(10), CONNECTIONPROPERTY('client_net_address'))
     --                   NOT IN ( '10.10.10.10', '10.10.10.11', ...)
            ))
    BEGIN
        RAISERROR('Non-application connection refused.', 16, 1);
        ROLLBACK;
    END;
    

    Le seul moyen maintenant serait de se connecter à la machine de production ou de faire usurper l'adresse IP du serveur d'application sur leur poste de travail. J'espère que les développeurs n'ont aucun accès pour se connecter à Production. Et l'usurpation d'une adresse IP existante sur un réseau provoque des problèmes qui pourraient nuire à la production, donc ils n'essaieront pas cela, non? Droite?

4
Solomon Rutzky

J'ai précédemment travaillé pour une entreprise qui avait ce problème avec un développeur. Il a été renvoyé, mais nous avons également implémenté une table qui avait LoginName et AllowedMachine (Application Server) via un déclencheur de connexion. Cela a résolu nos problèmes. Ou peut-être était-ce dû au licenciement.

1
TerryCC