Como negar o acesso ao SQL Server para determinado logon no SSMS, mas permitir no .Net SqlClient Data Provider

10

Temos uma situação em que os desenvolvedores não têm UPDATEpermissão, MAS trabalham com aplicativos e veem cadeias de conexão -> eles conhecem senhas de algumas contas SQL (exemplo SQLLogin1) que possuem permissões UPDATE. Atualmente, nossas operações não são perfeitas e, às vezes, os dados de produção precisam ser modificados (nenhuma GUI para isso ainda).

Em vez de entrar em contato com o DBA e pedir para ele modificar os dados, o Desenvolvedor (indevidamente) usaria a conta SQL SQLLogin1(que tem permissão para modificar os dados) e se conectaria pelo SQL Server Management Studio para modificar os dados.

O DBA não pode alterar a senha SQLLogin1sem que o Developer veja a nova cadeia de conexão e a nova senha, pois a cadeia de conexão do aplicativo usada SQLLogin1é mantida pelo Developer.

Questão:

Existe uma maneira de negar o acesso ao SQLLogin1logon do SQL, mas apenas se ele estiver se conectando pelo SSMS?

Ao mesmo tempo, se SQLLogin1estiver se conectando .Net SqlClient Data Provider( program_nameno sys.dm_exec_sessions), deve ser permitido o login.

Dessa forma, não queremos permitir que o Developer se conecte pelo SSMS usando SQLLogin1, enquanto o aplicativo que estiver usando SQLLogin1, ainda poderá se conectar.

Aleksey Vitsko
fonte

Respostas:

11

Você pode usar um gatilho de logon do servidor para fazer validações personalizadas de logon e rejeitá-las sempre que achar necessário. Você verá esse gatilho listado abaixo de "Objetos do servidor" e dentro de "Triggers" se estiver usando o SSMS.

Por exemplo:

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

O ROLLBACKinterior do gatilho rejeitará a conexão (há uma transação implícita envolvendo a chamada do gatilho no evento de logon).

Tenha cuidado ao implementar os gatilhos de logon; se não estiver codificado corretamente, você rejeitará os logons que devem poder fazer login (incluindo o seu!). Certifique-se de testar primeiro os ambientes test / dev.

Lembre-se de que esse código é executado antes da criação da sessão , portanto, as visualizações do sistema que dependem do ID da sessão (SPID) não conterão o logon atualmente verificado até que os gatilhos terminem sem reversão ou falha suficientemente alta.

EzLo
fonte
obrigado! pergunta - se eu cometer algum erro no gatilho de logon e ele bloquear até mesmo a conta do sysadmin de efetuar login, ainda há uma maneira de entrar no SQL Server e desativar o gatilho de logon?
Aleksey Vitsko 04/03/19
3
Você pode soltar o gatilho sem dispará-lo se conectar a um DAC (conexão de administrador dedicada). É uma conexão de usuário único específica que você pode emitir no servidor sempre que algo der errado. Geralmente é usado diretamente com o sqlcmd, mas você também pode fazê-lo com o SSMS. docs.microsoft.com/pt-br/previous-versions/sql/…
EzLo 4/19/19
6
Isso funcionará por alguns minutos, até que o desenvolvedor use uma ferramenta diferente. Você simplesmente não pode impedir um bom desenvolvedor se ele souber um login com permissões.
Joe
3
Esta é mais uma solução de política do que uma solução de segurança. Ou seja, o gatilho de logon deixa claro que é contra a política conectar-se diretamente ao banco de dados de produção. E como é improvável que você possa se proteger contra um desenvolvedor realmente malicioso , isso pode ser bom o suficiente.
David Browne - Microsoft
11
@voo eu deveria ter esclarecido. Você não pode se proteger contra desenvolvedores mal-intencionados com acesso ao ambiente de produção .
David Browne - Microsoft
13

Eu acho que não há solução confiável para o seu problema, pois Application Nameé modificável parameterque a cam seja alterada por qualquer usuário.

Aqui está como alterá-lo dentro de SSMS:

Na Connect to Database Objectcaixa de diálogo, escolha Opções, abra Additional Connection Parameterse escolha qualquer nome para o Application Nameseguinte:

insira a descrição da imagem aqui

Agora sys.dm_exec_sessionsDMV e Program_name () mostrarão o que você passou na sua cadeia de conexão no Application Nameparâmetro:

insira a descrição da imagem aqui

sepupico
fonte
4

Você não pode cortar um cliente específico, como já detalhado nas outras respostas.

A solução é remover os privilégios de acesso aos sistemas de produção das contas do desenvolvedor.

Qualquer alteração deve ter um script e um dba executará o script.

A implantação é realizada por um administrador de sistemas; devs produzem um pacote que dão a alguém com privilégios adequados e nunca vêem as configurações usadas nos sistemas de produção.

A depuração é organizada caso a caso com uma cópia dos dados de produção em um ambiente de preparação como uma solução preferida ou uma conta temporária com privilégios limitados, se necessário.

Paolo
fonte
4
  1. No sentido ideal, essa é uma questão de processo / política / gerenciamento. Mesmo se alguém souber a senha, se for contra a política da empresa que alguém, exceto um DBA, se conecte à Produção (bem, você pode ter uma equipe de Engenharia de Liberação e / ou administradores de sistemas, etc.) e há penalidades por violar as regras, então isso deve ser suficiente (supondo que essas regras sejam aplicadas).

  2. Tentar impedir que um aplicativo específico se conecte é impossível. Como demonstrou sepupic , é bastante fácil alterar o "nome do programa". Mas mesmo que o desenvolvedor não consiga descobrir isso, existem muitos outros programas que podem se conectar ao SQL Server. A maioria das pessoas terá acesso ao SQLCMD.exe e até ao OSQL.exe descontinuado . O desenvolvedor pode se conectar a partir do Visual Studio e até criar seu próprio aplicativo para se conectar via ".Net SqlClient Data Provider". Ah, e agora ainda temos o Azure Data Studio. São demais.

  3. Ainda assim, isso ainda pode ser possível se a abordarmos de outra direção: em vez de impedir que o aplicativo X se conecte, que tal permitir apenas o aplicativo Y se conectar? Claro, entramos novamente no "nome do programa" e até mesmo o "hostname" pode ser falsificado, MAS, tenho certeza de que o endereço IP do cliente não pode ser falsificado (pelo menos não através das palavras-chave da cadeia de conexão). Você conhece o endereço IP dos servidores de aplicativos ou pode encontrá-lo facilmente na sys.dm_exec_connectionsDMV (no client_net_addresscampo).

    Começando com o gatilho de logon sugerido pelo EzLo , podemos modificar a lógica que determina se a conexão é válida ou não:

    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;
    

    As únicas maneiras agora são logon na máquina de produção ou ter sua estação de trabalho falsificar o IP do servidor de aplicativos. Esperamos que os desenvolvedores não tenham acesso para fazer logon na Produção. A falsificação de um IP existente em uma rede causa problemas que podem afetar adversamente a Produção, para que eles não tentem isso, certo? Direita?

Solomon Rutzky
fonte
1

Eu trabalhei anteriormente para uma empresa que tinha esse problema com um desenvolvedor. Ele foi demitido, mas também implementamos uma tabela que tinha o LoginName e AllowedMachine (Application Server) por meio de um gatilho de login. Isso resolveu nossos problemas. Ou talvez tenha sido devido ao disparo.

TerryCC
fonte