RPC サーバーを利用できません?

Last Update: feedback 共有

本記事は 2009 年 9 月 2 日に公開された記事を本ブログに移行した記事になります。

こんにちは。Windows プラットフォーム サポート担当の加山です。

・ RPC サーバーを利用できません
・ エンドポイント マッパーから使用できるエンドポイントはこれ以上ありません

Windows のシステム管理者の方なら、一度はこのようなエラー メッセージを見たことがあるかも知れません。
Active Directory の複製処理を GUI から実行した時とか・・・

ntdsutil コマンドで Active Directory の管理を行う時とか・・・

デバッグ ログの中にも・・・

今日は管理者の皆様を悩ませている(かも知れない?)このエラーメッセージの意味と対処方法について解説していきます。

  1. RPC とは?
    RPC とは Remote Procedure Call の略で、その名の通りリモート コンピューター上に実装された機能を呼び出すための仕組みです。
    しかしながら、Web や電子メールなどが普及していることからも明らかなように、昨今のシステムの多くはネットワーク上のコンピューターの機能を利用してすることを前提として動作しています。「リモートコンピューターの機能を呼び出す」 という言葉だけを見ると、HTTP や SMTP のような通常のクライアント / サーバー型のアプリケーションとの違いがわかりにくいかもしれません。そこで、まず簡単ではありますが、下記にその違いについて解説します。

    • 通常のクライアント / サーバー型アプリケーション
      従来のクライアント / サーバー型のアプリケーションでは、クライアント側に実装された機能によってリクエストを生成します。リクエストを受けたサーバーはその内容を読み取って、サーバー側で実装された機能によって処理を行い、レスポンスを返します。
  • RPC アプリケーション
    一方で、RPC アプリケーションではサーバー側に実装された機能をプロシージャーの単位で呼び出します。イメージは、下図の通りです。

この例では、RPC クライアント アプリケーションが RemoteFunction という名前のプロシージャーを呼び出していますが、このプロシージャーによって呼び出される機能はクライアント側には実装されていません。RPC サーバーへのリクエストの作成、送信は RPC クライアント スタブライブラリが代行し、目的のプロシージャーはリモート コンピューター上で実行され、結果のみが RPC クライアントアプリケーションに返されます。このようにして、RPC クライアント アプリケーションは、サーバーに対してどのようにリクエストを送るかなどを意識せずに、その機能のみを利用できます。

** もちろん、リモートだけではなく、ローカル コンピューター上に実装されている RPC サーバー アプリケーションの機能を呼び出すことも可能です。呼び出すプロシージャーが同じであれば、実装されているのがローカルかリモートかによらず、同一の手順で処理を行えることも RPC の利点の一つです。

  • それでは、「RPC サーバーを利用できません」とは?
    前述の通り、RPC の機能を利用するクライアント アプリケーションは、「どのプロシージャーを呼び出すか」、「どのサーバーから呼び出すか」などの情報を RPC クライアント スタブ ライブラリに渡してプロシージャーの実行結果を待ちます。

通常は、前述の通り目的のプロシージャーが RPC サーバーによって実行され、成功、失敗などのメッセージが応答として RPC クライアントアプリケーションに返されるのですが、ネットワーク通信の問題などによって RPC サーバーに対してリクエストを送信できない場合、RPC クライアント アプリケーションは RPC スタブ ライブラリからエラーメッセージを受け取ります。

これが、問題のエラー メッセージ “RPC サーバーを利用できません” が発生する仕組みです。

RPC スタブ ライブラリは、OS で共通のコンポーネントが使用されます。多くの場合、アプリケーション側ではプロシージャーの実行結果として受け取ったエラーコードやメッセージをそのままの形でイベント ビューアやダイアログ ボックス、デバッグ ログなどに出力するので、RPC で利用する様々なアプリケーションでこの共通のエラーメッセージが出力されることになります。

  1. 主に考えられる原因と RPC エンドポイント マッパー

