Exchange 2013 CU11の管理シェルの変更点

昨年末ごろから、Exchange 2013の管理系の自作スクリプトが失敗する様になったという話を色々な所で耳にするようになりました。

Exchange Server 2013のコンソールからExchange管理シェルのプログラムを起動すると、黄色い字で「○○○(サーバ名)に接続しています/接続しました」と表示されます。

ただ、実際には別のサーバに接続しているケースがあります。例えば、下のスクリーンショットではmbxcas02ではなくmbxcas01に接続していることが、Get-ExchangeCertificateコマンドレットの実行結果からお分かり頂けると思います。
20160411_01

これは、Exchange Server 2013のCU 11から実装されたExchange管理シェル(EMS)の仕様変更に依るものです。

Exchange 管理シェルとメールボックスのアンカー設定

簡単に説明すると、今まではExchange管理シェルは接続した先のサーバにそのまま接続されていましたが、Exchange 2013 CU11からはCAS(クライアントアクセスサーバ)に接続した場合自分のメールボックスの存在するメールボックスサーバ(メールボックスを持たないアカウントの場合は調停メールボックスの存在するサーバ)に接続するようになりました。
20160411_02

なので、ローカルサーバへのオペレーションだと思って実行しているコマンドは違うサーバに対して実行されてしまうことがあります。接続先のサーバが異なるADサイトに存在をしている場合、AD情報の同期タイミングも考慮しなければいけません。

なお、CASの役割がインストールされていないサーバ(メールボックスのみやエッジトランスポートサーバ)の場合は影響ありません。

基本的な対処策としては、例えば Get-ExchangeCertificate であればGet-ExchangeCertificate -Server (hostname)などとして、明示的に実行先のサーバを指定するようにするという形になります。

いままで通りでやりたい場合は、PowerShellを管理者権限で立ち上げたあと、

Add-PSSnapin Microsoft.Exchange.Management.PowerShell.SnapIn

と実行すれば今までと同じ感覚で利用できますので、私なんかは.ps1スクリプトにしてデスクトップに置いておいてます。

Exchange 2010でドメインコントローラに接続できない

Exchange Server 2010で、ある日突然CASやメールボックスサーバがMSExchange ADAccessの2130,2102,2103など、いずれもドメインコントローラに接続できない旨のエラーが出てサービスが利用できなくなる事があります。
20151028_05

事象自体はOS再起動をすると治るのですが、たまに発生する割には、出る環境と出ない環境が決まっていて変だなと思って調査をしたのでそのメモを。

まず、この事象に陥ってもRDPでサーバに接続できます。でも、なぜかドメインコントローラに接続ができない、詳しく言うと、ドメインコントローラの名前解決のDNSに失敗します。nslookupでDNSサーバに接続しようとしても接続できません。
20151028_06

もっと調べると、この状態ですがTCPやICMPの通信には影響を及ぼさない(なのでRDP接続はできる)のですが、UDPでのみ通信ができないという状態だということが分かりました。

ここで、セッションの状態を見てみようとnetstat -anoを打ってみます。20151028_08 20151028_01

と、延々と続くUDPの待ち受けポート。どうやらこいつが原因のようです。TCPの動的ポート枯渇というのは497日問題で良く聞いた話ですが、UDPにも動的ポートがあります。どうやらこれが枯渇しているようです。
20151028_04

netstatの結果より調べたプロセスを特定します。タスクマネージャーを開き、必要に応じて更に列の選択でコマンドラインを表示させます。(w3wp.exeの場合、ワーカープロセスの特定に使います)
20151028_09

こちら場合によっていくつかケースがあるのですが、多くの場合はCASはOWAかExchangeServicesのIISのワーカープロセス、メールボックス(特にパブリックフォルダを有している)の場合はRPC Client Accessが多いです。
20151028_02

サービスの再起動か、ワーカープロセスの場合はIISマネージャーから、被疑アプリケーションプールのリサイクルを実施します。
20151028_03

