ノーヒントサーバ調査(Windowsサーバ編)

# **はじめに**

本記事は **[NSSOL Advent Calendar 2018](https://qiita.com/advent-calendar/2018/nssol)** の17日目の記事です。
今回は、大きく以下の2つのきっかけから本記事を執筆しました。

- 社内でAdvent Calendarのコンテンツを議論する中で、16日目の[ノーヒントサーバ調査(Linux編)](https://qiita.com/t_nakayama0714/items/9348e215f172562974e6)との**コラボ**企画のアイディアが浮かんだこと。
- 私自身がWindows技術者であり、トラブルシュートによく巻き込まれるため、~~頭の整理~~ 今後の効率化のために文章としてまとめたかったこと。


# **対象環境**

- Windows Server 2008R2～Windows Server 2012R2

※Windows Server 2016以降は、私自身が調査したことがないため対象外としています。ただし、おおむね使えると思います。

# **調査のゴール**

ゴール設定についてはLinux編と同様ですが、再掲します。
調査の内容が指定されていればいいのですが、今回はそうでもありません。
善良なるサーバ管理者の気持ちで、以下をゴールと定めてみましょう。

- **サーバの今がわかる**
    - 「現在サーバがどうなっているか」に答えられるようになる
    - 現状調査の方法理解が必要
        - サーバスペック / サーバ構成 / リソース状況 / ...
- **サーバの過去がわかる**
    - 「過去サーバがどうなっていたか」に答えられるようになる
    - 主にログの読み方理解が必要
- **サーバの未来がわかる**
    - 「今後サーバがどうなりそうか」に答えられるようになる
    - もちろんここは推論が入る


# ***心構え*** : Windows Serverで調査する際のポイント
- **偏見をなくした調査が重要**
 - トラブルシュートの基本かもしれませんが「当然ここぐらいは調査済だろう」とか、「設定は当然しているだろう」という思い込みは、なくすべきです。

- **ActiveDirecory(権限周り)を抑えておく**
    - 便利なのですが、知らない人には鬼門のActiveDiretory周りの設定(GPO含む)は、確認しておくことをお勧めします。強い権限だと、なんとなくでも動いてしまうので、特に注意が必要です。
    - アカウント権限、パーソナルファイヤーウォール有無、UAC有無あたりは、最初に確認しましょう。 
    - 調査用アカウントの権限についても注意が必要です。使用するアカウントによって再現性が異なるケースもあり得ます。

# ***事前準備*** : ヒアリングとツール準備

ノーヒントといえど、実機調査に先立って必要最低限の情報＋αをヒアリングしましょう (そういうノーヒントじゃない)

- 最低限確認しておきたい情報
    - 対象サーバのIPアドレス
    - アカウント＆パスワード
    - サーバ間の連携がおかしいのであれば通信相手のIP

また、調査対象自体の情報ではありませんが、以下のようなことも一応確認しておくと、調査を進めるうえで実施する諸々の作業をスムーズに進められると思います。

- 作業を進めるうえで知っておきたい情報
    - 対象サーバへの接続経路
    - 調査用に利用可能な端末
    - 作業としてやってよい範囲
    - 作業実施の承認要否(要の場合は承認済みかどうか)

可能であれば以下のような情報も確認して、発生している事象の全体像をあらかじめ把握したいところです。ただし、本記事では状況設定として**情報なし**を前提に記載します。

- 事象の全体像をつかむうえで整理したい情報
    - (Who)誰が : どのシステムが？(＝お客かも)
    - (What)なにが起きているか : 事実を聞く
    - (When)いつからおかしいか : 気づいた時間
    - (Where)どこでおかしいか : どのサーバが？またはサーバ間通信が？
    - (Why)なぜ : 問題の原因(=推測や論理的推察) 
    - (How)どのように : 問題の経緯

上にも書きましたが、**調査用として受け取ったアカウントの権限**は、最初に確認することが重要です。この点に関して、明確な情報が提供いただけない場合、他のヒアリング内容の精度についても同じレベルである可能性があるので、それを加味して調査を行う必要があります。また、提供された情報が何らかの理由で実機と異なる可能性もあるので、実機から情報を取得して、リバースエンジニアリング的に調査できる力も必要です。ありがちなのが、調査対象サーバだけでなくActiveDirecotryのGPOやOUなどを見なければいけないケースです。

ここから先は、**準備していたら調査が便利になるツール類**についてご紹介します。 ※各ツールの詳細は割愛します。

- **[SysInternal Tool](https://technet.microsoft.com/ja-jp/sysinternals/bb545021.aspx)**
    - Process Monitor 
    - TCPView 
    - Process Explorer
    - PSList 
    - (PortQryV2) ※Windows Server 2012からはPowerShellで代替可能

# ***調査作業***
## 調査の観点
- このサーバの現在はどうなっているのか？
調査対象としては、以下のようなものがあります。本記事では、**現在調査 : ～通信～**について深堀します。
    - 通信状況
    - プロセス有無
    - サービス有無
    - リソース情報
 

- このサーバの過去はどうなっているのか？
調査対象として、は以下のようなものがあります。本記事は、**過去調査 : ～ログ～**について深堀します。
    - 各種ログ
    - 修正プログラムの適用履歴
   
- このサーバの未来はどうなるのか？
少し先のふるまいを予測するための情報収集の仕組みとしては以下のようなものが考えられます。これらはこのテーマだけでかなりのボリュームとなってしまうため、今回は割愛します。
    - perfmonでの情報取得
    - デバックログやダンプの仕掛け

## 現在調査 : ～通信～
- **構成の確認 : マルチホーム、ルーティング、名前解決系**
最初に、調査対象サーバのネットワーク的な構成について確認することをお勧めします。通信要件一覧、IPアドレス一覧表など、ドキュメントが存在しているのが好ましいです。Windows Serverに絞った時のポイントですが、特定のケースでマルチホーム構成が非推奨とされていたり、通信確認に用いる手段によって、想定される動作が異なるケースがあります。NICが冗長化されている場合には、チーミング構成についても確認しましょう。

    - [WindowsのDNSリゾルバーの仕様](https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/dd197552(v=ws.10))
：nslookupの動きとpingの動きがある条件下で異なります。こういうのは、忘れた頃にハマります。
    - [ActiveDirectoryはマルチホーム非推奨](https://blogs.technet.microsoft.com/jpntsblog/2016/05/12/windows-server-%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%83%9E%E3%83%AB%E3%83%81%E3%83%9B%E3%83%BC%E3%83%A0%E6%A7%8B%E6%88%90/)
：有名な話ですが、まれにこの点を把握せずにマルチホーム構成をとってしまっているケースも見受けます。マルチホーム構成をとる場合は、いろいろと注意事項があるので、必ず確認しましょう。

- **通信の調査方法 : 基本編**
通信出来ていないかも？という時には、**どのレイヤーまで到達しているか**を確認しましょう(OSI参照モデルを念頭に置いています)
    - サーバ間での疎通については、すくなくともpingレベル(レイヤ3)と、UDP/TCPレベル(レイヤ4)での疎通可否を確認したいところです。
    - 疎通出来ない場合、以下のような観点で切り分けを進めます
        - 受信側サーバのポート待ち受け状態(listen状態か)の確認をしましょう。
        - ファイヤーウォールで落としていないか？
        - 送信側サーバから送信出来ているか？
        - 途中経路で落とされていないか？


<details><summary>コマンド例 : ポート確認例 </summary><div>

 - PowerShellのTest-NetConnectionで、ポート番号指定での疎通確認が可能です。
 - 従来は、telnetやPortQryV2を使っていたのですが、今はこれが便利です。

```powershell:Test-NetConnectionのTCPPort
      Test-NetConnection RemoteHost -port 80

ComputerName     : RemoteHost 
RemoteAddress    : 192.168.1.2
RemotePort       : 80
InterfaceAlias   : Ethernet0
SourceAddress    : 192.168.0.1
TcpTestSucceeded : True
```

 - 同じコマンドレットでTraceRouteなども出来ます。

```powershell:Test-NetConnectionのTraceRoute
Test-NetConnection -ComputerName RemoteHost -TraceRoute

ComputerName           : RemoteHost 
RemoteAddress          : 192.168.1.2
InterfaceAlias         : Ethernet0
SourceAddress          : 192.168.0.1
PingSucceeded          : True
PingReplyDetails (RTT) : 2 ms
TraceRoute             : 192.168.0.254
```

 - 参考までに、従来のportQry.exeのコマンド例

```powershell:PortQry.exe
PortQry.exe -n RemoteHost -e 53 -p TCP

Querying target system called:
 RemoteHost 
Attempting to resolve name to IP address...
Name resolved to 192.168.1.2
querying...
TCP port 80 (unknown service): FILTERED
```
</div></details>


   - Windows ServerはLinuxなどに比べて**パーソナルファイヤーウォール設定やウィルス対策ソフト**が入っていることが多いです。したがって以下のような観点での切り分けも有効な場合があります。
       - ファイヤーウォールログやウィルス対策ソフトでDenyLogが発生していないか。
       - 上記情報はイベントログとは違うところで出力されるので注意が必要です。

サーバの通信に関して、「リリース時に通信できていたので今も通信できるはずだ。」と期待したくなることが多いですが、**タイミングの問題などで期待とは異なる振る舞いをするケース**があるので注意しましょう。

<details>
<summary>以下は私が実際に遭遇した事例</summary>
 　例1 : 再起動したタイミングで疎通できなくなった。**設定変更の反映が再起動後だった**ため。
　例2 : **サービスは起動しているのだが、ポートがlistenしていなかった**。サービス起動タイミングの問題。ログにも何も出てきません。
　例3 : ファイヤーウォールがドメインポリシーで動いていたのに、**プライベートポリシーに切り替わった**。理由は不明。
</details>


- **通信の調査方法 : 応用編**
Microsoft固有の通信は、**権限**が大きく絡んでくることが多いです。そのため、**どのアカウントで事象が発生しているか**を強く意識することが重要となります。コンピュータが通信するということは、「Network Serviceアカウントが通信しているケース」など、が多いのでそういう点も注意が必要となります。

   - Domain Adminsや、(Local)Administoratorsの違いを意識して、個々の権限をもったアカウントで切り分けをすること
   - (リモート)UACが邪魔をしているケースも多々あるので、UACの有無を確認すること
   - GPOやローカルグループポリシーのセキュリティポリシーで、デフォルトから変更されているケースも意識すること

## 過去調査 : ～ログ～
- **ログの調査方法 : 基本編**
読むログの種類としては、「System」と「Application」の二種類で基本的には大丈夫です。細かいログを見なければいけないケースもありますが、そういったケースは稀なので、深い調査が必要となる時以外は見なくてもよいと思います。最近は**管理イベント**という便利なモノがあるので積極的に活用するとよいと思います。ログを読み解く上でのポイントとしては以下のようなものがあります。
   - Windows Serverはエラー&警告のログが多いです。無視してよいエラーも多いことから、エラー＝怪しいとは思わないことです。(例えば、DCOM関連はわりとよくあるエラー)。その前提で読み解くべきです。
   - 一方で、Informationレベルで重要なログもあります。しれっとサービス停止がInformationだったりします。
   - ~~ただひたすら眺めても眠くなるので、~~以下のような箇所を特に注意深して読むことで有益な情報が得やすくなります。
      - **エラー前後のログ**
      - **再起動直後のログ**
      - **問題があった前後時間帯のログ**

- **ログの調査方法 : 応用編**
   - メッセージの出現頻度やエラー発生時期を読み解くことで、発生している事象を理解しやすくなります。
   - 上記を目で確認したり整形するのは、時間がかかります。専用ツールが望ましいですが、PowerShellでも簡単に整形して表示することが可能です。。

<details><summary>コマンド例 : PowerShellによるログ出現頻度確認</summary><div>

Get-EventlogでイベントログのSystemをエラーと警告を表示。それを同じイベントログIDをGroup化して、頻度の確認が可能です。

```powershell
  Get-EventLog -LogName System -EntryType Warning,Error |
     Group-Object -Property InstanceID

Count Name                      Group
----- ----                      -----
   17 1085                      {System.Diagnostics.EventLogEntry, System.Diagnostics....
    3 6038                      {System.Diagnostics.EventLogEntry, System.Diagnostics....
  211 10016                     {System.Diagnostics.EventLogEntry, System.Diagnostics....
```

上記だけだとメッセージがわからないので、メッセージも含めてきれいに表示するなら、こういうコマンドのやり方があります。さすがに長いので、ここまで行くと覚えて打つことは厳しいですが。

```powershell
  Get-EventLog -LogName System -EntryType Warning,Error |
     Group-Object -Property InstanceID |
       select count,name,@{Name="EntryType";Expression={$_.Group.EntryType[0]}},@{Name="Message";Expression={$_.Group.Message[0]}}


Count Name       EntryType Message
----- ----       --------- -------
   17 1085         Warning Group Policy Registry の設定を適用できませんでした...
    3 6038         Warning Microsoft Windows Server とクライアントの間で、...
  211 10016          Error ソース 'DCOM' のイベント ID '10016' の説明が見つかりません...
    6 40961        Warning サーバー xxxとのセキュリティで保護された接続...
    2 3221232503     Error xxxサービスは予期せぬ原因により終了しました...
```
</div></details>

# ***最後に***

コラボしてくれた@t_nakayama0714さん、
推敲してくれた@yamamorisobaさん。

皆様のおかげでこの記事を投稿できました。ここにお礼を申し上げます。

また、本記事が、見てくれた方の何かしらの役に立てればと思います。
そんな調査じゃ何もわからない！こうやったほうがより有用なのに！というのもあると思います。
是非、ご意見ください。