Zabbix+snmptt: NW機器でwriteしたコンフィグを外部サーバに自動的にバックアップする。

#やりたいこと
NW機器のコンフィグ修正したとき、copy run startぐらいはするけど、
修正したコンフィグを管理サーバに保管(バックアップ)するのって忘れちゃうよね！って方おられませんか？

私はそんなタイプの人間なので、今回はcopy(write)コマンド発行すると、自動でtftpサーバにバックアップする仕組みを作ってみた。

ざっくりとした動きは以下6ステップ
1. CISCOルータでwriteコマンドをタイプしたとき、ルータがトラップ発報する。
2. Zabbixでトラップを受けて、「障害状態」(バックアップ未実施)とする。
3. Zabbixのtrigger でSNMPTRAPの内容を条件判断( tftpでバックアップする以外の動作であれば反応するようにする)
4. Zabbixのactionで、上記triggerが反応すれば、スクリプトを実行
5. スクリプトでCISCOルータのstartupコンフィグをtftpでバックアップする。
6. バックアップ出来たら、Zabbixでトラップを受けて、「障害復旧状態」(バックアップ実施済)とする。

#登場人物
1. 監視サーバ　Zabbix(snmptrapd+snmptt)(ip=192.168.99.18)
- NW機器　Cisco(今回は1812J)   (ip=192.168.99.2)
- バックアップサーバ　TFTPサーバ(ip=192.168.99.18)

# 前提
* Zabbix(zabbix-server/snmptrapd/snmptt)が稼働していること
* ZabbixでSNMPTRAPが受信できる状態であること
* バックアップ(tftp)サーバが存在して、CISCOからのコンフィグのTFTP転送が受けることができること。

# CISCOルータ側作業

##NW機器のSnmptrap設定

```ruby:SNMPTRAP設定
snmp-server host 192.168.99.18 version 2c public
snmp-server enable traps config
snmp-server trap-source FastEthernet0
```
(1行目)TRAP発報先の設定
(2行目)TRAP発報内容の設定
(3行目)TRAP発報の送信元インターフェース設定

* Zabbixの場合、trapのsourceIPが監視対象ホストのIPに一致しないと表示されないので注意。

### 設定反映を以下で確認。

```ruby:CISCOルータでcopyコマンド実行
Router#copy startup-config tftp://192.168.99.18/192.168.99.2.cfg
Address or name of remote host [192.168.99.18]?
Destination filename [192.168.99.2.cfg]?
!!
1503 bytes copied in 0.064 secs (23484 bytes/sec)
Router#
```
上記実行後、Zabbix側にトラップ(ccmHistoryMaxEventEntries)が飛ぶことを確認
加えて、TFTPサーバにコンフィグが保存されてることも確認

# サーバ(OS/SNMP/SNMPTT)側作業
## CISCOのMIBファイルの設置

mkdir /usr/share/snmp/mibs/cisco
このディレクトリに以下2ファイル設置

|MIBファイル|備考|
|----|----|
|cisco-config-man.mib|コンフィグ保存時のトラップ格納|
|cisco-smi.mib|CISCO用MIBの繋ぎ役(Structure of Management Information)|

## CISCOのMIBファイルを認識させる

```ruby:/etc/snmp/snmp.conf
mibdirs /usr/share/snmp/mibs:/usr/share/snmp/mibs/cisco
mibs ALL
```

## CISCOのMIBファイルの認識を確認してみる。

```ruby:snmptranslateコマンド(oid出力を確認)
snmptranslate -On -IR ccmHistoryMaxEventEntries
.1.3.6.1.4.1.9.9.43.1.1.4
```

## snmpttで使用するトラップ設定ファイルを作成
### トラップ抽出作業

```ruby:snmpttconvertmibコマンド
snmpttconvertmib --in=/usr/share/snmp/mibs/cisco/cisco-config-man.mib --out=output
```
### 上記で抽出したファイルをsnmpttで使用できるように加工
* FORMAT行の中身に文字列"ZBXTRAP $aA"を追記
* /etc/snmp/snmptt.{mibファイル名}.confに作成

```ruby:FORMAT行の加工
cat output | sed 's/^FORMAT /FORMAT ZBXTRAP $aA /' > /etc/snmp/snmptt.cisco-config-man.conf
```
```ruby:実際出力された/etc/snmp/snmptt.cisco-config-man.conf
#
MIB: CISCO-CONFIG-MAN-MIB (file:/usr/share/snmp/mibs/cisco/cisco-config-man.mib) converted on Sun May 14 06:52:01 2017 using snmpttconvertmib v1.4beta2
#
EVENT ciscoConfigManEvent .1.3.6.1.4.1.9.9.43.2.0.1 "Status Events" Normal
FORMAT ZBXTRAP $aA Notification of a configuration management event as $*
SDESC
Notification of a configuration management event as
recorded in ccmHistoryEventTable.
Variables:
  1: ccmHistoryEventCommandSource
  2: ccmHistoryEventConfigSource
  3: ccmHistoryEventConfigDestination
EDESC
```
上記confを見てわかるように、トラップメッセージの最後から２つのカラムには、
最後から2番目：ccmHistoryEventConfigSource(copy元)
最後から1番目：ccmHistoryEventConfigDestination(copy宛先)

