SQL Server監査データからスカラー値のユーザー定義関数の使用を除外する方法


12

データベースに対するすべての実行アクションを監査するデータベース監査仕様を持つSQL Serverデータベースがあります。

CREATE DATABASE AUDIT SPECIFICATION [dbAudit]
FOR SERVER AUDIT [servAudit]
ADD (EXECUTE ON DATABASE::[DatabaseName] BY [public])

一部のクエリは、結果セットのすべての行に対してスカラー関数の使用を監査ログに書き込むことがわかっています。これが発生すると、ログがETLで最終的な休憩場所に達する前にログがいっぱいになり、ログにギャップが生じます。

残念ながら、コンプライアンス上の理由により、すべてのEXECUTEステートメントの監査を停止することはできません。

この問題へのアプローチについて最初に考えたのはWHEREサーバー監査の句を使用してアクティビティを除外することです。コードは次のようになりました。

WHERE [object_id] not in (Select object_id from sys.objects where type = 'FN' )

残念ながら、SQL ServerはリレーショナルIN演算子を許可しません(おそらく、監査ログに書き込む必要があるたびにクエリを実行したくないためです)。

私たちは、どのハードコードストアドプロシージャ書き込みを避けたいobject_idWHERE句が、それは、この問題にアプローチする最良の方法で私たちの現在の考え方です。考慮すべき代替アプローチはありますか?

再帰CTEでスカラー関数が使用されている場合、結果セット内のすべての行の監査ログにクエリが書き込まれることに気付きました。

ベンダーが提供するいくつかのスカラー値関数がありますが、それらを削除したり、代替データベースに移動したりすることはできません。


6
We've found that some queries will write to the audit log the use of a scalar function for every row in a result set.-これは、私が今まで聞いた中で最も素晴らしいスカラーUDFの副作用の1つであり、多くのことを聞いたことがあります。
エリックダーリン

3
別のデータベースで監査したくない(監査されていない)UDFを作成し、3-part-nameでそれらを呼び出すオプションはありますか?
スコットホジン

@ScottHodgin、私は回避策が好きですが、私たちの環境では、ベンダーによって提供されるいくつかのスカラー値関数があり、それらを削除したり、代替データベースに移動したりすることはできません。
マークIannucci

後に続くものは、クエリが結果セット内のすべての行の監査ログに書き込む原因となるのは疑問です。スカラー関数が再帰的CTEで使用されているときに発生することに気付きました。
マークIannucci

回答:


6

私が仕事をすることができたいくつかのオプションがあります。すべてのオプションは、さまざまなフィルター述語を処理します。注:あなたがしなければならない無効の変更を行うために、サーバーの監査をした後、再使用可能に。

まず、最も一般的なアプローチは、すべてのScalar UDFを除外することです。それには、class_type監査フィールドを使用します。ドキュメントには、このフィールドがVARCHAR(2)であることが示されていますが、文字列の指定は許可されていません。しかし、私は次のものを機能させました:

ALTER SERVER AUDIT [servAudit]
WHERE ([class_type] <> 20038); -- EXECUTE Scalar UDF

(この調査の詳細については、サーバー監査ミステリー:class_typeのフィルタリングでエラーメッセージ25713が取得されます

これはベンダー提供のデータベースであり、変更を加えることができないと述べられているため、次に最も一般的なアプローチはオプションではありません。最後に取り上げます。

最も一般的でないアプローチ(ただし、確実に機能するアプローチ)は、特定の関数名を除外することです。

ALTER SERVER AUDIT [servAudit]
WHERE ([object_name]<>'function_name');

または、複数の名前の場合:

ALTER SERVER AUDIT [servAudit]
WHERE ([object_name]<>'function_name1' AND [object_name]<>'function_name2');

あまり一般的ではありませんが、このアプローチは、フィルターする関数の数がかなり少なく、新しい関数が導入されることはあまりないため、問題ありません。

最後に、この状況に直面し、変更を行うことを制限されていない他の人に:自分のスキーマに関数を配置し、そのスキーマだけを除外できます。これは、関数を個別にフィルタリングするよりも一般的です。名前付きのスキーマを作成し、fnその中に関数を配置すると仮定します。

ALTER SERVER AUDIT [servAudit]
WHERE ([schema_name]<>'fn');

また、質問の次の2つのコメントに関して:

残念ながら、SQL ServerはリレーショナルIN演算子を許可しません(おそらく、監査ログに書き込む必要があるたびにクエリを実行したくないためです)。

そして:

WHERE句にobject_idをハードコードするストアドプロシージャを記述しないようにしたい

INオペレータは問題ではありません。確かに、これはサポートされていませんが、OR条件のリストの略記です。実際の問題は、T-SQLの使用です。リテラル(文字列または数字)のみが許可されます。したがって、とにかくストアドプロシージャを実行することはできなかったでしょう。また、組み込み関数を使用することもできません。


この応答に感謝します。現在、この変更を実装するプロセスにあります。環境で機能することが確認できたら、この回答を受け入れます。
マークIannucci

1
@MarkIannucciありがとう!また、理想的な提案でマイナーなバグを修正しました。ANYTHING BUT関数の代わりにFOR関数をフィルタリングしていたテストからコピーして貼り付けました。私は答えを変更し=ました<>。私もそれをテストしましたが、宣伝どおりに動作します:
ソロモンラッツキー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.