エラー メッセージの意味がわかったところで、実際に RPC サーバーへの通信に失敗する原因にはどのようなものがあるのでしょうか。下記に、代表的な例をご紹介します。

  • 名前解決のトラブル、経路上の障害
    まず第一に考えられるのが、名前解決のトラブルや、ネットワーク経路上の通信トラブルです。多くの場合、RPC の通信は TCP/IP プロトコル上で動作しますので、IP 層での疎通ができていることがまず第一の条件となります。問題の発生しているコンピューターが宛先のコンピューターと疎通できているか、宛先として指定しているコンピューター名の名前解決が正常に行えているかを、ping コマンドや nslookup コマンドで確認してみましょう。名前解決の仕組みやネットワークの疎通の確認方法については、本 Blog の過去の記事 <Windows 名前解決の順序> もご参考にしていただければ幸いです。

  • ファイアウォールによる RPC に必要な通信のフィルタリング
    さて、上記の確認を行ったところ、名前解決も正しく行えていて、ping コマンドでネットワークの疎通も確認できている・・・にも拘わらず、何故か “RPC サーバーを利用できません” のエラーが出力されてしまう場合は、RPC で使用するポートが経路途中のファイアウォールや、コンピューター上のパーソナル ファイアウォールによってフィルタリングされている可能性があります。

Windows における RPC の実装では RPC エンドポイントマッパーと呼ばれる仕組みが用意されており、多くの RPC アプリケーションがこの仕組みを利用しています。この仕組みを使って RPC の通信が行われる場合、使用されるポートの選択方法が通常のクライアント / サーバーアプリケーションと比較して少しだけ複雑になっています。このため、これらの正しく仕組みを理解した上で、必要なポート番号による通信をあらかじめ許可しておくことが肝要となります。

  • RPC エンドポイント マッパーによる RPC 動的ポート通知の仕組み
    それでは、RPC エンドポイント マッパーの動作の仕組みを見ていきましょう。まずは、下の図をご覧ください。

図の通り、RPC サーバー側では、RPC エンドポイント マッパーが 135/tcp でリッスンしており、RPC クライアント アプリケーションからの要求を受け付けています。RPC エンドポイント マッパーの役割は、RPC クライアントが呼び出そうとしているアプリケーションの ID から、そのアプリケーションが使用しているリッスン ポート番号を伝えることです。エンドポイント マッパーからポート番号を受け取った RPC クライアントは、そのポート番号を宛先として目的のプロシージャーの呼び出しを実行します。

  • RPC 動的ポート割り当てについて
    RPC は数多くの Windows 標準のコンポーネントで使用されており、呼び出しの際にオンデマンドでアクティブ化されるものも存在します。また、Windows 標準のコンポーネントに限らず、個別に開発されたサード パーティー製のアプリケーションも RPC の仕組みを利用することも多々あります。このように、多数の RPC アプリケーションが様々なタイミングで起動することから、各アプリケーションに固定的にポート番号を割り当てるような実装方法では、ポート番号のバッティングが発生した際にアプリケーションの起動に失敗する可能性が出てきます。その度にポート番号の調整を行うことは、管理面から考えると非効率的と言えるでしょう。

このような背景もあって、RPC サーバー アプリケーションの多くは固定のポート番号でリッスンするのではなく、”RPC 動的ポート” の範囲から現在利用可能なポート番号を取得して使用します。そして、アプリケーションの起動時に自身が使用するポート番号を RPC エンドポイント マッパーに登録して、前述したような仕組みでクライアントがどのポート番号に対してアクセスすればよいかを取得できるようにしているのです。

** RPC 動的ポート割り当てを使用せず、固定ポート番号でリッスンを行い、クライアント側からも直接そのポート番号への通信を行う RPC アプリケーションも存在します。例えば、Windows Server 2003 R2 以降で実装された DFS Replication の機能では、5722/tcp が固定的に使用されています。

  • ファイアウォールで許可しなければならないポート番号
    RPC サーバー アプリケーションは、起動時に自身がリッスンするポート番号をエンドポイントマッパーに登録します。RPC サーバー アプリケーションが使用するポート番号は、Windows Server 2003 / Windows XP の既定では 1024 番~ 5000 番、Windows Server 2008 / Windows Vista の既定では 49152 番 ~ 65535 番です。このため、RPC サーバーの下記のポート番号宛ての通信が、経路上のファイアウォール、コンピューター上のパーソナル ファイアウォールなどで許可されている必要があります。
  • 135/tcp (RPC エンドポイント マッパー / 全 OS バージョン共通)
  • 1024-5000/tcp,udp (RPC 動的ポート / Windows Server 2003, Windows XP の場合)
  • 49152-65535/tcp,udp (RPC 動的ポート / Windows Server 2008, Windows Vista の場合)

