Как запретить доступ к SQL Server для определенного входа в систему через SSMS, но разрешить через .Net SqlClient Data Provider

10

У нас есть ситуация, когда у разработчиков нет никаких UPDATEразрешений, НО они работают с приложениями и видят строки подключения -> они знают пароли от некоторых учетных записей SQL (пример SQLLogin1), которые имеют разрешения UPDATE. Наши операции в настоящее время не совершенны, и иногда необходимо изменить производственные данные (пока нет графического интерфейса для этого).

Вместо того чтобы связываться с администратором базы данных и просить его изменить данные, разработчик (неправильно) использует учетную запись SQL SQLLogin1(у которой есть разрешение на изменение данных) и подключается через SQL Server Management Studio, чтобы самому изменять данные.

Администратор базы данных не может изменить пароль, SQLLogin1если Разработчик не увидит новую строку подключения и новый пароль, поскольку используемая строка подключения приложения SQLLogin1поддерживается Разработчиком.

Вопрос:

Есть ли способ запретить доступ к SQLLogin1входу в SQL, но только если он подключается через SSMS?

В то же время, если SQLLogin1соединение через .Net SqlClient Data Provider( program_nameв sys.dm_exec_sessions), он должен быть разрешен для входа.

Таким образом, мы не хотим, чтобы Разработчик подключался через SSMS SQLLogin1, в то время как приложение, которое использует SQLLogin1, все еще сможет подключаться.

Алексей Вицко
источник

Ответы:

11

Вы можете использовать триггер входа в систему на сервере, чтобы сделать пользовательские проверки входа в систему и отклонить их, когда считаете нужным. Вы увидите этот триггер в списке ниже «Объекты сервера» и внутри «Триггеры», если вы используете SSMS.

Например:

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

ROLLBACKВнутри триггера будет отвергать соединение (есть неявная транзакция оберточной вызов триггера на события входа в систему).

Будьте внимательны при реализации триггеров входа в систему, если они не закодированы должным образом, вы будете отклонять входы в систему, которые должны быть в состоянии войти (включая ваш собственный!). Обязательно сначала протестируйте в средах test / dev.

Имейте в виду, что этот код выполняется перед созданием сеанса , поэтому системные представления, основанные на идентификаторе сеанса (SPID), не будут содержать текущий проверенный вход в систему, пока триггеры не завершатся без отката или достаточно высокого сбоя.

EzLo
источник
Спасибо! вопрос - если я сделаю какую-либо ошибку в триггере входа в систему, и она заблокирует даже вход в систему учетной записи sysadmin, есть ли еще способ войти в SQL Server и отключить триггер входа?
Алексей
3
Вы можете сбросить триггер без его срабатывания, если вы подключаетесь через ЦАП (выделенное соединение администратора). Это конкретное однопользовательское соединение, которое вы можете установить на сервере, когда что-то пойдет не так. Обычно он используется напрямую с sqlcmd, но вы можете сделать это и с SSMS. docs.microsoft.com/en-us/previous-versions/sql/…
EzLo
6
Это будет работать в течение нескольких минут, пока разработчик не использует другой инструмент. Вы просто не можете удержать хорошего разработчика, если он знает логин с разрешениями.
Джо
3
Это скорее решение для политики, чем решение для безопасности. То есть, триггер входа в систему дает понять, что напрямую подключаться к производственной базе данных противоречит политике. А так как маловероятно, что вы в любом случае сможете защитить от действительно вредоносного разработчика, этого может быть достаточно.
Дэвид Браун - Microsoft
1
@voo Я должен был уточнить. Вы не можете защитить от злонамеренных разработчиков с доступом к производственной среде .
Дэвид Браун - Microsoft
13

Я думаю, что нет надежного решения вашей проблемы, так как он Application Nameможет parameterбыть изменен любым пользователем.

Вот как это можно изменить внутри SSMS:

В Connect to Database Objectдиалоговом окне выберите «Параметры», откройте Additional Connection Parametersи выберите любое имя, Application Nameнапример:

введите описание изображения здесь

Теперь sys.dm_exec_sessionsDMV и Program_name () покажут, что вы передали в строке подключения в Application Nameпараметре:

введите описание изображения здесь

sepupic
источник
4

Вы не можете отключить конкретного клиента, как уже подробно описано в других ответах.

Решение состоит в том, чтобы удалить права доступа к производственным системам из учетных записей разработчика.

Любое изменение должно быть записано в сценарии, и dba запустит сценарий.

Развертывание выполняется системным администратором; Разработчики создают пакет, который они дают кому-то с надлежащими привилегиями, и разработчики никогда не видят конфигурации, используемые в производственных системах.

Отладка организована в каждом конкретном случае с копией производственных данных в промежуточной среде в качестве предпочтительного решения или временной учетной записи с ограниченными привилегиями, если это необходимо.

Paolo
источник
4
  1. В идеальном смысле это проблема процесса / политики / управления. Даже если кто-то знает пароль, если это противоречит политике компании для любого, кроме администратора баз данных, подключаться к Production (ну, у вас может быть команда Release Engineering и / или администраторы sys и т. Д.), И существуют штрафы за нарушение правил, тогда этого должно быть достаточно (при условии соблюдения таких правил).

  2. Попытка предотвратить подключение определенного приложения невозможна. Как показал sepupic , «название программы» довольно легко изменить. Но даже если разработчик не может понять это, существует множество других программ, которые могут подключаться к SQL Server. Большинство людей будут иметь доступ к SQLCMD.exe и даже к устаревшему OSQL.exe . Разработчик может подключиться из Visual Studio и даже может создать собственное приложение для подключения через «.Net SqlClient Data Provider». О, и теперь у нас даже есть Azure Data Studio. Это слишком много.

  3. Тем не менее, это могло бы быть возможно, если бы мы подошли к этому с другой стороны: вместо того, чтобы препятствовать соединению приложения X, как насчет того, чтобы разрешить соединение только приложению Y? Конечно, мы снова попадаем в «имя программы», и даже «имя хоста» может быть подделано, НО, я уверен, что IP-адрес клиента не может быть подделан (по крайней мере, через ключевые слова строки подключения). Вы знаете IP-адрес сервера (ов) приложений или можете легко найти его из sys.dm_exec_connectionsDMV (в client_net_addressполе).

    Начиная с триггера входа в систему, предложенного EzLo , мы можем изменить логику, которая определяет, является ли соединение действительным или нет, следующим:

    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;

    В настоящее время единственным способом является либо войти на рабочий компьютер, либо заставить свою рабочую станцию ​​подделывать IP-адрес сервера приложений. Надеюсь, разработчики не имеют никакого доступа для входа в производство. А подделка существующего IP-адреса в сети вызывает проблемы, которые могут отрицательно повлиять на производство, поэтому они не будут пытаться это делать, верно? Правильно?

Соломон Руцкий
источник
1

Ранее я работал в компании, которая имела эту проблему с одним разработчиком. Он был уволен, но мы также реализовали таблицу, в которой были LoginName и AllowedMachine (сервер приложений) через триггер входа. Это решило наши проблемы. Или, может быть, это было связано с увольнением.

TerryCC
источник