PeeringDBから情報を引っ張る

[NetOpsCoding Advent Calendar 2016](http://qiita.com/advent-calendar/2016/netopscoding) 12/22分の記事です。

#はじめに
NetOpsCoding Advent Calendarの説明文には
>ソフトウェアからのネットワーク機器操作によってネットワーク運用の自動化を志す人達のAdvent Calendarです

と書かれていますがネットワーク機器操作ではありません。ごめんなさい。
ネットワーク機器の操作というよりはコンフィグ作成支援ツール的な部分になります。
なのでちょっと箸休め的な文章になりますがご了承下さい。

#Peeringって大変じゃないですか？
AS運用をメインとしたネットワークエンジニアには切っても切れないPeering業務、
やり取りを何度も何度も何度もして、コンフィグ作って・・・と大変じゃないですか。

![peering01.png](https://qiita-image-store.s3.amazonaws.com/0/28655/8c34e7ff-2746-43da-7180-915180554700.png)

![peering02.png](https://qiita-image-store.s3.amazonaws.com/0/28655/a32557f8-6c82-0260-10cb-dee346029105.png)

こんなやりとりをメールでやったあとにコンフィグを作って、管理票に記入して、Trapが飛んできたときに分かるように設定を入れるとか考えるとそれだけでPeering業務がいやになっちゃってきます。

#Peeringの業務をできるだけ楽にしたい
ということで、AS番号からPeeringDBの情報を調べて、そこの情報からコンフィグが作れればなと考えました。
本当はワンライナーで設定までいければカッコよかったのですがあいにく自社で利用しているルータは自動化に優しくなかったので挫折です。

#PeeringDB 2.0
2016年3月15日にPeeringDB2.0が正式公開されました！
それに伴いベータ版だったAPIも正式版に変更になっています。
昨年のアドベントカレンダーで@taijijijiさんが[公開](http://qiita.com/taijijiji/items/a8a8beb68038a993ac2e)していたものはベータ版で、多少の変更が入っています。

#ASから接続IX情報の取得
ベータ版ではAS番号から接続IXの情報を取得できるが、接続IXの詳細は見れない状態だったため、あらためて接続IXのIDから検索することで情報を取得できました。
しかし、2.0正式版ではAS番号で検索したとしても接続IXの情報すら取得できません。

AS17961の情報を取り出したい時にはまず
https://www.peeringdb.com/api/net?asn=”AS番号”
を参照します。

```json:www.peeringdb.com/api/net?asn=17961
{
	"meta": {},
	"data": [
		{
			"id": 2806,
			"org_id": 2346,
			"name": "mitene internet Co., Ltd.",
			"aka": "",
			"website": "http://www.mitene.co.jp",
			"asn": 17961,
			"looking_glass": "",
			"route_server": "",
			"irr_as_set": "AS-MITENE",
			"info_type": "Cable/DSL/ISP",
			"info_prefixes4": 100,
			"info_prefixes6": 20,
			"info_traffic": "",
			"info_ratio": "Mostly Inbound",
			"info_scope": "Asia Pacific",
			"info_unicast": true,
			"info_multicast": false,
			"info_ipv6": true,
			"notes": "\"BBIX Hong Kong / Singapore\" is Selective",
			"policy_url": "",
			"policy_general": "Open",
			"policy_locations": "Preferred",
			"policy_ratio": false,
			"policy_contracts": "Not Required",
			"created": "2009-12-15T03:12:32Z",
			"updated": "2016-04-18T03:53:12Z",
			"status": "ok"
		}
	]
}
```

ここでPeeringDB内でのAS17961の"id"を知ることが出来ます。
AS17961の場合のidは”2806”のようです。
ここから今度はidを使って情報を取り出します。

https://www.peeringdb.com/api/net/”ID”

```json:www.peeringdb.com/api/net/2806
{
	"meta": {},
	"data": [
		{
			"id": 2806,
			"org_id": 2346,
			"org": {
			"id": 2346,
			"name": "mitene internet Co., Ltd.",
			"website": "",
			"notes": "",
			"net_set": [
				2806
			],
			"fac_set": [],
			"ix_set": [],
			"address1": "",
			"address2": "",
			"city": "",
			"country": "",
			"state": "",
			"zipcode": "",
			"created": "2009-12-15T03:12:32Z",
			"updated": "2016-03-14T20:24:20Z",
			"status": "ok"
		},
		"name": "mitene internet Co., Ltd.",
		"aka": "",
		"website": "http://www.mitene.co.jp",
		"asn": 17961,
（中略）

		"netfac_set": [
			{
				"id": 21981,
				"name": "KDDI Otemachi (Telehouse Tokyo Otemachi)",
				"city": "Tokyo",
				"country": "JP",
				"fac_id": 142,
				"local_asn": 17961,
				"created": "2016-10-11T08:27:53Z",
				"updated": "2016-10-11T08:27:53Z",
				"status": "ok"
			},
（中略）
		],
		"netixlan_set": [
			{
				"id": 9417,
				"ix_id": 95,
				"name": "JPNAP Tokyo",
				"ixlan_id": 95,
				"notes": "",
				"speed": 10000,
				"asn": 17961,
				"ipaddr4": "210.173.176.55",
				"ipaddr6": "2001:7fa:7:1:0:1:7961:1",
				"is_rs_peer": true,
				"created": "2011-08-30T00:00:00Z",
				"updated": "2016-03-23T00:15:11Z",
				"status": "ok"
			},
（中略）
			{
				"id": 30811,
				"ix_id": 1449,
				"name": "BBIX Hong Kong",
				"ixlan_id": 1322,
				"notes": "",
				"speed": 1000,
				"asn": 17961,
				"ipaddr4": "103.203.158.85",
				"ipaddr6": "2403:c780:b800:bb00:0:1:7961:1",
				"is_rs_peer": false,
				"created": "2016-10-11T08:26:31Z",
				"updated": "2016-10-11T08:26:31Z",
				"status": "ok"
			}
		],
		"poc_set": [],
		"created": "2009-12-15T03:12:32Z",
		"updated": "2016-04-18T03:53:12Z",
			"status": "ok"
		}
	]
}
```
これで取得ができるようになりました。
ASだけで一発でここまで情報を取得できると楽なんですが現状では難しそうです。

#(余談)"ix_id"と"ixlan_id"
てっきりix_idとixlan_idは同一の数字が入ると思っていたのですが、
ix_idが1000くらいになるとズレが出てきてしまうので設定する時には注意が必要です。
上記の例だと、"BBIX Hong Kong"のix_idは**1449**で、ixlan_idは**1322**となります。
私は深い意味はないですがixlan_idで識別するようにしています。

#そんなASから所属IXを割り出してConfig作る
弊社で作成したサービスを切り出して公開することにしました。

**PeerConfig**
https://github.com/mitene17961/peerconfig

![peering03.png](https://qiita-image-store.s3.amazonaws.com/0/28655/b147417a-6793-dea0-7291-783077c08078.png)


機能は
・ASを入力するとPeeringDBから調べて自分がつながっているIXにいるかどうかを調べる。
・そのIX用のコンフィグを作成支援する。（コピペしやすいように作ってくれる）
・nfdumpのcsvデータがあれば調べたASの流量を調べる事ができる。

とシンプルなものになっています。

#ファイル構成
| ファイル名 | 内容 | 個別設定 |
|:-:|:-:|:-:|
| index.php  | 本体  |  不要 |
| define.php  | パス指定など各種設定ファイル  | 必要  |
| bgp_config_base  |  ベースコンフィグファイル | 必要  |
| ipv4-bgp_config  |  IPv4コンフィグファイル |  必要 |
| ipv6-bgp_config  |  IPv6コンフィグファイル |  必要 |
 
#初期設定
define.phpを起動前に設定します。
nfdumpで出力したCSVファイル出力の絶対パスがあれば設定します。なければ設定は不要です。
nfdumpは"-s as -n 300 -o csv"で出力してください。
（-nの値についてはもっと多くても構いません）

例：define( "FLOW_CSV_FILE_PATH"    , "/home/user/nfdumpas.csv" );

その他MaxPrefixの標準値や、コンフィグファイル名などは必要であれば変更をしてください。

次に、接続IXを記載していきます。
デフォルトでは東京のIX4箇所+ASIA SmartIXを設定していますが、自由に設定をして下さい。
array( 'ixLanID' => '95'        , 'displayName' => "JPNAP Tokyo1"               , 'ixPrefix' => 'JPNAP' )
の場合
ixLanIDがPeeringDBのixLanID(上記で説明しています)
displayNameはボタンの表示名
ixPrefixはコンフィグ時にIXに応じてフィルタを変更する場合に使う引数名になります。

#該当IXのボタンを押した際に表示するコンフィグ

bgp_config_base内に書いた内容を表示します。
同一IXで2IPあるASの場合はipv4-bgp_config,ipv6-bgp_config内の内容を該当IPごとにループするようにしています。
上記の3つのパタメータファイルを元に表示します。

#コンフィグ部分で利用できるパラメータ
| パラメータ | 取得内容 | 補足 |
|:-:|:-:|:-:|
| <%AS-NAME%>  |  該当ASのPeeringDBにあるIRR Recordから情報を取得 |  GUIで変更可能 |
|  <%AS_NUMBER%> | 該当ASのPeeringDBにあるPrimary ASNから情報を取得  |   |
|  <%TARGET_IPv4%> | 該当ASのPeeringDBにある該当IXのIPv4アドレスから取得  |   |
|  <%IPv4_PREFIX%> | 該当ASのPeeringDBのIPv4 Prefixesから取得  |  ない場合はdefine.phpよりデフォルト値を取得 |
|  <%TARGET_IPv6%> |  該当ASのPeeringDBにある該当IXのIPv6アドレスから取得 |   |
| <%IPv6_PREFIX%>  |  該当ASのPeeringDBのIPv6 Prefixesから取得 | ない場合はdefine.phpよりデフォルト値を取得  |
| <%IX-LAN-PREFIX%>  |  define.phpの接続IXで指定したixPrefixの値を取得 | 同一IX接続で同じフィルタを利用するなどの場合に利用  |

#最後に
こういった公開は実は初めてなのでドキドキです。
感想とか動かなかった報告お待ちしております！

[Blog](https://www.hagane.me)にもネットワークの事中心に書いてますのでこちらもよろしければ
最新技術というよりはネットワークの仕事ハック的なものばかりですが^^;