これでしばらく待つとMSExchange ADAccessが自動的にドメインコントローラを見つけてくれ、動作が再開します。

 

そもそもの原因なのですが、どうやら上記を初めとする一部のExchangeアプリケーションが全ドメインコントローラに接続できないタイミングで、そのアプリケーションでリークが発生。UDPの動的ポートが掴みっぱなしになり、そのポートが徐々に溜まっていき、16000超の領域を全部埋め尽くすと、今回の様な事象になるようです。

確かに、検証環境でADが1台しかなかったり、複数台有ってもメンテナンスの時などに一定時間(例えば15分)とか開けずに1台目のドメインコントローラが上がってきたタイミングですぐに2台目を再起動するなどの運用をしている環境でたまに発生していました。

特に直す気配も無さそうなので、対策としては

  1. 常時最低1台はMSExchange ADAccessからドメインコントローラに接続できているようにする
  2. UDPの動的ポートの数を増やす
  3. UDPのポート数を監視(1万くらいになったら対象プロセスを再起動)

とかになりますね。

DuplicateDeliverによる配信不可

Exchange Serverでは、以前のバージョンより同じメールが複数届いた場合に最初の1通のみ受信し、残りのメールを重複として削除するシングルインスタンス機能が備わっています。Exchange Server 2013においても同機能が備わっております。

重複と検出判断されたメールは、メッセージ追跡ログを見ると、2通目以降のメールには Source STOREDRIVER EventId DUPLICATEDELIVER が記録され、メールボックスには最初の1通だけ配送されます。
20150311_01

、同一のメッセージと見なされる条件は以下の通りです。

  • 同一のMessageIDヘッダであること
  • 同一のDateヘッダであること
  • 同一のメールボックスへの配送であること

参照:How does duplicate detection work? / Exchange 2007 で重複するメッセージを検出する方法

この機能自体は、ユーザー側のメールを読む負荷を軽減すると共に、メールのループ防止などの意味で重要な役割を担っているのですが、一定のケースで2通目以降のメールを受け取りたい場合があります。例えば、

  1. ウィルスが誤検知されて添付ファイルが削除されたメールをアンチウィルスソフトから再送する場合
  2. ユーザが誤って削除して復元できなくなったメールをジャーナルアーカイブから再送する場合
  3. システム上の制約で同じMessageIDで送信してくるメールを受信する場合
  4. Toに自身のアドレスが、Ccにメーリングリストが入っていて、メーリングリスト毎にフォルダ分けしている場合

などです。Exchange Server 2007/2010では、デフォルトで1時間の間このメッセージの重複を検知します。また、情報自体は7日間保存しております。この時間を変更する際には、レジストリの HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MSExchangeIS\<Server_Name>\Private-<GUID>\ 配下のDeliveredTo Expiration in Hours や DeliveredTo Cleanup Interval in Seconds を変更する事により変更することが可能でした。

ところが、Exchange Server 2013においては、検証する限りでこの設定が変更になっているようで、今までデフォルトでは1時間待てば配送されていた物が、7日間配送されないようになっておりました。また、今まで設定していたレジストリを設定してみても動作は変わりません

Microsoftのサポートに問い合わせて調査したところ、Exchange Server 2013 CU7現在、上記設定は7日にハードコーディングされており変更できなくなっているとのことでした。

Exchange Serverは、基本的にExchange Onlineと同じコードがベースになっているという話を聞いたことがあるので、Online側でカスタマイズ不可としてハードコーディングされているのであれば、それも考えられるかなとは思う反面、今までとデフォルト値を変更した上に設定変更も不可…というのはちょっと厳しいかなとも感じております。

最近、Exchange Onlineの挙動を見る限りでは、重複検出期間が24時間に仕様が変更になったっぽいので、オンプレも今後のCU8やそれ以降で挙動が変更にならないかどうか注視していきたいと思います。

関連記事: 重複メッセージの除去(Exchange Online)

ExchangeからEOPのSMTP配信速度のチューニング

