cisco機器のゼロタッチ展開

## はじめに
工場出荷状態のCisco機器時をネットワークへ接続するだけで、利用可能な状態にする。
設定はTFTPサーバに登録しておき、シリアル番号に応じたコンフィグを自動適用する。
これにより新規設置や保守交換時の作業を大幅に削減する。
これをCiscoのCNSやサードパーティ製アプリケーションを利用せずにフリーのツールのみを利用して実現できないか、と考えました。


## 対象機器及び環境
CiscoルータやL3SWなど、IOSが動作する機器を対象としています。

以下環境で検証しています。
* DHCPサーバ（CentOS7 7.6.1810）
* TFTPサーバ（CentOS7 7.6.1810）
* Ciscoルータ（1812J）


## このエントリを読むとできること
* Ciscoルータを工場出荷状態で購入して（なんなら中古で買ってコンフィグ消去したものでもOK）
* IPリーチャブルな環境に接続すると
* 遠隔から全自動でコンフィグを投入して
* エッジルータとして機能するようになる

はず。

## 関連するエントリ
* [CentOS7で各種ネットワークサービスを基本設定したメモ（dhcp/radius/proxy/tftp/syslog）](https://qiita.com/haruca_tech/items/2bf96ae84ebb5c84ba7d)


## 概要

### 考え方
Cisco製機器はブート時にDHCPでアドレスを要求するシーケンスが走る。
その際、TFTPサーバからブートファイルを読み込んでPXEブート（？）することもできる。
MACアドレスに紐づいたDHCP応答は広く知られているが、使いまわしのNW機器はMACアドレスはパッと見ではわからない。
工場出荷状態のMACアドレスも段ボールに記載されているが、「それはどのIFなんだ？」となってしまうため、よくわからない。

機器のシリアル番号であれば、機器にシールで貼り付けてあるし、きちんとした保守契約を結んでいれば、保守会社で出荷情報として開示してもらうこともできそうだ。
ならば、ブート時にはどんな機器にでも対応できるコンフィグを読み込ませてから、機器のシリアルを自動的に取得し、それに応じたファイルを取りに行けばよさそうだ。
そしたら、新規設置だろうが保守交換だろうがゼロタッチによる展開ができそう。


## 導入

###  Cisco機器

WAN収容セグメント：10.1.254.0/24 で構成されている場合、エッジルータのどこか１か所でよいので、DHCPヘルパーの設定を入れておく。

```bash:show_run_inter_vlan_2254
interface Vlan2254
 description ### HQ_Network_Management ###
 ip address 10.1.254.254 255.255.255.0
 ip helper-address 10.254.10.251
```

### 注意点
ゼロタッチ展開したいCisco機器を接続するセグメントではブロードキャスト設定(ip broadcast-address)を投入しないこと。
投入してしまうと、初回のブートシーケンス時にDHCPでアドレスの払い出しは完了するが、起動後のDHCPによるアドレスの払い出しは完了しないので、注意。
なぜかDHCPOFFERはDHCPサーバから飛んでいるが、DHCPACKが返ってこず、払い出しが完了しなかった。


###  DHCPサーバ

構築済みの **[DHCPサーバ](https://qiita.com/haruca_tech/items/2bf96ae84ebb5c84ba7d)** に、以下を追記する。

WANが広域イーサなどL2VPNで構築されており、各拠点のエッジルータで単一ネットワークアドレスとする。

```
# vi /etc/dhcp/dhcpd.conf
-----8<-----snip-----8<-----
subnet 10.1.254.0 netmask 255.255.255.0 {
  range 10.1.254.201 10.1.254.210;
  option subnet-mask 255.255.255.0;
  option routers 10.1.254.254;
  #TFTPサーバを指定
  next-server 10.254.10.251;
  #初期コンフィグを指定
  filename "cisco/autoinstall";
}
-----8<-----snip-----8<-----
# systemctl restart dhcpd
```


### TFTPサーバ

構築済みの **[TFTPサーバ](https://qiita.com/haruca_tech/items/2bf96ae84ebb5c84ba7d)** をベースにして、以下の修正を入れる。

#### コンフィグの配置

|ファイル|役割|
|:-:|:-:|
|/var/lib/tftpboot/cisco/autoinstall|最小構成のコンフィグ|
|/var/lib/tftpboot/cisco/serial/FHKxxxx.config|機器SNに対応するコンフィグ(FHKxxxは機器SN)|


上記ファイル群を収容するディレクトリをつくっておく

```
# mkdir -p /var/lib/tftpboot/cisco/serial
# chmod -R 777 /var/lib/tftpboot/cisco/
```

#### コンフィグ

`# vi /var/lib/tftpboot/cisco/autoinstall`

```bash:/var/lib/tftpboot/cisco/autoinstall
event manager applet CheckInterface
 ! 起動したタイミングでEEMを発動
 event syslog pattern "Cisco"
 ! 機種の確認
 action 3.0 set model "none"
 action 3.1 cli command "show version | include [Cc]isco\ (.+)\ (\(.+\)).+bytes of memory."
 action 3.2 regexp "[Cc]isco\ ([^\ ]*)\ " "$_cli_result" match model
 ! ひとまず1812Jの場合には、1812-J となる。
 action 4.0 if $model eq "1812-J"
 action 4.1  set interface "fas 0"
 ! 他機種でのshow version 出力結果を調査して、ここに記載すれば、他機種でも対応可能
 action 4.999 end
 ! DHCPでのインタフェイス設定
 action 5.0 cli command "enable"
 action 5.1 cli command "configure terminal"
 action 5.2 cli command "interface $interface"
 action 5.3 cli command " ip address dhcp"
 action 5.4 cli command " no shutdown"
 action 5.5 cli command "end"
!
!
event manager applet ConfigInstall
 ! DHCPでアドレスが取得できたタイミングでEEMを発動
 event syslog pattern "%DHCP-6-ADDRESS_ASSIGN"
 ! シリアルの確認
 action 1.0 set serial "none"
 action 1.1 cli command "show version | include Processor board ID"
 action 1.2 regexp "Processor\ board\ ID\ ([0-9a-zA-Z]*)," "$_cli_result" match serial
 ! シリアルに応じたファイルを取得
 action 2.0 cli command "enable"
 action 2.1 cli command "copy tftp://10.254.10.251/cisco/serial/$serial.config startup-config" pattern "Destination filename"
 action 2.2 cli command "startup-config"
 action 3.0 reload
!
```

### 実際の機器の場合

以下の機器をゼロタッチで構成してみる。

|項目|値|
|:-:|:-:|
|機器シリアル|FHK103320Q3|
|ホスト名|Rtest|
|IF|FastEther0|
|アドレス|10.1.254.3|
|ログイン方法|telnet|
|ユーザ名|（なし）|
|パスワード|password_chck|
|特権パスワード|secret_chck|


`# vi /var/lib/tftpboot/cisco/serial/FHK103320Q3.config`

```bash:/var/lib/tftpboot/cisco/serial/FHK103320Q3.config
hostname Rtest
enable secret secret_check
!
interface Fast 0 
 ip address 10.1.254.3 255.255.255.0
 no shutdown
!
line vty 0 4
 password password_check
 transport input telnet ssh
```

## 動作検証

Cisco1812JのFastEthernet0とWANセグメントを接続して、電源投入する。


### 初期ブートシーケンス

```
System Bootstrap, Version 12.3(8r)YH6, RELEASE SOFTWARE (fc1)
Technical Support: http://www.cisco.com/techsupport
Copyright (c) 2005 by cisco Systems, Inc.
C1800 platform with 393216 Kbytes of main memory with parity disabled

(省略）

Cisco IOS Software, C181X Software (C181X-ADVIPSERVICESK9-M), Version 15.1(4)M1, RELEASE SOFTWARE (fc1)

(省略）

Cisco 1812-J (MPC8500) processor (revision 0x400) with 354304K/38912K bytes of memory.
Processor board ID FHK103320Q3, with hardware revision 0000

10 FastEthernet interfaces
1 ISDN Basic Rate interface
1 Virtual Private Network (VPN) Module
31360K bytes of ATA CompactFlash (Read/Write)

Loading cisco/autoinstall from 10.254.10.251 (via FastEthernet0): !
[OK - 1072 bytes]
Domain server mapped address 10.254.10.251 to vmnetserv01.prosper2.net

Press RETURN to get started!

(省略）

*Jan  2 03:54:45.203: USB init complete.
*Jan  2 03:55:13.551: AUTOINSTALL: FastEthernet0 is assigned 10.1.254.201
*Jan  2 03:55:13.551: AUTOINSTALL: Obtain siaddr 10.254.10.251 (as config server)
*Jan  2 03:55:17.303: %PARSER-4-BADCFG: Unexpected end of configuration file.

*Jan  2 03:55:17.303: %SYS-5-CONFIG_I: Configured from tftp://vmnetserv01.prosper2.net/cisco/autoinstall by console

(省略）

*Jan  2 03:55:21.083: %SNMP-5-COLDSTART: SNMP agent on host Router is undergoing a cold start
*Jan  2 03:55:21.091: %SYS-6-BOOTTIME: Time taken to reboot after reload =  527 seconds

(省略）

*Jan  2 03:55:26.703: %SYS-5-CONFIG_I: Configured from console by  on vty0 (EEM:CheckInterface)
*Jan  2 03:55:37.459: %SYS-5-CONFIG_NV_I: Nonvolatile storage configured from tftp://vmnetserv01.prosper2.net/cisco/serial/FHK103320Q3.config by  on vty0 (EEM:ConfigInstall)
*Jan  2 03:55:37.667: %SYS-5-RELOAD: Reload requested by EEM. Reload Reason: Embedded Event Manager action.
```

ここで再起動がかかる

### 初期コンフィグ保存後再起動

```
System Bootstrap, Version 12.3(8r)YH6, RELEASE SOFTWARE (fc1)
Technical Support: http://www.cisco.com/techsupport
Copyright (c) 2005 by cisco Systems, Inc.
C1800 platform with 393216 Kbytes of main memory with parity disabled

(省略）

Cisco 1812-J (MPC8500) processor (revision 0x400) with 354304K/38912K bytes of memory.
Processor board ID FHKxxxxxxxx, with hardware revision 0000

10 FastEthernet interfaces
1 ISDN Basic Rate interface
1 Virtual Private Network (VPN) Module
31360K bytes of ATA CompactFlash (Read/Write)

SETUP: new interface BRI0 placed in "shutdown" state
SETUP: new interface FastEthernet1 placed in "shutdown" state


Press RETURN to get started!

(省略）

*Jan  2 03:56:39.199: USB init complete.
*Jan  2 03:56:40.703: %PARSER-4-BADCFG: Unexpected end of configuration file.

(省略）

User Access Verification

Password:
Rtest01>
```

コンフィグはちょっとお気に召さなかったようだが、設定したかった内容は反映されている。（end がない、とかかもしれない）


### 別機器からログインしてみる

ルーティングの設定をしていないため、同セグからログインします。
具体的には、ほかのWANエッジルータを踏み台にしています。

```
Rhq01#10.1.254.3
Trying 10.1.254.3 ... Open

User Access Verification

Password:
Rtest>en
Password:
Rtest#
```

## 実運用にあたって
間違ったコンフィグを指定してしまうと、間違ったままstartup-configが出来上がってしまうので、運用ミスへの対策がなんらか必要そう。USBブートができれば、「コンフィグ消去用USBメモリ」みたいなの作れればいいけど、むつかしそう。

## おわりに

### 感想
/var/lib/tftpboot/cisco/serial/FHKxxxxxxxx.config はシリアル番号に応じたコンフィグであり、機種によって体系が変わります。
また、パッと見で対象機器がわかりにくいため、運用性に欠けますね。
そのため、別ディレクトリにホスト名などでシンボリックリンクを張っておくことで、コンフィグ管理もできて運用性もアップ。
検証環境ではコンフィグ管理を **[haruca](http://www.prosper2.org/devwiki/index.php?haruca)** でまとめているので、もちっと工夫したい。