つまり、
"copy run start"すると、メッセージは"~~~~ running startup"
"copy start tftp:~"すると、メッセージは"~~~~ startup networkTftp"
となる。

## 先ほど出力したトラップ設定ファイルをsnmpttに認識させる。
snmptt.iniファイルの"snmptt_conf_files"に、先ほど作成したconfファイルを追記し、restartする。

```ruby:/etc/snmp/snmptt.ini
ファイルの一番最後に以下の行を追記
[TrapFiles]
# A list of snmptt.conf files (this is NOT the snmptrapd.conf file).  The COMPLETE path
# and filename.  Ex: '/etc/snmp/snmptt.conf'
snmptt_conf_files = <<END
/etc/snmp/snmptt.cisco-config-man.conf    <----- この行を追加
END
```
最後に、SNMPTTリスタート(systemctl restart snmptt)する。

# Zabbixサーバ(Zabbix-WEB)側作業

##監視サーバ設定(item/trigger)
### host設定(ipとホスト名)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/82244/bbc156af-ee52-9ce3-9d90-87b416500c50.png)

### host設定(macro)
ここでは、 ciscoへのtelnetアクセス情報( user/pass/enable-pass すべて ciscoとする)を定義する。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/82244/da7dfc59-53db-5ad4-24b1-4b901210f20a.png)

### item設定
CISCO機器から発報される特定トラップ(ciscoConfigManEvent)をアイテムとして登録する。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/82244/e6d22b6f-8515-9843-94e9-bfc250b5ba58.png)

### trigger設定
先ほどのイベントの中で特定文字列(startup networkTftp)が含まれていない場合、障害とする。
つまり、ActionのTFTPバックアップ(start->tftp)以外、 copy run start等は障害となる。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/82244/c4dd254d-d69a-70b5-7b3a-a2bbf7efead2.png)

##監視サーバ設定(Action/アクションスクリプト)

##監視サーバ設定(Action)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/82244/1ef9b4ec-57d4-2490-0bc6-7f4cd37df5b1.png)

```ruby:コマンド内容
/usr/local/bin/backupCiscoConfig.pl {HOST.IP} {$TELUSER} {$TELPASS} {$EXEPASS}
```
第一引数は、hostのipアドレスのマクロ(ここでは、SNMPTRAPを発報したルータIP)
第２引数以降は、ホスト設定(macro)で設定したマクロ情報を使用

##監視サーバ設定(アクションスクリプト)
手抜きですが、とりあえず動きます。

```ruby:/usr/local/bin/backupCiscoConfig.pl
#!/usr/bin/perl
use Net::Telnet::Cisco;

my $backup_host = "192.168.99.18";

my $session = Net::Telnet::Cisco->new(Host => $ARGV[0]);
$session->login( $ARGV[1], $ARGV[2]);

if ($session->enable( $ARGV[3]) ) {
    @out = $session->cmd("copy startup-config "
                        . "tftp://$backup_host/".$ARGV[0].".cfg\n\n\n");
    print "Result: @output\n";
} else {
    warn "Can't enable: " . $session->errmsg;
}

$session->close;
```

#実際に動くことを確認


### CISCOルータにログインして、writeコマンド発行

```ruby:CISCOルータ
Router#write
Building configuration...
[OK]
Router#
```

### tftpサーバにコンフィグファイルができることを確認

```ruby:TFTPサーバのコンフィグファイル確認
[root@sv ~]# ls -l /var/lib/tftpboot/192.168.99.2.cfg
-rw-rw-rw- 1 nobody nobody 1503 May 14 07:43 /var/lib/tftpboot/192.168.99.2.cfg
[root@sv ~]#
```

### Zabbixのイベントログを確認

![image.png](https://qiita-image-store.s3.amazonaws.com/0/82244/fcf2721a-5e64-11dd-6c00-91b41679861c.png)

2行目:  (障害)writeコマンド発行したことで、ルータが発報するトラップ( running -> startup)
1行目:  (復旧)Zabbixのアクションでcopy run tftpコマンド発行したことで、ルータが発報するトラップ( startup -> networkTftp)

### (おまけ)SNMPTTログを確認

```ruby:snmpttのログ
07:43:40 2017/05/14 ciscoConfigManEvent Normal "Status Events" 192.168.99.2 - ZBXTRAP 192.168.99.2 Notification of a configuration management event as commandLine running startup
07:44:07 2017/05/14 ciscoConfigManEvent Normal "Status Events" 192.168.99.2 - ZBXTRAP 192.168.99.2 Notification of a configuration management event as commandLine startup networkTftp
```

# 最後に
記載項目多すぎて、まとまりがなくなってしました。
今後、項目ごとにまとめようと思います。