システム監視設計〜監視製品導入から運用までエトセトラ

# はじめに
コンテナ、AIの登場でシステム基盤と言われるインフラレイヤの技術も変化の波が押し寄せてきていますが、「システム監視」に対する重要性は変わりません。

個人のサービスから大規模システムまで、システム監視に対する本質は基本的に同じです。システム監視に正解はなく、そのシステムの特性や運用に応じて、求められるものが変わります。

本記事は、システム監視設計に係わる知見についてのまとめです。
監視製品導入から運用までを一連のフローとし、具体的に設計に落とす際の考慮点等（※）を記載しています。

![システム監視フロー.jpg](https://qiita-image-store.s3.amazonaws.com/0/221759/b85e1cd1-0205-c074-afb7-2ac485dd7b9d.jpeg)

（※）オンプレミス目線で書いているものが殆どですが、クラウドにも通じます。

**※本記事の内容は、あくまで考え方の一例であり、必ずしも全ての考え方がシステムに適合したり、ここに書いている内容で満たされている訳ではありません。**

## 要件の確認
システム監視は、広義でセキュリティ対策の一環に含まれると考えます。

家の防犯対策と同じで、監視カメラを導入することで防犯対策を行うことができますが、当然、導入コスト及び運用コストが発生します。セキュリティ対策を行う場合、費用対効果は必ずも発生しません。

実際のシステム設計では、明示的に要件に組み込まれている場合や、運用設計の中で設計することが多いです。

**まずはシステムにおける要件を確認すること。また、要件がある場合、監視対象について明確に定義すること。**

要件が確認できたら、次は目的を整理します。

## 目的の整理
システム監視の目的は大きく以下のような考え方があります。

- セキュリティインシデントやシステム障害発生時に、異常が起きたことを何らかの方法で通知する

- システムで発生する障害を検知し、障害発生時のダウンタイムを短くする（信頼性の確保）

- リアルタイムでの性能情報取得及び、キャパシティ管理を行いリソースの妥当性を確認する

**システムにおいて何を監視するか、目的を整理すること。**

目的が整理できたら、次は設計です。目的を実現するための手段を決定し、具体的に設計に落とし込んでいきます。

## システム監視設計
### 製品選定
システム監視の実現方法は、監視製品を導入して監視を行うことが一般的です。
今はOSSから有償なものまで様々な監視製品がありますが、どの製品も基本的な監視を行うために、使用しているプロトコルの技術は同じです。

例えば、ノード監視はICMPプロトコルを使用しています。性能情報はSNMPプロトコルを使用し、MIB情報を取得して監視をしています。

各監視製品を選定するにあたり、製品の違いにより考慮すべきポイントを以下に記載します。

- **製品仕様による機能差異**
A製品はできるけど、B製品だとできない。また、同じ機能を有しても仕組みが違うことがあります。よって、目的を満たすためにその製品が提供する機能で実現することができるか製品仕様を確認します。

- **UI（管理コンソール）**
どの監視製品でも管理コンソールと言われる管理画面があります。それぞれの監視製品毎に情報の見えかたや設定の仕方は違うため、使いやすいと思う製品を選ぶのがポイントです。評価版がある場合はインストールして試してみることもできます。

- **コスト**
有償なものを使用すれば、導入コストやサポートなど保守費用が発生します。
また、使い方を覚えるのにそのためのコストも発生します。導入から運用まで先を見据えて、どれぐらいコストがかかるかを抑えておきます。

- **その他監視ツールの組み合わせ**
システムで他に何の監視ツールを使用しますか？他に使用する監視ツールも合わせて考えると、美しい監視設計が描けると思います。

**目的を満たすための監視製品を選定する。**

導入する監視製品が決定したら、次は設計方針を考えます。

### 設計方針
確認した要件及び整理した目的をインプットとし、設計方針について考えます。
最終的には、設計方針を基に設定値に落とし込んでいくため、設計方針がシステム監視の基底になります。

#### 死活監視
- ping監視   
監視対象ノードの稼働状態について、ICMPプロトコルを使用してpingの応答からノードの稼働状態を監視します。

pingを実行するポーリング間隔がポイントです。ポーリングの応答確認の時間が長い場合、機器が停止したことに気付くのが遅くなります。

また、監視製品は登録するノードに1つのIPアドレスを指定します。その場合、複数インターフェースを持つノードの別のインターフェースは監視ができないため、障害発生時に気付くことができません。

よって、複数インターフェースを持つノードを監視する場合は、同じノードであってもすべてのIPアドレスを別のノードとして登録するか、SNMPプロトコルを使用してインターフェースのMIB情報を取得し、障害を検知するなどの仕組みが必要です。

- プロセス監視   
監視対象とするプロセスの状態や、プロセス数の上限及び下限の閾値を監視します。
システムを構成するミドルウェアで、停止するとサービスに影響があるプロセスを監視することが重要です。

#### 障害監視
- ハードウェア監視（SNMPトラップ）
抽象化されたシステムは物理的なハードウェアという存在が下層にあるため、オンプレミスのシステムの場合はハードウェアをどのように監視するか検討が必要です。
また、SNMPトラップを送信する場合、警告レベル以上はSNMPトラップを送信するなど、出力設定を適切に行うことが重要です。

- ログ監視（シスログ/ミドルウェア等）
システムの異常を検知する場合は、ログ監視は必須です。但し、監視すべきログが出力される状態であることが前提になります。

システム基盤において、サーバで出力するログは、システムログ（WindowsのイベントログやLinuxのシステムログ）や、ミドルウェア固有で出力するログがあります。その他、アプライアンスやNW機器等も監視対象（※）である場合、システムの各要素毎に何をどのように監視するか検討が必要です。

（※）監視製品を導入できない機器は、監視製品によりインストールレス監視のような機能もあるため、そのような機能を利用するか、あるいはsyslogを使用するなどして監視することができます。

#### 性能監視
- キャパシティ管理   
どの監視製品もリアルタイムで、CPU、メモリ、ディスク使用率等の各種性能情報を監視する機能があると思いますが、蓄積する機能は別な場合があるので注意が必要です。

例えば、リアルタイム監視の場合、監視している情報をメモリに保持している作りだと、キャパシティ管理で前日分のCPU情報が見たいといっても、製品として蓄積する仕組みがなければキャパシティ管理を行うことができません。

**よって、蓄積する仕組みがない場合は、何らかの方法で情報を蓄積する仕組みが必要です。**

- トラフィック情報   
トラフィック情報を取得する場合、インタフェースのカウンタ値を取得して監視を行いますが、ギガビットイーサネットのインタフェースだと、32ビットカウンタでは桁あふれして正常に情報取得できないことがあります。
基本的に監視対象の機器側に依存しますが、監視する側の監視設定、監視される側の製品仕様を確認しましょう。
- アプリケーション監視   
HTTPプロトコル等リクエストの応答結果から状態変化を監視します。アプリケーション監視を行うことで、応答結果から外的要因などの影響を検知することができます。

## 運用
システム監視の設計は監視製品を導入して、設定したら終わりではありません。
そこにシステムがある限り、延々と運用という名の螺旋階段を登っていきます。  

なので、いきなり細かくチューニングを行うよりも、スモールスタートで徐々にチューニングを行っていくことが望ましいです。

**但し、前提として、監視すべきログがそもそも出力されていて、かつ、通知ができていることが重要です。**

例として、監査ログを監視する場合、OS側の設定等で監査ログ機能が有効になっていないため、そもそも監視ができていない。あるいは、マルウェア感染時に通知が行われないなど、監視製品を導入しても効果が得られない場合があります。

このような場合は、監視すべきログが出力されていること及び、ウイルス対策製品の機能等でマルウェア検知時にメールを送信するなど通知ができていることが前提になります。

## その他
その他考慮しておくとよい設計ポイントやナレッジについて以下に記載します。

- 監視サーバの冗長化   
監視を行うサーバがダウンすると、監視機能が停止します。必要に応じて冗長化を検討します。
- 監視サーバのディスク容量    
監視サーバで監視した情報を蓄積する場合、ディスク容量が満たせることの見積もりを行います。
- 適切な監視設定   
一時的に大量のメッセージが出力されるなどして、監視している情報が消えてしまっては意味がありません。大量メッセージ発生を考慮し、メッセージが全て補完できるように出力設定の見直しや、定期的にメッセージのログ等をバックアップするなど運用を行いましょう。
- SNMPトラップ文字化け   
SNMPトラップが文字化けする場合は、SNMPトラップ送信元で、Octet String のverbind部分に、バイナリデータが入っている場合、製品によってはソフトウェアのコード変換に対応していないと正常に表示されないことがあります。
- rshの通信   
パトランプを使用するシステムで、パトランプに対してrshで通信する場合は、監視サーバからパトランプは514ポートが使われますが、送信側も空いている1000番台のポートが使われることが多いので考慮が必要です。
- トラブルシューティング    
SNMPの通信が上手くいかない場合は、FW＞TCP Wrapper＞SNMPの設定（コミュニティ名等）を確認しましょう。

## 参考（SNMPとMIB）
監視製品で使用されるSNMPプロトコルとMIBについて簡単に解説します。

### SNMP
SNMPはIPネットワーク上の機器を監視するための通信プロトコルです。
SNMPを使用するためには、SNMPエージェントが導入されていることが前提となります。

アーキテクチャは、ネットワークを管理するシステムをマネージャと呼び、管理対象の機器をエージェントと呼びます。SNMPのバージョンは大別すると以下の３種類に分けることができます。

- SNMP v1
- SNMP v2c
- SNMP v3

SNMP v1及びSNMP v2cでは、コミュニティ名と言われる、監視対象をグルーピングするための文字列を指定します。同じコミュニティに属するホスト間でのみ通信することができます。コミュニティ名は、読み出し専用と読み書き可能の2つの権限に対して、別々のコミュニティ名を設定することができます。

SNMP v1とSNMP v2の場合、コミュニティ名は暗号化されず平文で通信が行われるため、脆弱性があります。

推奨は、ユーザ単位で暗号化されたパスワード認証を行うSNMP v3ですが、今でもSNMP v2cが広く使用されています。

**コミュニティは単なる文字列ではなく、パスワードと同じレベルで取り扱うことが重要です。**

デフォルトは殆どpublicになっていることが多いので、snmpの脆弱性を突かれると空いているポートやインストールしているソフトなど色々な情報が盗まれるリスクが存在することになります。

また、セキュリティ以外ではSNMP v1とSNMP v2で例として以下のような違いがあります。

SNMP v1のSNMPトラップの場合、SNMPトラップデータ中のAgent Addressフィールドに設定されたエージェントアドレスを送信元IPアドレスとして処理します。
SNMP v2cのSNMPトラップの場合、SNMPトラップのデータ部に送信元IPアドレスは存在しません。

SNMPを使用していて、その他監視製品等で送信しているエージェントアドレスが本来のエージェントと異なる場合は、SNMPバージョンの違いにより、トラップ形式が異なることが原因だったりします。

Linuxを例にsnpmdの設定例について以下に示します。
snmpdはnet-snmpというパッケージによって提供されます。


**snmpd.conf設定例**

```bash
#       sec.name  source          community
com2sec MyNetwork 192.1.2.3 MyCommunity

#       groupName      securityModel securityName
group MyGroup  v1         MyNetwork
group MyGroup  v2c        MyNetwork
group MyGroup  usm        MyNetwork

#       name           incl/excl     subtree         mask(optional)
view    all    included   .1

#       group          context sec.model sec.level prefix read   write  notif
access  MyGroup        ""      any       noauth    exact  all    none   none
```

1. **com2sec**の右から、セキュリティ名が「MyNetwork」、アクセス許可範囲をIPアドレスで「192.1.2.3」、コミュニティ名を「MyCommunity」を設定。
2. **group**の右から、グループ名が「MyGroup」、セキュリティモデルを「v1/v2c/usm」、セキュリティ名が「MyNetwork」を設定。
3. **view**の右から、mibに対してアクセスできる範囲（取得可能なOIDの範囲）を設定。（上記.1の場合だと全て許可する）
4. **access**の右から、セキュリティモデルに対して権限を設定。

### MIB
SNMPとMIBは混合すると分かりづらいですが、全く別の概念です。

MIBは管理情報ベース（Management Information Base, MIB）と言われる、データベースの一種であり、データベース内のオブジェクトの集合体から構成されています。SNMPで監視するということは、SNMPプロトコルを使用してMIB情報にアクセスすることで、オブジェクトの情報を見たり、しきい値監視を行ったりすることができます。

**MIBは、DNSプロトコルのドメインツリーと同じで、ツリー構造の考え方を基に作られています。OIDと言われるオブジェクトIDを辿ることで、それぞれの情報にアクセスできます。**

MIBは標準MIBと拡張MIBがあります。
標準MIBは、MIB1とMIB2があり、現在ではMIB2がデファクトスタンダードです。拡張MIBはベンダ固有のMIBで、拡張MIBにアクセスすることで独自のMIB情報を利用した監視を行うことができます。また、監視製品によっては拡張MIBを登録することで、SNMPトラップ受信時にOIDが変換されて少し見やすくしたりすることができます。

![mib.jpg](https://qiita-image-store.s3.amazonaws.com/0/221759/59574d3a-7809-45a9-ec1d-b82d5f857fb5.jpeg)

**snmpwalk実行例**

Net-SNMPは独自のMIBツリーとして、「.1.3.6.1.4.1.2021」として定義されている[ucdavis MIBオブジェクト](http://www.net-snmp.org/docs/mibs/ucdavis.html)があります。その中の、サブツリーとして「.1.3.6.1.4.1.2021.11」にはシステムの状態に係るMIB情報を見ることができます。

```bash
# snmpwalk -v 2c -c MyCommunity localhost 1.3.6.1.4.1.2021.11
UCD-SNMP-MIB::ssIndex.0 = INTEGER: 1
UCD-SNMP-MIB::ssErrorName.0 = STRING: systemStats
UCD-SNMP-MIB::ssSwapIn.0 = INTEGER: 0 kB
UCD-SNMP-MIB::ssSwapOut.0 = INTEGER: 0 kB
UCD-SNMP-MIB::ssIOSent.0 = INTEGER: 0 blocks/s
UCD-SNMP-MIB::ssIOReceive.0 = INTEGER: 0 blocks/s
UCD-SNMP-MIB::ssSysInterrupts.0 = INTEGER: 9 interrupts/s
UCD-SNMP-MIB::ssSysContext.0 = INTEGER: 13 switches/s
UCD-SNMP-MIB::ssCpuUser.0 = INTEGER: 0
UCD-SNMP-MIB::ssCpuSystem.0 = INTEGER: 0
UCD-SNMP-MIB::ssCpuIdle.0 = INTEGER: 99
UCD-SNMP-MIB::ssCpuRawUser.0 = Counter32: 1325
UCD-SNMP-MIB::ssCpuRawNice.0 = Counter32: 5
UCD-SNMP-MIB::ssCpuRawSystem.0 = Counter32: 8847
UCD-SNMP-MIB::ssCpuRawIdle.0 = Counter32: 9703683
UCD-SNMP-MIB::ssCpuRawWait.0 = Counter32: 1263
UCD-SNMP-MIB::ssCpuRawKernel.0 = Counter32: 0
UCD-SNMP-MIB::ssCpuRawInterrupt.0 = Counter32: 0
UCD-SNMP-MIB::ssIORawSent.0 = Counter32: 135954
UCD-SNMP-MIB::ssIORawReceived.0 = Counter32: 418996
UCD-SNMP-MIB::ssRawInterrupts.0 = Counter32: 893230
UCD-SNMP-MIB::ssRawContexts.0 = Counter32: 1360615
UCD-SNMP-MIB::ssCpuRawSoftIRQ.0 = Counter32: 548
UCD-SNMP-MIB::ssRawSwapIn.0 = Counter32: 0
UCD-SNMP-MIB::ssRawSwapOut.0 = Counter32: 0
UCD-SNMP-MIB::ssCpuRawSteal.0 = Counter32: 0
UCD-SNMP-MIB::ssCpuRawGuest.0 = Counter32: 0
UCD-SNMP-MIB::ssCpuRawGuestNice.0 = Counter32: 0
```

# さいごに
たかだか監視ですが、されど監視です。
SNMPプロトコルは、Simple Network Management Protocolという略称ですが、奥が深いです。

監視に対する知識を身につけ、よりよい監視システムを作りましょう。