はじめに
リンクサーバへアクセスするSQL Serverユーザーエージェントジョブを実行すると、「現在のセキュリティ コンテキストは信頼されていないので、リモート サーバーへのアクセスが拒否されました」というエラーになる場合があります。
このエラーの解決方法をググると、おおむね以下のような内容のものが見つかります。
- リンクサーバのセキュリティ設定を「このセキュリティ コンテキストを使用する」にする
- 「リモート ログイン」と「パスワード」にリモートサーバのユーザー名とパスワードを設定する
これで接続できるようになるということは、なにかジョブ特有の制限などによって失敗しているということではなく、単に接続の設定がうまくいっていないということのようです。確かにこれでエラー無く接続できるようになりますが、要はこのサーバにログインできるユーザーを無条件でリモートサーバにアクセスできるようにしているわけで、セキュリティ的には微妙です。
こういう何らかの制限を全開放することで解決するみたいなやり方は負けた感じがするので、全開放しないやり方を調べてみました。
そもそもなぜマッピングか使われないのか
リンクサーバへの接続はローカルのログインにリモートのログイン情報をマッピングするという方法で行います。さっきの設定はこのマッピングに該当しないユーザーのための設定です。
このマッピングの設定が間違っている場合、ジョブ以外のところでも、たとえばリンクサーバに対するクエリーの実行やManagement Studioのリンクサーバのカタログを見たりなども失敗するはずです。これらができるということは、このマッピングの設定は間違っていないと言えるでしょう。ということは、ジョブがマッピングで設定されているユーザーで実行されていないことが考えられます。
ジョブに指定するユーザーの情報としては、ステップの設定にある何も選べない「実行するアカウント名」が真っ先に目に付きますが、これは罠です。
この設定はステップの種類が外部コマンドなどの場合に実行するWindowsのアカウントを指定するもので、「Transact-SQL スクリプト」の場合は指定することはできません。種類を別のものに変えてから「Transact-SQL スクリプト」に戻すとグレーアウトされて選択できなくなります。
その他の設定としては詳細設定にある「実行時のユーザー」がそれっぽい感じがしますが、これも違います。SQL Serverにはサーバへの接続に使用する「ログイン」と、データベースへの権限などを指定する「ユーザー」との2種類のユーザーがあります。マッピングで使用するのは「ログイン」の方で、「実行時のユーザー」はデータベースの「ユーザー」なので違います。
ではどこで指定するのかというと、以下の引用にあるように「ジョブの所有者」です。引用中の「SQL Server エージェント プロキシ」というのは先ほどの「実行するアカウント名」の設定のことです。
ジョブ ステップの管理 | Transact-SQL ジョブ ステップ
https://technet.microsoft.com/ja-jp/library/ms187056(v=sql.110).aspx#Anchor_2
Transact-SQL ジョブ ステップでは SQL Server エージェント プロキシを使用しません。このジョブ ステップはジョブ ステップの所有者として実行されるか、ジョブ ステップの所有者が sysadmin 固定サーバー ロールのメンバーの場合には SQL Server エージェント サービス アカウントとして実行されます。
ジョブの所有者の初期値はジョブを作成したユーザーですが、ジョブを作成できるユーザーはおおむね sysadmin になっていますから、SQL Server エージェントサービスアカウント(NT SERVICE\SQLAgentみたいなやつ)として実行されていたわけです。リンクサーバのマッピングにそんなユーザーは設定していないのでリンクサーバへの接続に失敗していたというわけです。
正しく動作する設定方法
ということで、正しく動作する適切な設定は以下になります。
- ジョブの所有者に適切なユーザーを設定する
- リンクサーバのログインのマッピングにジョブの所有者を追加する
[参考]
リンク サーバーの作成 (SQL Server データベース エンジン)
https://msdn.microsoft.com/ja-jp/library/ff772782.aspx