しかしながら、”1024-5000/tcp,udp” や “49152-65535/tcp,udp” のように、広範囲のポート番号の通信をファイアウォールで許可することはセキュリティ上望ましくないと判断されるお客様も多くいらっしゃいます。このような要件を満たすために、RPC 動的ポートで使用されるポートの範囲を変更する方法が下記の弊社サイトにて公開されています。

The default dynamic port range for TCP/IP has changed in Windows Vista and in Windows Server 2008 (英語)
http://support.microsoft.com/kb/929851/en-us

ただし、動的ポートの範囲をあまり狭くしすぎるとポートの枯渇が発生し、やはり RPC サーバー アプリケーションが正常に起動できなくなるなどの問題が発生します。お客様環境の要件合わせて、ある程度余裕を持たせた適切な範囲で設定していただくことをお勧めしております (サポート技術情報 154596 にて記載しております “最低でも 100” という数字も目安になります)。

  1. トラブルシューディング : ネットワーク トレースの解析

最後に、実際にエラーが発生した場合に、ネットワーク トレースを用いてトラブル シューディングを行う方法をご紹介します。

ネットワーク トレースを取得すると、通信のどの段階で問題が発生しているかを特定することが容易となります。弊社からも Microsoft Network Monitor というツールを公開しており、下記の Web サイトからダウンロードしてご利用いただくことが可能です。

Microsoft Network Monitor 3.4
http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=983b941d-06cb-4658-b7f6-3088333d062f

  • RPC エンドポイントマッパー (135/tcp) 宛の通信がフィルタリングされている場合
    例えば、ntdsutil コマンドを用いて Active Directory の FSMO ロールをメンバー サーバーから変更しようとした際に、下記のようにエラーとなり、操作が行えない現象が発生しているとします。

現象を再現させて、上記のエラーメッセージが出力されるタイミングでのネットワーク トレースを取得します。

上の図が、採取されたネットワークトレースです。Frame 3 ~ Frame4 から、DNS の名前解決には成功していることがわかります。

一方で、Frame 5 ~ Frame7 を見ると、目的のホストである 2k3r2sp2-01 の 135/tcp へのアクセスを行おうとしているにもかかわらず、応答が返されていないことがわかります。このことから、経路上、もしくは目的のサーバー上で、135/tcp 宛の通信がフィルタリングされていることが疑われます。

  • RPC 動的ポート (1024-5000/tcp,udp or 49152-65535/tcp,udp) 宛の通信がフィルタリングされている場合
    RPC 動的ポートが利用できない場合は、下記のように少し異なるエラーメッセージが出力されます。

ネットワーク トレースを見てみましょう。

Frame8 ~ Frame 11 を見ると、エンドポイント マッパー宛の通信に成功していることがわかります。目的のプロシージャーの呼び出しに使用するべきポート番号が 1026/tcp であることが通知されています。
** 使用される RPC の種類によってはパケットのフォーマットが異なり、この例と同じようにポート番号が表示されない場合があります。ご注意ください。

その後、受領したポート番号 1026/tcp 宛に通信を行おうとして、応答が返されていない様子が確認できます。やはり同様に、RPC 動的ポートで使用する通信が経路上、宛先サーバー上でフィルタリングされている可能性が考えられます。

  • RPC エンドポイントマッパーにアプリケーションが登録されていない場合
    ポートの枯渇などが原因で、RPC サーバー アプリケーションが RPC 動的ポートのバインドに失敗して RPC エンドポイント マッパーにアプリケーションが登録されていない場合もやはり、ネットワーク トレースによってその状況を確認することができます。

やはり同様に、下記のようなエラーメッセージが表示されます。

では、ネットワーク トレースを見てみましょう。

経路上でポートがフィルタリングされている場合と異なり、RPC エンドポイント マッパー (135/tcp) から EP_S_NOT_REGISTERD のエラー コードが返されていることがわかります。これは、指定した RPC サーバー アプリケーションが RPC エンドポイント マッパーに登録されていないことを意味します。

「RPC サーバーを利用できません」、「エンドポイント マッパーから使用できるエンドポイントはこれ以上ありません」 のメッセージが出力された場合は、前述したような、名前解決の問題、ネットワーク 通信の経路上の問題、RPC で使用されるポートのフィルタリング、ポートの枯渇などが原因となっていることがほとんどです。本記事が原因追求のご参考となれば幸いです。

[特記事項]
本情報の内容(添付文書、リンク先などを含む)は、作成日時点でのものであり、予告なく変更される場合があります。