Batfishを使ったConfig参照誤りの検知

# 1. はじめに
[Advent Calender 5日目](https://qiita.com/tech_kitara/items/be71005ad7b5091d25a4)でご紹介した通り、ネットワーク解析ツールであるBatfishには、現在42種類のQuestion機能があります。
今回は`undefinedReferences`と`unusedStructures`についてご紹介します。


# 2. 各Questionの概要

いずれも、Config内で「参照-被参照の関係にある設定」に誤りがないかチェックしてくれるQuestionになります。
具体的に、Cisco IOSの「アクセスグループ(参照)」と「ACL(被参照)」を例に説明すると、確認できることは以下の通りです。

| Question       | 確認できること                                          |
|:-----------------|:-----------------------------------------------------|
| undefinedReferences | アクセスグループで指定しているACLが存在しないケース(全通信が許可されてしまう)     |
| unusedStructures | 設定したACLが、どのアクセスグループからも参照されていないケース |

これ以降で、実際のConfigを使って、どこまで精度の高いチェックが可能か見ていきたいと思います。

# 3. 参照関係が正常なConfigのチェック

### 3-1. 対象Config
まずは、正常な`brborder2`(スポーク拠点のWANルータ)に対してチェックを行います。参照-被参照の関係にある設定は、大まかには以下の4つです。

**1. トンネルインターフェース**
　トンネルインターフェースの送信元インターフェースとして、Loopbackを指定
　　⇒トンネルインターフェースがLoopbackを参照

**2. パケットフィルタ**
　トンネルインターフェースにて、ハブ拠点向けの通信をout方向ACLで制御
　　⇒アクセスグループが名前付き拡張ACLを参照

**3. ルートフィルタ**
　トンネルインターフェースにて、ハブ拠点向けに広報するルートをACLで指定
　　⇒ディストリビュートリストが名前付き標準ACLを参照

**4. QoS**
　トンネルインターフェースにて、ハブ拠点向けの通信を帯域制御
　　⇒サービスポリシーがポリシーマップを参照
　　⇒ポリシーマップがクラスマップを参照
　　⇒クラスマップが番号付き拡張ACLを参照

Configは以下の通りです。

```text:正常Config
～中略～
!
class-map match-all C-DATA2
 match access-group 101
class-map match-all C-DATA1
 match access-group 100
!
!
policy-map P-CHILD
 class C-DATA1
  priority percent 40
 class C-DATA2
  bandwidth percent 30
 class class-default
  bandwidth percent 30
policy-map P-PARENT
 class class-default
  shape average 10000000
  service-policy P-CHILD
!
!
interface Tunnel1
 description << To hqborder2 >>
 bandwidth 100
 ip address 10.1.1.10 255.255.255.252
 ip access-group WAN out
 delay 10
 tunnel source Loopback0
 tunnel destination 1.1.1.1
 service-policy output P-PARENT
!
interface Loopback0
 ip address 1.1.1.2 255.255.255.255
!
interface FastEthernet0
 description << To PE Router >>
 ip address 10.1.1.6 255.255.255.252
 duplex auto
 speed auto
!
～中略～
!
interface Vlan10
 ip address 10.10.1.48 255.255.255.0
!
router eigrp 1
 distribute-list EIGRP_WAN out Tunnel1
 network 10.1.1.8 0.0.0.3
 network 10.10.1.0 0.0.0.255
 no auto-summary
!
ip route 1.1.1.1 255.255.255.255 10.1.1.5
ip route 2.2.2.2 255.255.255.255 10.1.1.5
!
ip access-list standard EIGRP_WAN
 permit 10.10.1.0 0.0.0.255
!
ip access-list extended WAN
 permit ip 10.10.1.0 0.0.0.255 192.168.100.0 0.0.0.255
 permit ip any host 192.168.100.107
 permit ip any host 192.168.100.37
 permit ip any host 192.168.100.47
 permit ip any host 192.168.100.44
 permit udp any host 192.168.100.44 eq ntp
!
no ip http server
no ip http secure-server
!
logging 192.168.100.107
access-list 100 permit ip any 192.168.100.0 0.0.0.255
access-list 101 permit ip any 192.168.101.0 0.0.0.255
!
～中略～
end
```

### 3-2. 参照関係の抽出

別のQuestionである`referencedStructures`を使って、参照関係を抽出した結果は以下の通りです。前述した設定1～4の内、「3. ルートフィルタ」は参照関係を認識できていません。言い換えると、ルートフィルタの参照関係に異常があった場合、検知できないことになります。
実際に使用する際は、現状のConfigでチェックを行い、検知できる範囲を確認した方がいいと思います。
![12-1.png](https://qiita-image-store.s3.amazonaws.com/0/310082/ea081fa9-d6c4-e91e-e535-9bbae7448ee8.png)

### 3-3. 参照関係のチェック

`undefinedReferences`と`unusedStructures`を使って、参照関係をチェックした結果は以下の通りです。前項の通り、実際には問題ないにもかかわらず、ルートフィルタのACLが、どの設定からも参照されていないことになっています。
![12-3.png](https://qiita-image-store.s3.amazonaws.com/0/310082/efba46a0-8edf-271d-c9a8-26ef5ba1a52a.png)


# 4. 参照関係が異常なConfigのチェック

### 4-1. 対象Config
`brborder2`に対し、以下の誤った設定を入れてチェックを行います。

**1. パケットフィルタ**
　LAN側インターフェースにて、ハブ拠点向けの通信をin方向ACLで制御
　ただし、アクセスグループで指定したACLを入れ忘れている

**2. QoS**
　トンネルインターフェースにて、ハブ拠点向けの通信を帯域制御
　ただし、トンネスインターフェースへのサービスポリシー適用を忘れている

差分Configは以下の通りです。

```text:異常Config
interface Tunnel1
 description << To hqborder2 >>
 bandwidth 100
 ip address 10.1.1.10 255.255.255.252
 ip access-group WAN out
 delay 10
 tunnel source Loopback0
 tunnel destination 1.1.1.1
    # service-policyなし(どこからも参照されていない)
!
interface Vlan10
 ip address 10.10.1.48 255.255.255.0
 ip access-group LAN out   # 参照するACLなし
```

### 4-2. 参照関係のチェック
`undefinedReferences`では、誤り設定1が検出されています。`unusedStructures`でも、誤り設定2が検出されており、少なくとも今回のケースでは、期待通りの動作をしてくれています。
![12-4.png](https://qiita-image-store.s3.amazonaws.com/0/310082/5464f9a7-5206-50ff-f933-fcd9e914d0d7.png)


# 5. まとめ
いずれのQuestionも、今回試したCisco IOSのConfigでは、概ね問題なく参照誤りの検知ができました。ただし、誤検知も発生したため、現状の本番環境のConfigを使って、検知可能な範囲を確認した上で使用するのが良いと思います。