開発者にUPDATE
権限がない状況がありますが、アプリケーションを操作して接続文字列を表示します-> UPDATE権限を持ついくつかのSQLアカウント(例SQLLogin1
)からのパスワードを知っています。現在のところ私たちの操作は完全ではなく、時々本番データを変更する必要があります(まだGUIがありません)。
DBAに連絡してデータを変更するように依頼する代わりに、開発者は(不適切に)SQLアカウントSQLLogin1
(データを変更する権限を持つ)を使用し、SQL Server Management Studio経由で接続してデータを変更します。
DBAはSQLLogin1
のパスワードを変更できません。開発者がSQLLogin1
を使用するアプリケーション接続文字列を開発者が管理しているため、新しい接続文字列と新しいパスワードが表示されます。
SQLLogin1
SQLログインへのアクセスを拒否する方法はありますが、SSMS経由で接続している場合のみですか?
同時に、SQLLogin1
が.Net SqlClient Data Provider
(program_name
のsys.dm_exec_sessions
)を介して接続している場合、ログインを許可する必要があります。
このように、SQLLogin1
を使用しているアプリケーションが引き続き接続できる一方で、開発者にSQLLogin1
を使用してSSMS経由で接続させないようにします。
サーバーログオントリガー を使用して、カスタムログオン検証を行い、必要に応じて拒否することができます。 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環境でテストしてください。
このコードは、セッションが作成される前に実行されるため、セッションID(SPID)に依存するシステムビューには、現在のトリガーがロールバックまたは十分な失敗なしで終了するまで、ログインを確認しました。
他の回答で既に詳述されているように、特定のクライアントを遮断することはできません。
解決策は、開発者のアカウントから本番システムへのアクセス権限を削除することです。
変更はスクリプト化する必要があり、dbaがスクリプトを実行します。
展開はsysadminによって実行されます。開発者は、適切な特権を持つ誰かに与えるパッケージを作成します。開発者は、実稼働システムで使用される構成を決して見ません。
デバッグはケースバイケースで調整され、ステージング環境での本番データのコピーが優先ソリューションとして、または必要に応じて特権が制限された一時的なアカウントで配置されます。
理想的には、これはプロセス/ポリシー/管理の問題です。誰かがパスワードを知っていても、DBA以外の人がプロダクションに接続することが会社のポリシーに違反している場合(まあ、リリースエンジニアリングチームやシステム管理者などがいる可能性があります)、規則に違反するとペナルティがあります。次に、で十分です(このようなルールが適用されていると想定)。
特定のアプリケーションが接続できないようにすることは不可能です。 sepupicが示す のように、「プログラム名」を変更するのはかなり簡単です。しかし、開発者がそれを理解できない場合でも、SQL Serverに接続できるプログラムは他にもたくさんあります。ほとんどの人はSQLCMD.exeにアクセスでき、非推奨のOSQL.exe。開発者はVisual Studio内から接続でき、および ".Net SqlClient Data Provider"を介して接続する独自のアプリを作成することもできます。ああ、今ではAzure Data Studioさえあります。多すぎます。
それでも、別の方向からアプローチする場合は、これがまだ可能である可能性があります。アプリケーションXの接続を防ぐのではなく、アプリケーションYだけに接続を許可するのはどうでしょうか。確かに、再び「プログラム名」に入ります。「ホスト名」でさえ偽装される可能性がありますが、クライアントのIPアドレスが(少なくとも接続文字列キーワードを介して)偽装されることはないと確信しています。アプリサーバーのIPアドレスを知っているか、またはsys.dm_exec_connections
DMV(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(アプリケーションサーバー)を持つテーブルも実装しました。これで問題は解決しました。あるいは、それは発砲のせいかもしれません。