Office 365のサービスの一つであるEOP(Exchange Online Protection)を利用すると、ハイブリッド構成時に受信時だけではなく送信時についてもspam判定を行うように構成をすることができます。

今回は、Exchangeハイブリッド構成時にOffice 365への通常のメール送信速度を理論上数倍にする方法をご紹介します。
20150226_01

Exchange Serverからの送信時のメールフローは、これにするかEdgeから直接出すかというほぼ2択になりますが、送受信でメールフローが同じでありシンプルだということもあり、この構成を取っている方も多いかと思います。

EOP を介した基本的なメール フローの設定に必要なコネクタを作成する などの記事を参照にこちらのEDGEサーバからExchange Online Protectionへの送信コネクタを作成します。サーバからEOPに円滑かつ継続的にメールを送信する為の注意点として、以下の記載が有ります。

  1. 1 接続当たりの送信電子メール数が 50 通以下
  2. 使用する同時接続数が 50 未満

今回は、この値を守りつつ、少しでもパフォーマンスを上げられるようにしていきたいと思います。

まず、1番です。こちらは送信コネクタのパラメータにSmtpMaxMessagesPerConnectionという値が有り、20に設定されています。

SMTP接続時のネゴシエーションに時間がかかるようであればこの値を大きくするのですが、インターネットを経由して送信していることもあってか、プロトコルログを確認する限りEdgeからEOPへの送信は、実際のメール送信に殆どの時間を費やしているのでこれを50などに増やしてもあまりパフォーマンスは向上しなさそうです。

次に2番。前提として、こちらの「同時接続数」の判定ですが、受信コネクタのMaxInboundConnectionPerSource の設定と同じように制御された場合、IPアドレスをベースにEOPに判定されてしまう可能性があります。複数台のEdgeサーバが同一のグローバルIPでNAPTして送信される場合は、50を台数で割った数字になるように調整しましょう。

この値は、Set-TransportService(Exchange 2010の場合はSet-TransportServer)のMaxPerDomainOutboundConnectionsで指定できます。デフォルト値は20になります。これだけ見ると、単一のスマートホスト先であるEOPへは、デフォルト設定でも20平行なのでそれなりにパフォーマンスが確保できるように見えますね。

が、実際に比較的メール流量が多い環境で利用すると、かなりEdge→EOPのパフォーマンスは低く、メールが滞留するポイントになりがちです。

なぜかというと、MaxPerDomainOutboundConnectionsというのはあくまで制限値であり、Exchangeがそこまで利用しようとするかとすると必ずしもそうではないからです。Edgeサーバ上でGet-Message -Queue [EOPへのキュー]などで挙動を観察してみると、キューの数が20までは1つのセッションで送信しようとして、それを越えると1つSMTPセッションを張るという挙動に見えます。
20150227_01

つまり デフォルトの制限値である20同時セッションになるにはキューが400通溜まる状態に、50同時セッションなら1000通までにならないといけない ことになります。そんな状態になったら、メールの配信遅延が顕在化してしまっている頃ですよね。

という訳で、ここをチューニングしてみたいと思います。

ここの数値ですが、コマンドの設定で変えられる設定は見つかりません。

色々と調べた結果、EdgeTransport.config にSmtpConnectorQueueMessageCountThresholdForConcurrentConnections パラメータを設定することにより、こちらをチューニングすることができました。

C:\Program Files\Microsoft\Exchange Server\V15\Bin\EdgeTransport.exe.config の<app Settings> </app Settings>の間に以下の値を入れます

<add key="SmtpConnectorQueueMessageCountThresholdForConcurrentConnections" value="新たにセッションを張る閾値"/>

例えば、デフォルトは20になりますので、値を5にした場合は理論上4倍の速度でセッションが張られて処理速度が向上することになります。
20150227_02

どんな値を設定したほうが良いかは、利用するリソースやメールサイズ等の特性によりケースバイケースだと思いますので、定期的にキューの状態やプロトコルログなどを確認していただいてチューニングするのがよろしいかと思います。